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

Покер - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.95
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
10.05.2013, 18:57     Покер #1
Хочу написать простенькую покерную программу на с++. Нужна помощь с архитектурой. Напишите, пожалуйста, какие классы стоит реализовать. Спасибо!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.05.2013, 18:57     Покер
Посмотрите здесь:

C++ Задача Покер
Задача Покер C++
Моделирование игры в покер C++
C++ Проверка на стрит(покер)
Программа для игры в покер C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 928
Завершенные тесты: 1
13.05.2013, 03:08     Покер #21
Цитата Сообщение от lemegeton Посмотреть сообщение
Перемешивать особо не выйдет.
Это как?)) Постоянно играть одними и теми же картами?

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

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

Добавлено через 1 минуту
2vlad_light
Дело в том, что это не имеет смысла. То что не имеет смысла не нужно и приведет к ошибкам. Так что резать на этапе компиляции.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
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). Что ещё добавить/убрать?
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
13.05.2013, 03:25     Покер #23
Цитата Сообщение от vlad_light Посмотреть сообщение
Я где-то читал (если правильно помню), что конструктор по умолчания, копии, деструктор и оператор присваивания создаются автоматически, если их не написать вручную. Так вот я их и написал, чтоб (если вдруг что) в будущем их подправить. И вообще мне кто-то говорил, что лучше их всё-таки писать (даже пустые), чем не писать вообще во избежании проблем в будущем.
Класс карты примитывный, тут нет ресурсов которые требуется освобобождать или копировать, потому писать свой свои пустые реализации смысла нет. "Если в друг что" - что например? Класс карты станет не картой или что?
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
13.05.2013, 03:29  [ТС]     Покер #24
Дело в том, что я пока не очень разбираюсь, где класс примитивный, а где -- нет. Поэтому и пишу эти штуке везде где надо и где не надо Это больше для выработки привычки (как std:: вместо using namespace std), чем для извлечения какой-то пользы из этого.
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 928
Завершенные тесты: 1
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 описывать игроков для любой карточной игры.
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
13.05.2013, 04:26  [ТС]     Покер #26

Не по теме:

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


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

Не по теме:

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

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

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

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

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

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

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

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

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

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

Отето от разделение от него мне кажется программа более запутаной, чем делать все в одном классе.
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
13.05.2013, 13:32     Покер #29
Цитата Сообщение от ninja2 Посмотреть сообщение
карта, от нее идет производный класс колода
Колоду нельзя наследовать от карты, так как колода не является картой. Тут должна быть аггрегация.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.05.2013, 13:35     Покер #30
Цитата Сообщение от lemegeton Посмотреть сообщение
Колоду нельзя наследовать от карты, так как колода не является картой. Тут должна быть аггрегация.
Тут похоже кругом агрегацию нужно применять.
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
13.05.2013, 19:58     Покер #31
Цитата Сообщение от ninja2 Посмотреть сообщение
Тут похоже кругом агрегацию нужно применять.
Ибо одно из правил гласит -- предпочитайте аггрегацию наследованию.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.05.2013, 20:33     Покер #32
Цитата Сообщение от lemegeton Посмотреть сообщение
Ибо одно из правил гласит -- предпочитайте аггрегацию наследованию.
Не знаю я таких правил не примоню, а от точно помню делал упражнение, там нужно было написать два способа как построить отношение классов класс имеет, первый способ это агрегация хранить объект другого класса в классе и второй это наследование.
В принципе если посудить, то смысл не меняется программка разбита на меньшие подпрограммы. От если подумать карта не есть колода но если мы будем создавать вначале карта протестим ее отладим, все мы к ней не возвращаемся, затем колода, которая производная от карта, тоже отладили ее и снова уже к ней не возвращаемся. Появление ошибок в этик кусках кода уже будет исключено. Дальше пишем программу делаем делаем игрок производным от колода и так же отлаживаем тестим, но тут нам нужно создать еще и класс стол и сделать множественное наследование с классом игрок. А дальше просто создаем объект игрок, инициализируются разом все базовые классы, обращаясь к методам игрока мы уже мы уже строим программу. Но лучше создать верхний (нижний) класс который будет интерфейсом игры например game().

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

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

Я в этом не сильно опытен и компетентен, но если просто представить как будет строится программка и как она будет работать, то получается очень удобно.
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
13.05.2013, 21:53     Покер #33
Цитата Сообщение от ninja2 Посмотреть сообщение
Не знаю я таких правил не примоню
Читайте больше теории. Еще больше теории. Книжки по проектированию подойдут.
Цитата Сообщение от ninja2 Посмотреть сообщение
колода, которая производная от карта
У карты какие свойства? Ранг и масть.
Какая масть у колоды? Какой ранг у колоды?!
Так какой смысл колоду наследовать от карты?! Что бы все запутались?
Цитата Сообщение от ninja2 Посмотреть сообщение
Появление ошибок в этик кусках кода уже будет исключено.
Ошибки не появляются. Они есть. Всегда. В любом коде. Земля вертится, все меняется. То, что сегодня казалось безупречным, завтра будет куском легаси кода, подлежащим немедленному рефакторингу.
Цитата Сообщение от ninja2 Посмотреть сообщение
класс стол и сделать множественное наследование с классом игрок
Осторожно, вы уже выходите за грань как добра так и зла.
Цитата Сообщение от ninja2 Посмотреть сообщение
то код я думаю получиться не плохо структурированным и наверняка легко поддерживаемым
Простите, но это будет ад и содомия.
Цитата Сообщение от ninja2 Посмотреть сообщение
даже по моему такой способ как я описал есть, и он как то называется, то ли построение снизу вверх или наоборот с верху вниз,
Индусский код это называется.

Цитата Сообщение от ninja2 Посмотреть сообщение
так можно незаметно громаднейшие программы строить разбитые на модули, которые можно сказать независимые друг от друга, не все конечно, но зависимость конечно будет
Чет я не понял. У вас ВСЕ классы будут зависеть друг от друга наследованием(!), но код при этом каким-то чудом окажется независимым?! Это странно как минимум.

Очень большая проблема ООП -- так называемая "хрупкость" базового класса. Т.е. в большом проекте изменения в базовом классе сделать либо практически невозможно либо повлечет за собой непредсказуемое поведение системы в целом. Отсюда и правило -- предпочитайте аггрегацию наследованию.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.05.2013, 23:10     Покер #34
Цитата Сообщение от lemegeton Посмотреть сообщение
Очень большая проблема ООП -- так называемая "хрупкость" базового класса. Т.е. в большом проекте изменения в базовом классе сделать либо практически невозможно либо повлечет за собой непредсказуемое поведение системы в целом. Отсюда и правило -- предпочитайте аггрегацию наследованию.
А согласись даже при агрегации код зависим получается, потому что должно быть как минимум определение класса, который будет передаваться, а это уже зависимость. Отдельно класс тоже не получится использовать если он агрегацией связан, то есть находится в отношении имеет.

Можно только использовать классы отдельно если они не имеют никакой зависимости с другими классами либо имеют зависимость с вложенными классами.

Получается все взаимосвязано и что то поменять уже не так просто.
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
13.05.2013, 23:16     Покер #35
Цитата Сообщение от ninja2 Посмотреть сообщение
А согласись даже при агрегации код зависим получается, потому что должно быть как минимум определение класса, который будет передаваться, а это уже зависимость. Отдельно класс тоже не получится использовать если он агрегацией связан, то есть находится в отношении имеет.
Можно только использовать классы отдельно если они не имеют никакой зависимости с другими классами либо имеют зависимость с вложенными классами.
Получается все взаимосвязано и что то поменять уже не так просто.
Безусловно. Код на аггрегациях все же менее хрупкий.
Все равно, стоит сначала разобраться, когда можно использовать наследование, перед тем, как предпочитать ему аггрегацию. )
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.05.2013, 23:23     Покер #36
Цитата Сообщение от lemegeton Посмотреть сообщение
У карты какие свойства? Ранг и масть.
Какая масть у колоды? Какой ранг у колоды?!
Так какой смысл колоду наследовать от карты?! Что бы все запутались?
А если ранг и масть это закрытые члены класса, то для удобства нам нужно делать класс карта другом класса колода, чтобы можно спокойно обращатся к этим членам, это тоже не сильно удобно.
Мне кажется проще сделать наследование а в классе колода создать массив из объектов карт к которым можно спокойно обращаться. Хотя неудобно наверно проще создать указатель на карты и хранить в объекте колода массив карт, как бы агрегация, ну тогда лучше делать ранг и масть открытыми членами.
Да и смысла похоже нету, нам же ведь нужна ни одна карта а целый массив карт который удобно хранить в указателе на массив объектов карта. Ну в принципе наследование здесь не нужно.
Ну зато для колоды и игрока там уже можно сделать наследование, так как объект колода у нас будет один, поэтому без разници хоть наследование, хоть через указатель результат один и тот же будет.

Добавлено через 1 минуту
lemegeton, да я понял наследование нужно применять, если есть общие методы и члены для классов наследников, чтобы не писать код дважды.
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
13.05.2013, 23:26     Покер #37
Цитата Сообщение от ninja2 Посмотреть сообщение
А если ранг и масть это закрытые члены класса, то для удобства нам нужно делать класс карта другом класса колода, чтобы можно спокойно обращатся к этим членам, это тоже не сильно удобно.
не надо другом. Все общение с объектами происходит через открытые методы.

Цитата Сообщение от ninja2 Посмотреть сообщение
Мне кажется проще сделать наследование
Бессмысленно. Просто ни к чему.

Цитата Сообщение от ninja2 Посмотреть сообщение
ну в принципе наследование здесь не нужно.
Абсолютно.

Цитата Сообщение от ninja2 Посмотреть сообщение
Ну зато для колоды и игрока там уже можно сделать наследование, так как объект колода у нас будет один, поэтому без разници хоть наследование, хоть через указатель результат один и тот же будет.
Тоже не нужно. Игрок не является колодой.

Добавлено через 52 секунды
Цитата Сообщение от ninja2 Посмотреть сообщение
lemegeton, да я понял наследование нужно применять, если есть общие методы и члены для классов наследников, чтобы не писать код дважды.
Наследование нужно применять, когда дочерний объект является родительским и ведет себя как родительский.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.05.2013, 23:31     Покер #38
меня просто задание збило для меня как бы наследование и агрегация тождественные они просто одинаково строят отношение имеет.

Добавлено через 5 минут
lemegeton, Спасибо за лекбез. ООП правда запутанная тема, возможностей много, а как правильно делать кто его знает как.
ТОрчОК
Заблокирован
13.05.2013, 23:33     Покер #39
я сейчас пытаюсь сделать игру в дурака у меня объект - набор карт(векторы) вся колода, карты на игроков и "бито". интересно с помощью какого метода лучше всего реализовывать AI? с помощью дерева - хороший ли вариант?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.05.2013, 23:50     Покер
Еще ссылки по теме:

Покер C++
C++ Графический покер
C++ Покер

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

Или воспользуйтесь поиском по форуму:
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.05.2013, 23:50     Покер #40
ТОрчОК, Попытайся без дерева. Я так понимаю дерево это альфа-бета осечение или как там его называют?
Просто попробуй 3 правила для хода компа. От если ходит комп то обязательно с самой меньшей карты не козырь и подкидывает допустим карты максимум валет и шушваль, остальное оставляет себе, там дамы короли тузы. Просто попробуй для начала придумать небольшой набор правил я думаю аи этим инструкциям будет следовать постоянно то к концу игры у него накопится норм козырей и больших карт так что с ним играть будет интересно.
Так же какой нибудь набор правил придумай небольшой для того варианта, если комп отбивается. Не обязательно дерево. Дерево это мегаацкий камп сделать, который не переиграть , а в дурака играют обычные пользователи кое как, им не интересно будет с таким компом играть, так что твой простой алгоритм будет рулить

Добавлено через 4 минуты
ТОрчОК, я тоже делал игру reversi и тоже нужно было AI сделать так я простейшие правила для хода компа сделал и кам тяжело выиграть, хотя можно было альфа-бета отсечение ну в нем еще нужно разобраться было, поэтому я не делал. Просто понял что альфа-бета отсечение это дерево в котором находятся все возможные ходы которые токо могут быть, комп как то их перебирает и обязательно ходит правильно, всегда выберает наиболее правильный ход заглядывая на перед, Но нафиг так делать? Обычный пользователь не профи, ему пару правил и мега ацкий AI получается.
Yandex
Объявления
13.05.2013, 23:50     Покер
Ответ Создать тему
Опции темы

Текущее время: 15:30. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru