-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
146 lines (116 loc) · 4.39 KB
/
Copy pathserver.py
File metadata and controls
146 lines (116 loc) · 4.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
from flask import Flask, render_template, jsonify, request
from poker.game import GameState
from poker.player import Player
from poker.bot import Bot
from poker.hand import HandEvaluator
app = Flask(__name__)
# Global Game Instance
game = None
def serialize_card(card):
return {"rank": card.rank, "suit": card.suit, "display": str(card)}
def serialize_player(p):
return {
"name": p.name,
"stack": p.stack,
"bet": p.current_bet,
"is_folded": p.is_folded,
"is_all_in": p.is_all_in,
# Show hole cards if it's Hero OR if it's Showdown
"hole_cards": [serialize_card(c) for c in p.hole_cards] if (p.name == "Hero" or (game and game.stage == "SHOWDOWN")) else []
}
@app.route('/')
def home():
return render_template('index.html')
@app.route('/api/start', methods=['POST'])
def start_game():
global game
# Deep Stack 10,000 chips
hero = Player("Hero", 10000)
bot1 = Bot("Bot 1", 10000)
bot2 = Bot("Bot 2", 10000)
players = [hero, bot1, bot2]
game = GameState(players)
game.start_hand()
return jsonify({"status": "Game Started"})
@app.route('/api/next_hand', methods=['POST'])
def next_hand():
global game
if not game:
return jsonify({"error": "No game active"}), 400
game.start_hand()
return jsonify({"status": "New Hand Started"})
# Cache for equity
last_game_state_hash = None
cached_equity = 0
cached_recommendation = "Wait"
@app.route('/api/state', methods=['GET'])
def get_state():
global game, last_game_state_hash, cached_equity, cached_recommendation
if not game:
return jsonify({"error": "No game active"}), 400
# Calculate Equity for Hero
# We use a hash of the board and stage and hole cards to decide if we need to re-run
hero = game.players[0] # Hero is index 0
current_hash = hash((
game.stage,
tuple(str(c) for c in game.board),
tuple(str(c) for c in hero.hole_cards),
hero.is_folded
))
if current_hash != last_game_state_hash:
from engine.simulator import MonteCarloSimulator
if not hero.is_folded and game.stage != "SHOWDOWN":
sim = MonteCarloSimulator()
# Increase iterations for better accuracy since we cache it now
equity = sim.calculate_equity(hero.hole_cards, game.board, iterations=2000)
# Simple Recommendation Logic
rec_text = "Wait"
rec_amount = 0
if equity > 0.8:
rec_text = "All-In / Large Raise"
rec_amount = game.pot * 1.5 # Overbet
elif equity > 0.65:
rec_text = "Raise (Strong)"
rec_amount = game.pot * 0.75 # 3/4 Pot
elif equity > 0.55:
rec_text = "Value Bet / Raise"
rec_amount = game.pot * 0.5 # Half Pot
elif equity > 0.4:
rec_text = "Call / Check"
else:
rec_text = "Fold / Check"
cached_equity = equity
cached_recommendation = f"{rec_text}"
if rec_amount > 0:
cached_recommendation += f" (${int(rec_amount)})"
else:
cached_equity = 0
cached_recommendation = "--"
last_game_state_hash = current_hash
response = {
"pot": game.pot,
"board": [serialize_card(c) for c in game.board],
"stage": game.stage,
"current_player": game.players[game.current_player_idx].name,
"players": [serialize_player(p) for p in game.players],
"hero_equity": round(cached_equity * 100, 1),
"recommendation": cached_recommendation
}
return jsonify(response)
@app.route('/api/action', methods=['POST'])
def player_action():
global game
if not game:
return jsonify({"error": "No game"}), 400
data = request.json
action = data.get('action')
amount = data.get('amount', 0)
# Process Action with amount
# We map 'raise' or 'bet' to passing the amount
hero = game.players[0]
game.handle_action(hero.name, action, int(amount))
# For simplified flow, we still auto-advance stage after user acts (plus bots)
game.next_stage()
return jsonify({"status": "Action processed", "new_stage": game.stage})
if __name__ == '__main__':
app.run(debug=True, port=8888)