Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.95
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
#1

Покер - C++

10.05.2013, 18:57. Просмотров 3625. Ответов 47
Метки нет (Все метки)

Хочу написать простенькую покерную программу на с++. Нужна помощь с архитектурой. Напишите, пожалуйста, какие классы стоит реализовать. Спасибо!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.05.2013, 18:57
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Покер (C++):

Покер - C++
Прошу помощи. Болел - ничего не понял. Скоро экзамен, а я ничего не понимаю в С++. Дали примерные задачи, а я не понимаю как решать. Вот...

Покер - C++
Подскажите пожалуста где ошибка??????:help: компилятор выдает ошибки Ошибка 2 error LNK2005: "int __cdecl compareCards(void const...

Графический покер - C++
Доброго времени суток всем. Вот, немного запутался.... Есть игра покер...Нужно ее реализовать в упрощенном виде. Есть изображения...

Задача Покер - C++
Даны 5 целых чисел. Среди них: если одинаковы 5, то вывести "Impossible", иначе если одинаковы 4, то вывести "Four of a Kind", иначе ...

Задача Покер - C++
Даны 5 целых чисел. Среди них: если одинаковы 5, то вывести "Impossible", иначе если одинаковы 4, то вывести "Four of a Kind", иначе ...

Моделирование игры в покер - C++
Недавно начал изучать С++,использую книгу Харви М. Детела Как программировать на С++.В конце одной из глав есть упражнение,в котором нужно...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
lemegeton
2924 / 1353 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
13.05.2013, 02:27 #16
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>
 
/**
 * Игральная карта. Один байт в памяти.
 */
class Card {
 public:
  static const std::string SUIT_NAMES[];
  static const std::string RANK_NAMES[];
  Card(unsigned char id) : id(id) {}
  Card(unsigned char rankId, unsigned char suitId) : id((suitId << 5) | rankId) {}
  unsigned char getId() const { return id; }
  unsigned char getRankId() const { return id & 31; }
  unsigned char getSuitId() const { return id >> 5; }
  const std::string &getRankName() const { return RANK_NAMES[getRankId()]; }
  const std::string &getSuitName() const { return SUIT_NAMES[getSuitId()]; }
 private:
  unsigned char id;
};
 
const std::string Card::SUIT_NAMES[] = {"spades", "diamonds", "clubs",
  "hearts"};
const std::string Card::RANK_NAMES[] = {"2", "3", "4", "5", "6", "7",
  "8", "9", "10", "jack", "queen", "king", "ace"};
 
bool operator<(const Card &a, const Card &b) {
  return a.getId() < b.getId();
}
 
std::ostream &operator<<(std::ostream &stream, const Card &c) {
  return stream << c.getRankName() << " of " << c.getSuitName();
}
Набор карт можно сделать просто набором битов. 52 карты уложатся в восемь байт.
Шаффл вообще не нужен -- нужно просто брать рандомную карту.

Добавлено через 7 минут
std::bitset поможет, кстати.
2
stima
473 / 322 / 30
Регистрация: 22.03.2011
Сообщений: 1,046
Завершенные тесты: 2
13.05.2013, 02:55 #17
2lemegeton
1. Ну один байт это если запретить выравнивание.
2. Card card(255). Это что за карта?
3. А теперь представьте. Ваш покер пользуется популярностью и Вы все улучшаете его и улучшаете. Кода все больше и больше. Время для переписывания все меньше и меньше. Как Вы думаете, Вы сразу сообразите что это
C++
1
unsigned char getSuitId() const { return id >> 5; }
4.
Цитата Сообщение от lemegeton Посмотреть сообщение
Шаффл вообще не нужен -- нужно просто брать рандомную карту.
Каждый раз рандомить + хранить какая карта выбыла? Или все таки один раз перемешать.
0
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
13.05.2013, 02:59  [ТС] #18
Я бы сделал как-то так. Соответственно разбив это на обьявление и имлементацию.
В принципе, я где-то так и сделал... Спасибо!
сделать просто набором битов
Ой, тяжело мне даются эти штуки с умножением на 31 == (1 << 5) - 1 и т.п. Можно было тогда вообще всю колоду в 7 байтов (два unsigned int или один unsigned long long ) обозначить
Например 4 бубен и король пик имеет вид (масти HDCS, ранг от 2 до А):
##...#23...KA23456...QKA
00....000...0000100....010 = 68719476738.

Добавлено через 1 минуту
Каждый раз рандомить + хранить какая карта выбыла? Или все таки один раз перемешать.
Я это тоже хотел спросить

Добавлено через 2 минуты
Вы сразу сообразите что это
C++
1
unsigned char getSuitId() const { return id >> 5; }
Скорее, что это:
C++
1
unsigned char getRankId() const { return id & 31; }

Не по теме:

Вот, раскритиковали человека, а на самом деле очень умные вещи рассказывает. Просто мне до них ещё далеко, поэтому и не воспринимаю я такое...

0
lemegeton
2924 / 1353 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
13.05.2013, 03:02 #19
Цитата Сообщение от stima Посмотреть сообщение
1. Ну один байт это если запретить выравнивание.
Ок.

Цитата Сообщение от stima Посмотреть сообщение
Каждый раз рандомить + хранить какая карта выбыла?
Я предлагаю сделать битсет, и хранить в нем все возможные карты. Перемешивать особо не выйдет.

Цитата Сообщение от stima Посмотреть сообщение
3. А теперь представьте. Ваш покер пользуется популярностью и Вы все улучшаете его и улучшаете. Кода все больше и больше. Время для переписывания все меньше и меньше. Как Вы думаете, Вы сразу сообразите что это
Да. Обязательная документация.

Цитата Сообщение от stima Посмотреть сообщение
2. Card card(255). Это что за карта?
Тот же смысл, что и Card card(255, 255).
0
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
13.05.2013, 03:03  [ТС] #20
2. Card card(255). Это что за карта?
такой, как я понял -- нету. И задаваться они будут в стиле Card card ((suit << 5) + rank), если я правильно понял код...
0
stima
473 / 322 / 30
Регистрация: 22.03.2011
Сообщений: 1,046
Завершенные тесты: 2
13.05.2013, 03:08 #21
Цитата Сообщение от lemegeton Посмотреть сообщение
Перемешивать особо не выйдет.
Это как?)) Постоянно играть одними и теми же картами?

Цитата Сообщение от lemegeton Посмотреть сообщение
Да. Обязательная документация.
Не думаю что для моего примера нужна документация к этому классу.

Цитата Сообщение от lemegeton Посмотреть сообщение
Тот же смысл, что и Card card(255, 255).
Это откуда? С моего примера? Тогда скомпильте это.

Добавлено через 1 минуту
2vlad_light
Дело в том, что это не имеет смысла. То что не имеет смысла не нужно и приведет к ошибкам. Так что резать на этапе компиляции.
0
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
13.05.2013, 03:10  [ТС] #22

Не по теме:

Дело в том, что это не имеет смысла.
что именно?


И, кстати, нужна помощь с классом Player. Я сделал ему такие переменные:
C++
1
2
3
4
5
std::string         name_;
std::vector<Card>   cards_;
int                 currentChips_;  
int                 investedChips_;
bool                isInGame_;
и 2 метода (помимо set/get): fold () и invest (int). Что ещё добавить/убрать?
0
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
13.05.2013, 03:25 #23
Цитата Сообщение от vlad_light Посмотреть сообщение
Я где-то читал (если правильно помню), что конструктор по умолчания, копии, деструктор и оператор присваивания создаются автоматически, если их не написать вручную. Так вот я их и написал, чтоб (если вдруг что) в будущем их подправить. И вообще мне кто-то говорил, что лучше их всё-таки писать (даже пустые), чем не писать вообще во избежании проблем в будущем.
Класс карты примитывный, тут нет ресурсов которые требуется освобобождать или копировать, потому писать свой свои пустые реализации смысла нет. "Если в друг что" - что например? Класс карты станет не картой или что?
1
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
13.05.2013, 03:29  [ТС] #24
Дело в том, что я пока не очень разбираюсь, где класс примитивный, а где -- нет. Поэтому и пишу эти штуке везде где надо и где не надо Это больше для выработки привычки (как std:: вместо using namespace std), чем для извлечения какой-то пользы из этого.
0
stima
473 / 322 / 30
Регистрация: 22.03.2011
Сообщений: 1,046
Завершенные тесты: 2
13.05.2013, 04:06 #25
2 vlad_light
Это по теме. Тема называется проектирование. Упростим. Как пример представьте вы разрабатываете класс Human. Человек может быть или мужчина или женщина. Это можно сделать так как предложил lemegeton.

C++
1
2
3
4
5
6
7
8
9
10
11
class Human
{
   typedef unsigned char uchar;
public:
    Human(uchar sex) :
           : sex(sex) {}
    ---------
private:
    uchar sex; //  где 0 это мужчина а 1 женщина
   ----------
};
Так вот. Такой код позволяет написать так
C++
1
Human human(42);
Что:
1. Компилируеться.
2. Линкуеться,
3. Работает

Но пола 42 нету. И нужно постоянно помнить кто 0, а кто 1. И это может сказаться потом часами отладки.

Или так как предложил я
C++
1
2
3
4
5
6
7
8
9
10
11
12
class Human
{
public:
    enum Sex  { Man, Women };
 
    Human(const Sex& sex) :
           : sex(sex) {}
    ---------
private:
    Sex sex;
   ----------
};
Теперь. Это
C++
1
Human human(42);
будет ошибкой компиляции.

Что же касается Вашего вопроса по поводу Player.
C++
1
То std::vector<Card>   cards_;
Следует заменить на
C++
1
2
То std::list<const Card*>   cards_;
//или То std::list<const Card&>   cards_;
Так как во первых у вас постоянная вставка/удаление (почитайте разницу междуstd::list и std::vector). Во вторых картами владеет колода, а не игрок. Игрок их только держит(указатель/ссылка) и не может менять их содержимое(const).

И почитайте про понятия pimpl или наследование. Тогда вот эти вот переменные
C++
1
2
int                 currentChips_;  
int                 investedChips_;
Уйдут в имплементацию(припустим PokerPlayer). И вы можете на основе Player описывать игроков для любой карточной игры.
1
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
13.05.2013, 04:26  [ТС] #26

Не по теме:

Я понял, что пола 42 не существует (я же сразу ответил, что карты 255 тоже нет). Я просто не сразу понял, к чему это было адресовано.


Под переменной cards_ в классе Player я имел ввиду карты, которыми владеет игрок. Т.е. я предлагаю создать колоду в виде стека и из неё доставать (удалять) по одной карте и передавать (записывать в переменную) её игроку. Т.е. картами уже владеет игрок, а не колода.
Вашу идею я понял, но мне кажется, её будет сложнее реализовать (нужно будет держать в голове, что куда указывает). Хотя по эффективности она конечно выигрывает
И почитайте про понятия pimpl или наследование.
Почитаю, но позже. Я пока до этого не дошёл, поэтому попробую пока сделать так, а потом переделаю.

Не по теме:

Спасибо Вам большое, но у меня уже 3:30 ночи, пойду спать. Завтра постараюсь продолжить

0
lemegeton
2924 / 1353 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
13.05.2013, 04:35 #27
Цитата Сообщение от stima Посмотреть сообщение
Это как?)) Постоянно играть одними и теми же картами?
В битсете нечего перемешивать. Представьте пятьдесят два установленных бита подряд. Что там перемешивать?

Цитата Сообщение от stima Посмотреть сообщение
Не думаю что для моего примера нужна документация к этому классу.
Документация нужна всегда.

Цитата Сообщение от stima Посмотреть сообщение
Это откуда? С моего примера? Тогда скомпильте это.
Энумы это прекрасно, но менее гибко.

Цитата Сообщение от stima Посмотреть сообщение
Как пример представьте вы разрабатываете класс Human. Человек может быть или мужчина или женщина.
... и не дай Б-г вдруг пользователю класса узнать, что существуют гермафродиты. Будет переписывать весь класс. По теме карт -- не модифицируя код класса Card, представьте с помощью него новую карту -- джокера.

stima, не надо так горячиться. Ваш код вполне хорош (что-то там с итераторами какая-то ерунда, кстати), никто не отрицает. У нас, например, считается хорошей практикой использовать enum в качестве именованных констант, а как тип данных используется редко из-за негибкости подхода и для прибивания гвоздями ограниченного количества возможных вариантов данных. У вас, возможен другой опыт.

Моя идея заключалась в том, чтобы хранить любой набор 52 карт в семи байтах, вычисляя саму карту походя из позиции установленного бита. That's, в общем-то, it.
0
ninja2
231 / 187 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.05.2013, 12:59 #28
Цитата Сообщение от MihalNik Посмотреть сообщение
- карта // объектами будут карты
- колода // состоит из набора карт
- игрок // хранит данные о фишках, возможных ходах и т.п.
- стол // хранит информацию об игроках, текущем ходе, банке и т.п.
- ИИ // н.к.
Вот я бы не делал карты объектами. А просто числами. Пару функций для масти и достоинства делаются делением как частное и остаток. Названия или картинки для карт - массивом. В колоду массив чисел, перемешивать очень удобно, сдавать и т.п. Вообще для любых карточных игр, не только покера.
Мне от просто интересно понять иерархию классов, если от так создать классы, то в каких они будут отношения?
Класс Deck будет отностися к Card, значит что в нем будет хранится указатель на объекты Card. Класс игрок, что он будет делать? В игрока наверно будет колода, и наверно еще свои карты, значит это, то что игрок имеет колоду. Класс ИИ это разновидность игрока Значит можно сделать ИИ : public игрок. (но я думаю это фигня там простая функция которая просто по алгоритму будет менять параметры массива розданных карт).
А стол куда будет относится? Наверно игрок имеет и стол и игрок имеет и колоду, на столе допустим просто будут розданые карты. Как мы видим в верху всего у нас стоит класс карта, от нее идет производный класс колода, от колоды идет производный класс игрок, от также производный и от класса стол,
Получается просто :
колода : public карта;
игрок : public колода, public стол.
стол как бы сам по себе хранит просто данные об игре.

В любом случае насколько я понял классы как то взаимодействуют, это как правило взаимодействие "имеет". Это как правило либо наследование либо агрегация через указатель. Если класс "не имеет" то есть он просто использует другой класс внутри себя, то я думаю это использование класса как структуры, хотя это однозначно то же самое что "имеет".

Я просто сам пытаюсь разобраться в этих иерархиях и архитектурах классов, хотя как мне кажется нету никакой архитектуры, просто есть допустим громадная программа, которую мы можем разбить на подклассы, допустим отдельные мелкие функции взять и разбить на подклассы, законченные конечно. Это просто более удобно один класс верхушку создал, отладил все работает, мы больше к нему не возвращаемся делаем наследование создаем производный класс, либо еще новый который независимый и так от строим иерархию. Это выглядит построение снизу вверх, просто явно видно. И тоже способ очень в принципе хороший да и простенько и ясненько. Разделяй и властвуй как говорится.

Хотя мб я и не прав. Но я больше думаю что всетаки прав, потому что по другому как строить я не вижу.

Отето от разделение от него мне кажется программа более запутаной, чем делать все в одном классе.
0
lemegeton
2924 / 1353 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
13.05.2013, 13:32 #29
Цитата Сообщение от ninja2 Посмотреть сообщение
карта, от нее идет производный класс колода
Колоду нельзя наследовать от карты, так как колода не является картой. Тут должна быть аггрегация.
0
ninja2
231 / 187 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.05.2013, 13:35 #30
Цитата Сообщение от lemegeton Посмотреть сообщение
Колоду нельзя наследовать от карты, так как колода не является картой. Тут должна быть аггрегация.
Тут похоже кругом агрегацию нужно применять.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.05.2013, 13:35
Привет! Вот еще темы с ответами:

Проверка на стрит(покер) - C++
В одном из заданий из книги Дейтелов необходимо определить, имеется ли на руках у игрока стрит(пять карт последовательных номиналов). Но...

Кому интересно. Покер - C++
Вообщем, давно ничего не кодил и на днях накатал немного говно кода на тему Покера. Кому будет интересно, посмотрите и предложите если...

Программа для игры в покер - C++
Никак не могу понять суть ооп. До прихода в с++ програмировал на С микроконтроллеры. Там всё просто. Есть начало программы, и пишеш...

Покер - даны 5 целых чисел. Определить в них комбинации повторяющихся элементов - C++
есть массив. надо определить в нем комбинации повторяющихся элементов: for(int i=0; i&lt;5;i++) { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
13.05.2013, 13:35
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru