forked from Turing-Games/template-python-poker-bot
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkellycriterion.py
More file actions
executable file
·104 lines (88 loc) · 3.39 KB
/
kellycriterion.py
File metadata and controls
executable file
·104 lines (88 loc) · 3.39 KB
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python3
import asyncio
from typing import Tuple
import argparse
import treys
import time
from tg.bot import Bot
import tg.types as pokerTypes
parser = argparse.ArgumentParser(
prog='Template bot',
description='A Turing Games poker bot that always checks or calls, no matter what the target bet is (it never folds and it never raises)')
parser.add_argument('--port', type=int,
help='The port to connect to the server on')
parser.add_argument('--host', type=str, default='localhost',
help='The host to connect to the server on')
parser.add_argument('--room', type=str, default='my-new-room',
help='The room to connect to')
parser.add_argument('--party', type=str, default='poker',
help='The room to connect to')
parser.add_argument('--key', type=str, default='',
help='The key for authentication')
parser.add_argument('--simulations', type=int, default=1000)
args = parser.parse_args()
def card_name(card: pokerTypes.Card):
val = str(card.rank)
if card.rank == 1:
val = 'A'
if card.rank == 10:
val = 'T'
elif card.rank == 11:
val = 'J'
elif card.rank == 12:
val = 'Q'
elif card.rank == 13:
val = 'K'
return f"{val}{card.suit[0]}"
# Use kelly criterion to bet based on the win probability
class KellyCriterion(Bot):
def act(self, state, hand):
prob = self.win_prob(state, hand)
me = None
for player in state.players:
if player.id == self.my_id:
me = player
break
p = prob
b = len(state.players)
raise_to = (p - (1-p)/b)*(me.stack)
print('my stack:', me.stack, raise_to, p, ''.join(map(card_name, hand)), ''.join(map(card_name, state.cards)))
cost_to_play = min(state.target_bet-me.current_bet, me.stack)
if raise_to > state.target_bet:
return {'type': 'raise', 'amount': raise_to-state.target_bet}
elif raise_to >= cost_to_play or cost_to_play == 0:
return {'type': 'call'}
print('fold')
return {'type': 'fold'}
def opponent_action(self, action, player):
pass
def game_over(self, payouts):
#print('game over', payouts)
pass
def start_game(self, my_id):
self.my_id = my_id
print('start game', my_id)
def win_prob(self, state: pokerTypes.PokerSharedState, hand: Tuple[pokerTypes.Card, pokerTypes.Card]):
out = 0
hand = [
treys.Card.new(card_name(hand[0])),
treys.Card.new(card_name(hand[1]))]
board = [treys.Card.new(card_name(card)) for card in state.cards]
evaluator = treys.Evaluator()
for i in range(args.simulations):
deck = treys.Deck()
deck.shuffle()
for card in hand+board:
deck.cards.remove(card)
pred = board + deck.draw(5-len(board))
score = evaluator.evaluate(hand, pred)
other = 10**9
for player in state.players:
if player.id != self.my_id:
other = min(other, evaluator.evaluate(deck.draw(2), pred))
if score < other:
out += 1
return out/args.simulations
if __name__ == "__main__":
bot = KellyCriterion(args.host, args.port, args.room, args.party, args.key)
asyncio.run(bot.start())