Как связать смену рук и игровое поле моего игрока с существующим оценщиком покерных рук?

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

ОРИГИНАЛ:

Я нашел этот оценщик покерных рук на Python от Элвина Ляна, который я хочу внедрить в свою игру: https://github.com/aliang/pokerhand-eval

ЛУЧШЕЕ РЕШЕНИЕ для моих нужд (В НАСТОЯЩЕЕ ВРЕМЯ ХОЧУ РЕАЛИЗОВАТЬ ЭТО): (из курса udacity csc212 Питера Норвига)

import itertools

## Deck adds two cards:
## '?B': black joker; can be used as any black card (S or C)
## '?R': red joker; can be used as any red card (H or D)

allranks = '23456789TJQKA'
redcards = [r+s for r in allranks for s in 'DH']
blackcards = [r+s for r in allranks for s in 'SC']

def best_wild_hand(hand):
"Try all values for jokers in all 5-card selections."
hands = set(best_hand(h)
            for h in itertools.product(*map(replacements, hand)))
return max(hands, key=hand_rank)

def replacements(card):
"""Return a list of the possible replacements for a card.
There will be more than 1 only for wild cards."""
if card == '?B': return blackcards
elif card == '?R': return redcards
else: return [card]

def best_hand(hand):
"From a 7-card hand, return the best 5 card hand."
return max(itertools.combinations(hand, 5), key=hand_rank)

def test_best_wild_hand():
assert (sorted(best_wild_hand("6C 7C 8C 9C TC 5C ?B".split()))
        == ['7C', '8C', '9C', 'JC', 'TC'])
assert (sorted(best_wild_hand("TD TC 5H 5C 7C ?R ?B".split()))
        == ['7C', 'TC', 'TD', 'TH', 'TS'])
assert (sorted(best_wild_hand("JD TC TH 7C 7D 7S 7H".split()))
        == ['7C', '7D', '7H', '7S', 'JD'])
return 'test_best_wild_hand passes'



def hand_rank(hand):
"Return a value indicating the ranking of a hand."
ranks = card_ranks(hand)
if straight(ranks) and flush(hand):
    return (8, max(ranks))
elif kind(4, ranks):
    return (7, kind(4, ranks), kind(1, ranks))
elif kind(3, ranks) and kind(2, ranks):
    return (6, kind(3, ranks), kind(2, ranks))
elif flush(hand):
    return (5, ranks)
elif straight(ranks):
    return (4, max(ranks))
elif kind(3, ranks):
    return (3, kind(3, ranks), ranks)
elif two_pair(ranks):
    return (2, two_pair(ranks), ranks)
elif kind(2, ranks):
    return (1, kind(2, ranks), ranks)
else:
    return (0, ranks)

def card_ranks(hand):
"Return a list of the ranks, sorted with higher first."
ranks = ['--23456789TJQKA'.index(r) for r, s in hand]
ranks.sort(reverse = True)
return [5, 4, 3, 2, 1] if (ranks == [14, 5, 4, 3, 2]) else ranks

def flush(hand):
"Return True if all the cards have the same suit."
suits = [s for r,s in hand]
return len(set(suits)) == 1

def straight(ranks):
"""Return True if the ordered
ranks form a 5-card straight."""
return (max(ranks)-min(ranks) == 4) and len(set(ranks)) == 5

def kind(n, ranks):
"""Return the first rank that this hand has
exactly n-of-a-kind of. Return None if there
is no n-of-a-kind in the hand."""
for r in ranks:
    if ranks.count(r) == n: return r
return None

def two_pair(ranks):
"""If there are two pair here, return the two
ranks of the two pairs, else None."""
pair = kind(2, ranks)
lowpair = kind(2, list(reversed(ranks)))
if pair and lowpair != pair:
    return (pair, lowpair)
else:
    return None

print test_best_wild_hand()

Вот код GamerManager, который у меня есть:

import json
import gameboard
from django.shortcuts import HttpResponse, render, redirect, Http404
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required

cardDict = {
    0: "ace of clubs",
    1: "two of clubs",
    2: "three of clubs",
    3: "four of clubs",
    4: "five of clubs",
    5: "six of clubs",
    6: "seven of clubs",
    7: "eight of clubs",
    8: "nine of clubs",
    9: "ten of clubs",
    10: "jack of clubs",
    11: "queen of clubs",
    12: "king of clubs",
    13: "ace of diamonds",
    14: "two of diamonds",
    15: "three of diamonds",
    16: "four of diamonds",
    17: "five of diamonds",
    18: "six of diamonds",
    19: "seven of diamonds",
    20: "eight of diamonds",
    21: "nine of diamonds",
    22: "ten of diamonds",
    23: "jack of diamonds",
    24: "queen of diamonds",
    25: "king of diamonds",
    26: "ace of hearts",
    27: "two of hearts",
    28: "three of hearts",
    29: "four of hearts",
    30: "five of hearts",
    31: "six of hearts",
    32: "seven of hearts",
    33: "eight of hearts",
    34: "nine of hearts",
    35: "ten of hearts",
    36: "jack of hearts",
    37: "queen of hearts",
    38: "king of hearts",
    39: "ace of spades",
    40: "two of spades",
    41: "three of spades",
    42: "four of spades",
    43: "five of spades",
    44: "six of spades",
    45: "seven of spades",
    46: "eight of spades",
    47: "nine of spades",
    48: "ten of spades",
    49: "jack of spades",
    50: "queen of spades",
    51: "king of spades",
    52: "black joker",
    53: "red joker",
    54: "back"
}


@login_required
def createGameRoom(request):
    userName = request.user.username
    board = gameboard.GameBoard()
    points = [0, 0, 0, 0]
    room = request.POST['gameRoom']
    roomDir = 'Game/GameRooms/game'+room+'.json'
    gameFile = open(roomDir)
    gameState = json.load(gameFile)
    gameFile.close()
    if gameState['p1Name'] == userName:
        gameState['board'] = board.board
        gameState['playerNum'] = 4
        gameState['turn'] = 1
        gameState['rounds'] = 0
        gameState['timeLimit'] = 30
        gameState['points'] = points
        gameState['player1'] = [0, 0]
        gameState['player2'] = [0, 5]
        gameState['player3'] = [5, 5]
        gameState['player4'] = [5, 0]
        gameState['player1Hand'] = []
        gameState['player2Hand'] = []
        gameState['player3Hand'] = []
        gameState['player4Hand'] = []
        with open(roomDir, 'w+') as jFile:
            json.dump(gameState, jFile)
            jFile.close()
    return HttpResponse(json.dumps(gameState), content_type="application/json")

@login_required
def resetRoom(request):
    if request.user.is_staff:
        board = gameboard.GameBoard()
        points = [0, 0, 0, 0]
        room = request.GET['room']
        roomDir = 'Game/GameRooms/game'+room+'.json'
        with open(roomDir, 'w+') as jFile:
            gameState = {'board': board.board,
                         'playerNum': 4,
                         'playerCount': 0,
                         'turn': 1,
                         'rounds': 0,
                         'timeLimit': 30,
                         'p1Name': '',
                         'p2Name': '',
                         'p3Name': '',
                         'p4Name': '',
                         'points': points,
                         'player1': [0, 0],
                         'player2': [0, 5],
                         'player3': [5, 5],
                         'player4': [5, 0],
                         'player1Hand': [],
                         'player2Hand': [],
                         'player3Hand': [],
                         'player4Hand': []}
            json.dump(gameState, jFile)
            jFile.close()
        return redirect(showRooms)
    else:
        return HttpResponse('Error')

@login_required
def joinGameRoom(request):
    room = request.GET["room"]
    roomDir = 'Game/GameRooms/game' + room + ".json"
    gameFile = open(roomDir)
    gameState = json.load(gameFile)
    gameFile.close()
    playerNum = 0
    print "joined room:" + str(request.user.username)
    if gameState['playerCount'] >= 4:
        return HttpResponse("Room is full")
    if gameState['p1Name'] == '':
        gameState['p1Name'] = request.user.username
        playerNum = 1
    elif gameState['p2Name'] == '':
        gameState['p2Name'] = request.user.username
        playerNum = 2
    elif gameState['p3Name'] == '':
        gameState['p3Name'] = request.user.username
        playerNum = 3
    elif gameState['p4Name'] == '':
        gameState['p4Name'] = request.user.username
        playerNum = 4
    gameState['playerCount'] += 1
    with open(roomDir, 'w+') as jFile:
        json.dump(gameState, jFile)
        jFile.close()
    context = {'roomNum': room, 'playerNum': playerNum}
    return render(request, "Games/board.html", context)


@login_required
def startRound(request):
    room = request.POST['gameRoom']
    gameDir = 'Game/GameRooms/game'+room+'.json'
    gameFile = open(gameDir)
    gameState = json.load(gameFile)
    board = gameboard.GameBoard()
    board.start()
    gameState['board'] = board.board
    gameState['rounds'] += 1
    gameState['player1'] = [0, 0]
    gameState['player1Hand'] = []
    gameState['player2'] = [0, 5]
    gameState['player2Hand'] = []
    gameState['player3'] = [5, 5]
    gameState['player3Hand'] = []
    gameState['player4'] = [5, 0]
    gameState['player4Hand'] = []
    gameFile.close()
    with open(gameDir, 'w+') as jFile:
        json.dump(gameState, jFile)
        jFile.close()
    return HttpResponse(json.dumps(gameState), content_type="application/json")


@login_required
@csrf_exempt
def makeMove(request):
    room = request.POST['roomNum']
    gameDir = 'Game/GameRooms/game'+room+'.json'
    row = int(request.POST['row'])
    column = int(request.POST['column'])
    playerNum = request.POST['playerNum']
    gameFile = open(gameDir)
    gameState = json.load(gameFile)
    print gameState
    gameFile.close()
    if int(playerNum) == gameState['turn']:
        print 'making move: ' + playerNum + " in room " + room
        player = 'player'+playerNum
        gameState[player] = [row, column]
        card = gameState['board'][row][column]
        if card != 54:
            gameState[player + 'Hand'].append(card)
            gameState['board'][row][column] = 54
        gameState['turn'] += 1
        if gameState['turn'] > 4:
            gameState['turn'] = 1
        with open(gameDir, 'w+') as jfile:
            json.dump(gameState, jfile)
    return HttpResponse(json.dumps(gameState), content_type="application/json")


def checkOccupied(gameState, row, column):
    isOccupied = False
    gameFile = open('Game/GameRooms/game.json')
    gameState = json.load(gameFile)
    if gameState['player1'] == [row, column]:
        isOccupied = True
    if gameState['player2'] == [row, column]:
        isOccupied = True
    if gameState['player3'] == [row, column]:
        isOccupied = True
    if gameState['player4'] == [row, column]:
        isOccupied = True
    gameFile.close()
    return isOccupied

@login_required
def getValidMoves(request):
    gameFile = open('Game/GameRooms/game.json')
    gameState = json.load(gameFile)
    player = ''
    if gameState['turn'] == 1:
        player = 'player1'
    elif gameState['turn'] == 2:
        player = 'player2'
    elif gameState['turn'] == 3:
        player = 'player3'
    elif gameState['turn'] == 4:
        player = 'player4'
    row = gameState[player][0]
    column = gameState[player][1]
    tempRow = row
    tempCol = column
    validMoves = []
    while (tempCol + 1) < 6:
        tempCol += 1
        occupied = checkOccupied(gameState, tempRow, tempCol)
        if not occupied:
            validMoves.append([tempRow, tempCol])
        else:
            break
    tempCol = column
    while (tempCol - 1) >= 0:
            tempCol -= 1
            occupied = checkOccupied(gameState, tempRow, tempCol)
            if not occupied:
                validMoves.append((tempRow, tempCol))
            else:
                break
    tempCol = column
    while (tempRow + 1) < 6:
            tempRow += 1
            occupied = checkOccupied(gameState, tempRow, tempCol)
            if not occupied:
                validMoves.append((tempRow, tempCol))
            else:
                break
    tempRow = row
    while (tempRow - 1) >= 0:
            tempRow -= 1
            occupied = checkOccupied(gameState, tempRow, tempCol)
            if not occupied:
                validMoves.append((tempRow, tempCol))
            else:
                break
    return HttpResponse(json.dumps(validMoves), content_type="application/json")

@login_required
def getBoard(request):
    if request.method == 'POST':
        room = request.POST['gameRoom']
        gameDir = 'Game/GameRooms/game'+room+'.json'
        gameFile = open(gameDir)
        gameState = json.load(gameFile)
        return HttpResponse(json.dumps(gameState), content_type="application/json")


@login_required
def showRooms(request):
    context = {'room_list':range(1,9)}
    return render(request, "Games/rooms.html", context)

а вот мой класс игрока

class player:
    def __init__(self, playerNum):
        self.name = ""
        self.playerNum = playerNum
        self.row = 0
        self.column = 0
        self.hand = []

    def toHand(self, card):
        self.hand.append(card)

    def setPiece(self, row, column):
        self.row = row
        self.column = column

    def clearHand(self):
        self.hand = []

В принципе, я не совсем уверен, как связать этот оценщик с тем, что у меня сейчас есть. Как связать смену рук и игровое поле моего игрока с существующим оценщиком покерных рук?

Любые идеи помогут (псевдокод или python).


person Kaylie    schedule 17.05.2013    source источник


Ответы (1)


Главное, что вам нужно сделать, это преобразовать представление вашей карты в его. Вы используете одно число 0..51, он использует предмет с мастью и рангом, оба в разном порядке. Чтобы преобразовать ваше значение int (n) в его класс Card, попробуйте следующее:

s = 4 - (n // 13);

r = n % 13;
if r == 0:
    r = 14
else:
    r += 1

c = Card(r, s)

После этого его руки — это просто списки карточных объектов.

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

person Lee Daniel Crocker    schedule 17.05.2013
comment
Мм понятно. Итак, чтобы собрать все воедино, я просто импортировал его библиотеку и приспособился к использованию объекта с костюмом и рангом. Затем у меня будет список объектов карты, и я их отсортирую. Какая из них является вашей реализацией? Мне было бы интересно глянуть. Как бы я реализовал ваш? Большое спасибо! @LeeDanielCrocker - person Kaylie; 17.05.2013
comment
Я хотел бы иметь бета-тестер для своей библиотеки, который полезен для всех видов карточных игр и симуляторов. К сожалению, я только что начал серьезный рефакторинг своего кода, поэтому не могу указать вам на чистую кодовую базу прямо сейчас, пока не закончу и не выложу ее на GitHub. Но если вы хотите попробовать, пришлите мне по электронной почте некоторые подробности (например, какую ОС вы используете, версию Python и т. д.), и, возможно, я смогу собрать что-то, что вы сможете использовать. - person Lee Daniel Crocker; 18.05.2013