|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Алгоритм подсчета покерной руки |
|
|
Алгоритм подсчета покерной руки
|
(*.*) Сообщения: 36564 |
Доброго времени суток!
Вот добрался я и до этого форума ![]() Финальный проект курса формулируется так. Надо сгенерировать колоду карт на 52 листа. Сначала нужно создать структуру данных, у которой два члена: face (номинал карты) и suit (масть). Затем нужно сформировать массив, который и будет наполнен 52 картами. Затем нужно сгенерировать 5 случайных уникальных номеров от 0 до 51 (или от 1 до 52) и на основе этих номеров сформировать покерную руку. Ну и самое главное - определить покерную комбиниацию, которая получится в рез-те. Покерные комбинации такие Flush (все одной масти) Четверка (четыре карды одного номинала) Full house (3+2) Тройка Две пары Пара Ничего Как видите, вариант упрощенный - straight (стрит) подсчитывать не нужно (курс-то для начинающих ;-) Ну и вывести надо 5 карт и название комбинации. Никаких картинок карточной колоды, все в текстовом виде. Затрудненения у меня вызвали пять уникальных случайных кард и алгоритм подсчета покерной руки. С пятью уникальными картами я вроде разобрался относительно легко. Прикрепленный файл Если я что-то упустил, то буду признателен, если вы укажете на ошибки. С подсчетом покерных комбинаций было сложнее. В конечном итоге, я его определил, но хотелось бы услышать и ваше мнение. Возможно, я что-то где-то упустил, или можно все сильно упростить. Основная идея: в руке не может быть более двух различных совпадающих номиналов карт. Т.е. если есть два туза и два короля, то пятой карте пары уже точно не будет. Значит надо подсчитать сколько раз совпали два различных номинала. Прикрепленный файл Ну а дальше уже детали. По порядку проверяем следующие условия:
Вот так я себе это представил, и вроде даже работает. Буду признателен, если вы проверите алгоритм на наличие ошибок или предложите более оптимальный вариант. Может где-то есть лишние шаги, которые можно убрать, упростив код. Спасибо за внимание. P.S. Полный код проекта прикреплен. |
|
------- Отправлено: 11:05, 18-04-2005 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Немного путанно или я старый уже, мозги усохли :] Можно уточнить условия?
>> Затем нужно сгенерировать 5 случайных уникальных номеров от 0 до 51 (или от 1 до 52) и на основе этих номеров сформировать покерную руку Что такое "сформировать покерную руку"? Нужно просто рандомом (следя за неповторяющимися номерами) выбрать 5 чисел от 1 до 52? И всё? Так? Т.е. "сдать пять карт"? >> Ну и самое главное - определить покерную комбиниацию, которая получится в рез-те. Опять непонятно. Честно, я не очень понимаю. Нужно просто сказать, какая комбинация карт получилась из сданных пяти? Так? Т.е. никаких подсчётов вероятностей, никаких"взять ещё три" и "сколько сдать карт, чтобы получить флэш" и т.д.? |
Отправлено: 11:40, 18-04-2005 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Тасование колоды:
Цитата:
1. Инициализируем массив, от 1 до 52, Перемешиваем массив - RandomN() 2. Берём его первые 5 элементов. |
|
Отправлено: 12:03, 18-04-2005 | #3 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Масть - номер карты (0-51) mod 4 (остаток от деления) 0 - пики... 3 - бубны
Номинал - номер карты (0-51) / 4 (целочисленное деление) 0 - двойка ... 12 - туз |
Отправлено: 12:10, 18-04-2005 | #4 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Проверку на флеш делаем очень быструю, без массивов.
Флеш - это когда K[0]%4 == k[1]%4 == k[2]%4 == k[3]%4 == k[4]%4 % - остаток от деления == - равно Сорри за мой С :-Р Поверки по номиналам даём с использованием промежуточного массива. 1. Делаем пустой масив номиналов S размером от 0(двойка) до 12 (туз), итого 13 элементов. 2. Инициализируем его нулями - это счётчики встреч 3. Для каждой карты K из массива k[0..4](пять карт) увеличиваем счётчик номинала. для i от 0 до 4 счётчик[K[i]/4] ++ / - целочисленое деление ++ - увеличение на 1. Далее сортируем массив S (счётчиков номинала по возрастанию) и проверяем результат: 1. если первый элемент стал 4 - "каре". 2. если первый элемент стал 3: 2а. если второй элемент равен 2 - "полный дом". 2б. если второй элемент равен 0 или 1 - "тройка" 3. если первый елемент равен 2: 3а. если второй элемент равен 2 - "две пары". 3б. если второй элемент равен 0 или 1 - "пара" Комбинации "туз" и "стрит-флеш" тоже легко вычисляются. Осталось только расписать "сортируем массив счётчиков" - это простая пузырьковая сортировка, например. Или чего-нибудь продвинутое :] |
|
Отправлено: 12:29, 18-04-2005 | #5 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Сортировка (два-три метода)
http://www.relib.com/articles/article.asp?id=197 |
Отправлено: 12:37, 18-04-2005 | #6 |
(*.*) Сообщения: 36564
|
Профиль | Сайт | Отправить PM | Цитировать hasherfrog
LOL Цитата:
Цитата:
![]() ![]() Насчет тасования колоды я понял идею, но не слишком понял реализацию. Что делает следующий код? Конкретнее, downto2 do begin вообще непонятно, сорри. А для подсчета совпадений номиналов твой вариант действительно проще. Общая идея, как я вижу, такая же: отталкиваемся от факта, что у нас не более двух различных совпадающих номиналов карт. Однако исполнение намного проще. Мне как-то в голову не пришло использовать целочисленое деление ![]() Я сделал так. Допустим, у меня уже есть массив Hand(4), 5 элементов которого являются случайными числами от 0 до 51. Теперь создается массив HandFaces(12) для номиналов и все элементы наполняются нулями. Затем для каждого элемента из массива Hand выполняется целочисленное деление, получившееся число становится индексом массива HandFaces и значение данного элемента увеличивается на единицу. Я правильно понял? Затем массив HandFaces сортируется. Я, честно говоря, не знаю как отсортировать в обратном порядке. Поэтому мне нужно смотреть на последний и предпоследний элементы. Правильно? |
||
------- Отправлено: 00:46, 19-04-2005 | #7 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать >> Правильно?
Ну да :] Кстати... Я только сейчас увидел, что дал кусок про тасовку карт на паскале... :-P LOL, даже ROTFLMAO По-русски :] это будет так: Sub shuffle() 'массив карт Dim L(0 To 51) As Integer 'инициализация колоды For I = 0 To 51 Step 1 L(I) = I Next I 'печать для екселя - надо же что-то узреть :) For I = 0 To 51 Step 1 Worksheets(1).Cells(I + 1, 1).Value = L(I) Next I 'тасовка For I = 51 To 0 Step -1 R = Int(52 * Rnd) If R <> I Then T = L(R): L(R) = L(I): L(I) = T End If Next I 'снова печать - результат тасования For I = 0 To 51 Step 1 Worksheets(1).Cells(I + 1, 2).Value = L(I) Next I End Sub |
Отправлено: 10:00, 19-04-2005 | #8 |
(*.*) Сообщения: 36564
|
Профиль | Сайт | Отправить PM | Цитировать hasherfrog
Да я уже разобрался как отсортировать массив в обратном порядке. На самом деле мне это не нужно, без разницы какой элемент использовать для подсчета сопвадений. Кстати, хорошая идея с Цитата:
Спасибо за пояснения по тасовке колоды. Я понял теперь ![]() ![]() Признателен за ответы ![]() |
|
------- Отправлено: 10:32, 19-04-2005 | #9 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать У-ё.
Неправильно я расписал тасовку. Так тужился, вспоминая васик... :] Переупростил код и потерял смысл использования -1. Надо так: 'тасовка For I = 51 To 1 Step -1 R = Int((I + 1) * Rnd) If R <> I Then T = L(R): L(R) = L(I): L(I) = T End If Next I Стоит только начать... ;] Удачи при сдаче. |
Отправлено: 11:38, 19-04-2005 | #10 |
|
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
FreeBSD - Кривые руки | xolod. | Общий по FreeBSD | 2 | 14-05-2009 12:02 | |
[решено] мои руки\цп\мать кто виноват и что делать) | SoA | Непонятные проблемы с Железом | 12 | 14-08-2008 17:34 | |
DNS (опустились руки) 53 порт локального сервера | Virtus1k | Microsoft Windows NT/2000/2003 | 3 | 03-01-2008 11:16 | |
Программа подсчета трафика. | NewWind | Общий по Linux | 1 | 04-06-2007 16:37 | |
Кривые руки при разгоне - и комп перестал грузится... | Shaytan | Непонятные проблемы с Железом | 13 | 06-03-2005 21:56 |
|