2 / 3 / 0
Регистрация: 11.05.2015
Сообщений: 15
1

Отсортировать poker hand

16.03.2020, 14:24. Показов 2481. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, пишу небольшую программу для покера, конкретно для омахи(одна из разновидностей покера). Омаха - карточная игра в покер, все тоже самое как и в Холдеме, все теже правила. НО раздают вместо 2-х карт ЧЕТЫРЕ карты. И мне для начала нужно правильно отсортировать эту руку(4 карты) в правильном порядке. Пара примеров на картинке:
Вот сам код, пока только получается правильно отсортировать по Рангу:
Буду рад любой помощи, Спасибо.
Кликните здесь для просмотра всего текста

Java
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class Card implements Comparable<Card> {
 
    private final Rank rank;
    private final Suit suit;
 
    public Card(Rank rank, Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }
 
    @Override
    public String toString() {
        return rank.getShortRepresentative()
                + Character.toString(suit.getShortRepresentative());
    }
 
    public String toLongString() {
        return rank.getLongRepresentative() + " of " + suit.getLongRepresentative();
    }
 
    public Rank getRank() {
        return rank;
    }
 
    public Suit getSuit() {
        return suit;
    }
 
    public int getValue() {
        return rank.getValue();
    }
 
    @Override
    public int compareTo(Card card) {
        return Comparator.comparing(Card::getRank)
                .compare(this, card);
    }
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Card)) return false;
        Card card = (Card) o;
        return getRank() == card.getRank() &&
                getSuit() == card.getSuit();
    }
 
    @Override
    public int hashCode() {
        return Objects.hash(getRank(), getSuit());
    }
 
}
Java
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
 
public enum Rank {
    TWO(2, '2', "Two"), THREE(3, '3', "Three"), FOUR(4, '4', "Four"),
    FIVE(5, '5', "Five"), SIX(6, '6', "Six"), SEVEN(7, '7', "Seven"),
    EIGHT(8, '8', "Eight"), NINE(9, '9', "Nine"), TEN(10, 'T', "Ten"),
    JACK(11, 'J', "Jack"), QUEEN(12, 'Q', "Queen"), KING(13, 'K', "King"),
    ACE(14, 'A', "Ace");
 
    private int value;
    private char shortRepresentative;
    private String longRepresentative;
 
    private static final List<Rank> VALUES =
            Collections.unmodifiableList(Arrays.asList(values()));
    private static final int SIZE = VALUES.size();
    private static final Random RANDOM = new Random();
 
    Rank(int value, char shortRepresentative, String longRepresentative) {
        this.value = value;
        this.shortRepresentative = shortRepresentative;
        this.longRepresentative = longRepresentative;
    }
 
    public int getValue() {
        return value;
    }
 
    public char getShortRepresentative() {
        return shortRepresentative;
    }
 
    public String getLongRepresentative() {
        return longRepresentative;
    }
 
    public static Rank getRankFromChar(char c) {
        for (Rank r : Rank.values()) {
            if (c == r.getShortRepresentative()) {
                return r;
            }
        }
        return null;
    }
 
    public static Rank getRandomRank() {
        return VALUES.get(RANDOM.nextInt(SIZE));
    }
 
}
Java
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
 
public enum Suit {
    HEARTS('H', "Hearts", 0),
    SPADES('S', "Spades", 1),
    DIAMONDS('D', "Diamonds", 2),
    CLUBS('C', "Clubs", 3);
 
    private char shortRepresentative;
    private String longRepresentative;
    private int sortingIndex;
 
    private static final List<Suit> VALUES =
            Collections.unmodifiableList(Arrays.asList(values()));
    private static final int SIZE = VALUES.size();
    private static final Random RANDOM = new Random();
 
    Suit(char shortRepresentative, String longRepresentative, int sortingIdx) {
        this.shortRepresentative = shortRepresentative;
        this.longRepresentative = longRepresentative;
        this.sortingIndex = sortingIdx;
    }
 
    public void setSortingIndex(int sortingIndex) {
        this.sortingIndex = sortingIndex;
    }
 
    public char getShortRepresentative() {
        return shortRepresentative;
    }
 
    public String getLongRepresentative() {
        return longRepresentative;
    }
 
    public int getSortingIndex() {
        return sortingIndex;
    }
 
    public static Suit getSuitFromChar(char c) {
        for (Suit suit : Suit.values()) {
            if (c == suit.getShortRepresentative()) {
                return suit;
            }
        }
        return null;
    }
 
    public static Suit getRandomSuit() {
        return VALUES.get(RANDOM.nextInt(SIZE));
    }
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
import java.util.Comparator;
 
public class RankComparator implements Comparator<Card> {
    @Override
    public int compare(Card card1, Card card2) {
        if (card1.getRank() == card2.getRank()) {
            return card1.getSuit().compareTo(card2.getSuit());
        }
        return card1.getRank().compareTo(card2.getRank());
 
    }
}
Java
1
2
3
4
5
6
7
8
9
10
11
import java.util.Comparator;
 
public class SuitComparator implements Comparator<Card> {
    @Override
    public int compare(Card card1, Card card2) {
        if (card1.getSuit() == card2.getSuit()) {
            return card1.getRank().compareTo(card2.getRank());
        }
        return card1.getSuit().compareTo(card2.getSuit());
    }
}
Java
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
import java.util.*;
 
public class Main {
 
    private static List<Card> cards = getRandomHand();
    private static RankComparator rankComparator = new RankComparator();
    private static SuitComparator suitComparator = new SuitComparator();
 
    public static void main(String[] args) {
 
        System.out.println("Random hand, but still not sorted = " + cards.toString());
        cards.sort(rankComparator);
        cards.sort(Collections.reverseOrder());
//        cards.sort(suitComparator);
        System.out.println("Hand sorted by Rank = " + cards.toString());
    }
 
    private static List<Card> getRandomHand() {
        int sizeOfOmahaHand = 4;
        Set<Card> cardsSet = new HashSet<>();
        while (cardsSet.size() != sizeOfOmahaHand) {
            cardsSet.add(new Card(Rank.getRandomRank(), Suit.getRandomSuit()));
        }
        return new ArrayList<>(cardsSet);
    }
 
}
Миниатюры
Отсортировать poker hand  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.03.2020, 14:24
Ответы с готовыми решениями:

Poker
Даны 5 целых чисел. Среди них: если одинаковы 5, то вывести &quot;Impossible&quot;, иначе если одинаковы...

Poker
Даны 5 целых чисел. Среди них: если одинаковы 5, то вывести &quot;Impossible&quot;, иначе если одинаковы 4,...

Poker Dice Энди Харрис
люди помогите пожалуйста с игрой &quot;Покер с костями&quot; из учебник Харриса по сути почти все норм...

Создание онлайн приложения Poker
На каком языке программирования лучше и проще написать онлайн покер для социальной сети?

19
Эксперт Java
3638 / 2970 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
16.03.2020, 14:51 2
Java
1
2
3
4
List<Card> cards = getRandomHand();
        System.out.println("Random hand, but still not sorted = " + cards.toString());
        cards.sort(Comparator.comparing(Card::getSuit).thenComparing(Card::getRank));
        System.out.println("Hand sorted by Rank = " + cards.toString());
0
429 / 363 / 109
Регистрация: 23.05.2016
Сообщений: 1,484
16.03.2020, 15:02 3
Компаратор в терминах Ява вам тут не поможет. Т.к. компаратор по двум объектам должен иметь возможность определить какой из них больше или не меньше другого. А у вас отношение порядка зависит от других объектов в руке.

Можно поступить так. Контейнер с картами в руке отсортировать по убыванию без учета масти. Это можно сделать и компаратором. Далее, создаем новый пустой контейнер.
(*)Помещаем в новый контейнер первую карту из старого (отсортированного), помещенную карту из старого контейнера удаляем. Далее перебираем все оставшиеся элементы первого контейнера и помещаем в новый контейнер те, масть которых совпадает с первой помещенной картой (элементы из старого контейнера при этом удаляем).
Если по достижении конца первого контейнера он не пуст, переходим к (*). Если пуст - задача выполнена.
0
Эксперт Java
3638 / 2970 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
16.03.2020, 15:26 4
Цитата Сообщение от Sindbad_M Посмотреть сообщение
Компаратор в терминах Ява вам тут не поможет
мой код смотрел же?
0
429 / 363 / 109
Регистрация: 23.05.2016
Сообщений: 1,484
16.03.2020, 15:43 5
Цитата Сообщение от xoraxax Посмотреть сообщение
мой код смотрел же?
Смотрю. Тут без поллитры не разобраться.
0
2 / 3 / 0
Регистрация: 11.05.2015
Сообщений: 15
16.03.2020, 16:03  [ТС] 6
Пробывал я написать и такое и почти получилось, но там оказалась другая проблема. В перечисление Suit есть порядок мастей(хотя он ни на что не должен влиять) и когда рука сортируется по рангу и например раздали руку где 2 одинаковые старшие карты, то первой в сортировке встанет всегда та карта, у которой масть имеет порядковый номер выше, чем у другой и неважно, есть потом к ней карта с такой мастью или нет. А мне именно и нужно, что допустим при первых одниковых по рангу карты при сортировке вперед всегда ставала имеенно та карта, у которой масть. Но опять же как я описал проблему на картинке, особенно это касается 4-ой и 5-ой руки, где раздали 2 короля(одинаковых по рангу) и у них есть в руке еще по одной такой же мастевой карте, то там сортировка необходима со сравнением уже 2-х по рангу карт, у кого старше эта карта, та масть и встает вперед при сортировке. Если можно, то ответьте лучше с примером кода.
0
Эксперт Java
3638 / 2970 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
16.03.2020, 16:17 7
Сначала сортируем по масти, внутри масти сортируем по номиналу. Так?
0
429 / 363 / 109
Регистрация: 23.05.2016
Сообщений: 1,484
16.03.2020, 16:30 8
bIVEHb, если вы по поводу моего алгоритма, то он проблему однозначно решает. И сводит к задаче школьного уровня. Код вам тоже дали, но чтобы его понять мне, например, требуется некоторое время.

Цитата Сообщение от bIVEHb Посмотреть сообщение
нужно, что допустим при первых одниковых по рангу карты при сортировке вперед всегда ставала имеенно та карта, у которой масть.
Это решается при сортировке первого массива. Сортируете карты по рангу, для равных по рангу проверяете масть и выстраиваете по масти.

Добавлено через 2 минуты
Цитата Сообщение от xoraxax Посмотреть сообщение
Сначала сортируем по масти, внутри масти сортируем по номиналу. Так?
нет, сложнее. Сначала выбираем самую старшую по номиналу. Если старших по номиналу несколько, выбираем из них старшую по масти, затем помещаем в руку все карты этой масти по убыванию номиналов, для оставшихся карт повторяем.
0
2 / 3 / 0
Регистрация: 11.05.2015
Сообщений: 15
16.03.2020, 16:43  [ТС] 9
Цитата Сообщение от xoraxax Посмотреть сообщение
Сначала сортируем по масти, внутри масти сортируем по номиналу. Так?
Рука в любом случае должна быть отсортирована по рангу, но мастевые карты с более старшими картами должны идти первыми. И главное что масти не должны иметь никакой порядковый приоритет.
Пример, когда 2 масти в руке
Раздали руку 8♠9♥A♠A♥
Это две масти Пики и Черви и есть 2 старшие карты - Тузы, так вот первым встанет Туз червей, потому что 2 карта червей 9-ка по рангу, старше 2-ой карты пик, которая 8-ка.
Далее 3-й картой встанет Туз пик, четвертой = 8 пик
и должно получится:
A♥9♥A♠8♠

Еще пример, где одна масть:
раздали руку Т♦Q♣A♠5♦ - это 10-ка бубей, Дама крестей, Туз пик, 5-ка бубей.
Самая старшая карта = Туз бубей, есть карты такой же масти = нет. Есть такая же карта по рангу = нет. Значит эта карта первая станет.
Далее по рангу Дама крестей, есть карты такой же масти = нет. Есть такая же карта по рангу = нет. Значит эта карта вторая.
Далее по рангу 10-ка бубей, есть карты такой же масти = да = 5-ка бубей, но она по рангу меньше 10-ки, значит будет идти за 10-кой.
Итого:
A♠Q♣Т♦5♦

Я просто не знаю, как еще подробнее расписать(((

Добавлено через 2 минуты
Цитата Сообщение от Sindbad_M Посмотреть сообщение
нет, сложнее. Сначала выбираем самую старшую по номиналу. Если старших по номиналу несколько, выбираем из них старшую по масти, затем помещаем в руку все карты этой масти по убыванию номиналов, для оставшихся карт повторяем.
А вот в этом и проблема, что никакой старшей по масти НЕТ, а просто идет сначала та масть у которой карты по рангу старше чем у другой.
0
Эксперт Java
3638 / 2970 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
16.03.2020, 16:50 10
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
List<Card> cards = getRandomHand(10);
        System.out.println("Random hand, but still not sorted = " + cards.toString());
        Comparator<Card> comparingSuit = Comparator.comparing(Card::getSuit);
        Comparator<Card> comparingRank = Comparator.comparing(Card::getRank).reversed();
        cards.sort(comparingSuit.thenComparing(comparingRank));
        Comparator<List<Card>> comparingRankOfFirst = Comparator.comparing(list -> list.get(0).getRank());
        List<Card> result = cards
                .stream()
                .collect(groupingBy(Card::getSuit))
                .entrySet()
                .stream()
                .map(Map.Entry::getValue)
                .sorted(comparingRankOfFirst.reversed())
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
        System.out.println("Hand sorted by Rank = " + result.toString());
типа так штоле
0
429 / 363 / 109
Регистрация: 23.05.2016
Сообщений: 1,484
16.03.2020, 17:00 11
Цитата Сообщение от bIVEHb Посмотреть сообщение
первым встанет Туз червей, потому что 2 карта червей 9-ка по рангу, старше 2-ой карты пик
теперь понял. Т.е. все масти равносильны? А если рука такая:
{
8 пик
8 черви
туз пик
туз черви
}
в каком порядке должны быть карты в руке?
0
2 / 3 / 0
Регистрация: 11.05.2015
Сообщений: 15
16.03.2020, 17:25  [ТС] 12
Цитата Сообщение от Sindbad_M Посмотреть сообщение
теперь понял. Т.е. все масти равносильны? А если рука такая:
{
8 пик
8 черви
туз пик
туз черви
}
в каком порядке должны быть карты в руке?
Абсолютно верно все масти равносильны.
Хороший вопрос, по идее конечно здесь без разницы, ведь если они равносильны, то какая разница какие из них встанут вперед.
Вот именно из за вот таких нюансов, мне и непонятно, как решить эту проблему.

Добавлено через 5 минут
Цитата Сообщение от xoraxax Посмотреть сообщение
типа так штоле
Я сейчас делаю большую выборку, но на первый взгляд ваше решение работает. Спасибо.

Добавлено через 11 минут
Цитата Сообщение от xoraxax Посмотреть сообщение
типа так штоле
И все таки чуток не то, так как при проверке оказалось, при первых двух одинаковых по рангу карт, алгоритм ставил вперед карту не с другими картами этой же масти, а ту которая видать просто по порядку среди мастей была старше.
0
429 / 363 / 109
Регистрация: 23.05.2016
Сообщений: 1,484
16.03.2020, 17:31 13
Очередное решение от xoraxax превосходит уровень моего восприятия. Поэтому предложу альтернативный подход:
хранить карты одной масти в отдельном контейнере, каждый контейнер отсортировать по рангу карты.
таким образом рука - контейнер содержащий четыре контейнера. Контейнеры в руке отсортировать по возрастанию рангов карт стоящих на первом месте, если они равны, то сравнивают карты на втором месте и т.д. Для каждой из сортировок можно написать компаратор.

Добавлено через 1 минуту
Цитата Сообщение от bIVEHb Посмотреть сообщение
при первых двух одинаковых по рангу карт, алгоритм ставил вперед карту не с другими картами этой же масти, а ту....
Проще и нагляднее привести тест который алгоритм не прошел. Т.е. пришла рука - надо так - алгоритм сделал так.
0
2 / 3 / 0
Регистрация: 11.05.2015
Сообщений: 15
16.03.2020, 17:43  [ТС] 14
Цитата Сообщение от Sindbad_M Посмотреть сообщение
Проще и нагляднее привести тест который алгоритм не прошел. Т.е. пришла рука - надо так - алгоритм сделал так.
Ок.
Random hand, but still not sorted = [8C, 9S, JS, JC]
Hand sorted by Rank = [JC, 8C, JS, 9S]
Очевидно, что здесь быть так: [ JS, 9S, JC, 8C] - при равенстве валетов, здесь у масти Spades, вторая карта 9-ка старше второй карты Clubs 8-ки

Вот еще:
Random hand, but still not sorted = [7D, JS, JH, 6S]
Hand sorted by Rank = [JH, JS, 6S, 7D]
Должно быть так = [JS, 6S, JH, 7D] - при равенстве валетов, JS имеет в руке еще одну карту с такой же мастью и поэтому этот валет должен быть первой картой в этой руке.

Вместо рандомной руки, можно просто вбить эти руки и посмотреть как отсортирует алгоритм xoraxax, чтоб не верить наслово мне))
0
Эксперт Java
3638 / 2970 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
16.03.2020, 18:35 15
Цитата Сообщение от Sindbad_M Посмотреть сообщение
Очередное решение от xoraxax превосходит уровень моего восприятия
отсортировали по масти, внутри масти по номиналу. Сгруппировали все масти - получили 4 массива. Отсортировали по первому элементу массива, собрали в один массив.
0
429 / 363 / 109
Регистрация: 23.05.2016
Сообщений: 1,484
16.03.2020, 21:57 16
Цитата Сообщение от xoraxax Посмотреть сообщение
Отсортировали по первому элементу массива,
Вот. При равенстве первых элементов не сравниваются вторые.

Все равно, до такого кода я не дорос. Функциональные блоки только со справочником в руках кое-как могу расшифровать.
0
477 / 327 / 130
Регистрация: 14.06.2016
Сообщений: 640
16.03.2020, 22:30 17
Лучший ответ Сообщение было отмечено bIVEHb как решение

Решение

Java
1
2
3
4
Map<Suit, Integer> map =
        cards.stream().collect(groupingBy(Card::getSuit, Collectors.summingInt(c -> 1 << c.getRank().getValue())));
 
cards.sort(Comparator.comparing((Card c) -> map.get(c.getSuit())).thenComparing(Card::getRank).reversed());
1
2 / 3 / 0
Регистрация: 11.05.2015
Сообщений: 15
17.03.2020, 13:21  [ТС] 18
Цитата Сообщение от vcrop Посмотреть сообщение
Map<Suit, Integer> map =
        cards.stream().collect(groupingBy(Card::getSuit, Collectors.summingInt(c -> 1 << c.getRank().getValue())));
cards.sort(Comparator.comparing((Card c) -> map.get(c.getSuit())).thenComparing(Card::getRank).reversed());
Добрый день! Ваше решение полностью подошло, сделал большую выборку на 1000 рук, в том числе по сложным ситуациям, где первые карты по рангу равны, все работает корректно. Большое спасибо за помощь. И все таки расскажите поподробнее про ваше решение, особенно это касается, где происходит побитый сдвиг влево. Спасибо.

Добавлено через 2 часа 0 минут
Цитата Сообщение от vcrop Посмотреть сообщение
Map<Suit, Integer> map =
        cards.stream().collect(groupingBy(Card::getSuit, Collectors.summingInt(c -> 1 << c.getRank().getValue())));
cards.sort(Comparator.comparing((Card c) -> map.get(c.getSuit())).thenComparing(Card::getRank).reversed());
И все таки нашел брешь в вашем решении) 2 масти и 2 пары одинаковых по рангу карты, сортирует не так.
Примеры:
Random hand, but still not sorted = [QD, QH, 3D, 3H]
Hand sorted = [QD, QH, 3D, 3H]
Должно быть так [QD, 3D, QH, 3H] или так [QH, 3H, QD, 3D]

Random hand, but still not sorted = [AS, 8C, 8S, AC]
Hand sorted = [AS, AC, 8C, 8S]
Должно быть так [AS, 8S, AC, 8C] или так [AC, 8C, AS, 8S]

Random hand, but still not sorted = [9D, TC, 9C, TD]
Hand sorted = [TC, TD, 9D, 9C]
Должно быть так [TC, 9C, TD, 9D] или так [TD, 9D, TC, 9C]

Все таки даже при равных 2-х пар карт с разными мастями, они должны сортироваться по своей масти.
0
477 / 327 / 130
Регистрация: 14.06.2016
Сообщений: 640
17.03.2020, 13:27 19
Да, конечно, я забыл

cards.sort(Comparator.comparing((Card c) -> map.get(c.getSuit())).thenComparing(Card::getSuit).thenComparing(Card::getRank).reversed());
0
2 / 3 / 0
Регистрация: 11.05.2015
Сообщений: 15
17.03.2020, 13:41  [ТС] 20
Цитата Сообщение от vcrop Посмотреть сообщение
Да, конечно, я забыл
cards.sort(Comparator.comparing((Card c) -> map.get(c.getSuit())).thenComparing(Card::getSuit).thenComparing(Card::getRank). reversed());
Подтверждаю, теперь работает все корректно.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.03.2020, 13:41
Помогаю со студенческими работами здесь

Програмное приложение для online poker
Нужно разработать программное обеспечение для онлайн-покера. плюс создать сайт для онлайн-игры...

Создание бота для приложения вконтакте ''Poker Shark"
Здравствуйте, хочу написать бота для приложения вконтакте ''Poker Shark&quot;. Не для того чтоб бот...

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

right-hand operand
#include &lt;iostream&gt; #include &lt;cmath&gt; #include &lt;ctime&gt; using namespace std; const int n=3;...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru