shortdeck1.3:ui and fix

This commit is contained in:
2025-10-11 18:24:24 +08:00
parent 4763f9a630
commit 8f30e75e1a
69 changed files with 2753 additions and 97 deletions

13
__init__.py Normal file
View File

@@ -0,0 +1,13 @@
from .shortdeck_arena import Simulation, Agent, HumanAgent, Card, HandEvaluator, HandRanking
from .shortdeck_server import ArenaGame
__all__ = [
"Simulation",
"Agent",
"HumanAgent",
"Card",
"HandEvaluator",
"HandRanking",
"ArenaGame"
]

Binary file not shown.

Binary file not shown.

Binary file not shown.

856
client/index.html Normal file
View File

@@ -0,0 +1,856 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ShortDeck Poker - Professional Client</title>
<!-- React & TypeScript (via CDN for quick setup) -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script crossorigin src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Custom Styles -->
<style>
body {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
font-family: 'Inter', system-ui, sans-serif;
min-height: 100vh;
}
.poker-table {
background: radial-gradient(ellipse at center, #059669 0%, #047857 70%, #065f46 100%);
border: 8px solid #92400e;
box-shadow: 0 0 50px rgba(0, 0, 0, 0.7);
}
.card {
width: 60px;
height: 84px;
border-radius: 8px;
background: white;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 0.9rem;
}
.card.red {
color: #dc2626;
}
.card.back {
background: linear-gradient(45deg, #1e40af, #3730a3);
color: white;
}
.player-seat {
transition: all 0.3s ease;
}
.player-seat.active {
box-shadow: 0 0 20px rgba(34, 197, 94, 0.6);
border: 2px solid #10b981;
}
.action-button {
transition: all 0.2s ease;
}
.action-button:hover {
transform: translateY(-2px);
}
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const { useState, useEffect, useContext, createContext, useCallback } = React;
// API Configuration
const API_BASE_URL = 'http://127.0.0.1:8001';
// Game Context
const GameContext = createContext();
// TypeScript-like interfaces (comments for structure)
/*
interface GameState {
gameId: string;
playerId: number | null;
playerName: string;
players: string[];
dealerIndex: number;
currentTurn: number;
stage: string;
totalPot: number;
sidePots: Array<{amount: number, eligible_players: number[]}>;
boardCards: string[];
playerCards: string[];
stacks: number[];
playerStates: string[];
currentPot: number[];
actions: {
can_act: boolean;
can_fold?: boolean;
can_call?: boolean;
can_raise?: boolean;
can_check?: boolean;
can_bet?: boolean;
can_allin?: boolean;
call_amount?: number;
min_raise?: number;
max_raise?: number;
};
handStrength?: {
handType: string;
description: string;
strength: number;
cards: string[];
};
showdown?: any;
loading: boolean;
error: string | null;
}
*/
// Game Provider Component
const GameProvider = ({ children }) => {
const [gameState, setGameState] = useState({
gameId: '',
playerId: null,
playerName: '',
players: [],
dealerIndex: 0,
currentTurn: 0,
stage: 'waiting',
totalPot: 0,
sidePots: [],
boardCards: [],
playerCards: [],
stacks: [],
playerStates: [],
currentPot: [],
actions: { can_act: false },
handStrength: null,
showdown: null,
winnings: null,
loading: false,
error: null,
});
// API Functions
const joinGame = async (playerName) => {
setGameState(prev => ({ ...prev, loading: true, error: null }));
try {
const response = await axios.post(`${API_BASE_URL}/join`, { name: playerName });
setGameState(prev => ({
...prev,
playerId: response.data.player_id,
playerName: response.data.name,
loading: false
}));
} catch (error) {
setGameState(prev => ({
...prev,
error: error.response?.data?.detail || '加入游戏失败',
loading: false
}));
}
};
const applyAction = async (action, amount = null) => {
if (gameState.playerId === null) return;
setGameState(prev => ({ ...prev, loading: true }));
try {
const payload = {
player_id: gameState.playerId,
action,
amount
};
await axios.post(`${API_BASE_URL}/apply_action`, payload);
await fetchGameInfo();
} catch (error) {
setGameState(prev => ({
...prev,
error: error.response?.data?.detail || '行动失败',
loading: false
}));
}
};
const fetchGameInfo = async () => {
if (gameState.playerId === null) return;
try {
const response = await axios.get(`${API_BASE_URL}/info/${gameState.playerId}`);
const data = response.data;
console.log('Debug - player_cards from API:', data.player_cards);
console.log('Debug - player_cards type:', typeof data.player_cards);
console.log('Debug - is array:', Array.isArray(data.player_cards));
console.log('Frontend Debug - Raw API data.player_cards:', data.player_cards);
console.log('Frontend Debug - Player ID:', gameState.playerId);
setGameState(prev => ({
...prev,
gameId: data.game_id || '',
players: data.players || [],
dealerIndex: data.dealer_index || 0,
currentTurn: data.current_turn || 0,
stage: data.stage || 'waiting',
totalPot: data.total_pot || 0,
sidePots: data.side_pots || [],
boardCards: data.board_cards || [],
playerCards: data.player_cards || [],
stacks: data.stacks || [],
playerStates: data.player_states || [],
currentPot: data.current_pot || [],
actions: data.actions || { can_act: false },
showdown: data.showdown_hands || null,
winnings: data.winnings || null,
loading: false,
error: null
}));
} catch (error) {
console.error('Failed to fetch game info:', error);
}
};
const fetchHandStrength = async () => {
if (gameState.playerId === null || gameState.playerCards.length === 0) return;
try {
const response = await axios.get(`${API_BASE_URL}/hand_strength/${gameState.playerId}`);
if (!response.data.error) {
setGameState(prev => ({
...prev,
handStrength: response.data
}));
}
} catch (error) {
console.error('Failed to fetch hand strength:', error);
}
};
const resetGame = async (resetChips = true) => {
try {
if (resetChips) {
await axios.post(`${API_BASE_URL}/reset`, { keep_chips: false });
setGameState({
gameId: '',
playerId: null,
playerName: '',
players: [],
dealerIndex: 0,
currentTurn: 0,
stage: 'waiting',
totalPot: 0,
sidePots: [],
boardCards: [],
playerCards: [],
stacks: [],
playerStates: [],
currentPot: [],
actions: { can_act: false },
handStrength: null,
showdown: null,
loading: false,
error: null,
});
} else {
await axios.post(`${API_BASE_URL}/reset`, { keep_chips: true });
setGameState(prev => ({
...prev,
stage: 'waiting',
totalPot: 0,
sidePots: [],
boardCards: [],
playerCards: [],
currentPot: [],
actions: { can_act: false },
handStrength: null,
showdown: null,
loading: false,
error: null,
}));
setTimeout(() => {
fetchGameInfo();
}, 1000);
}
} catch (error) {
console.error('Failed to reset game:', error);
}
};
const leaveTable = async () => {
try {
await resetGame(true);
} catch (error) {
console.error('Failed to leave table:', error);
}
};
// Polling for game state updates
useEffect(() => {
if (gameState.playerId !== null) {
const interval = setInterval(fetchGameInfo, 1000);
return () => clearInterval(interval);
}
}, [gameState.playerId]);
// Fetch hand strength when cards change
useEffect(() => {
if (gameState.playerCards.length > 0) {
fetchHandStrength();
}
}, [gameState.playerCards.length, gameState.boardCards.length]);
return React.createElement(GameContext.Provider, {
value: {
gameState,
joinGame,
applyAction,
fetchGameInfo,
resetGame,
leaveTable
}
}, children);
};
const useGame = () => {
const context = useContext(GameContext);
if (!context) {
throw new Error('useGame must be used within a GameProvider');
}
return context;
};
// Card Component
const Card = ({ card, isBack = false }) => {
if (isBack || !card) {
return React.createElement('div', {
className: 'card back'
}, '🂠');
}
// Convert card notation to display format
const convertCard = (cardStr) => {
if (!cardStr || cardStr.length < 2) return cardStr;
const rank = cardStr.slice(0, -1);
const suit = cardStr.slice(-1).toLowerCase();
const suitSymbols = {
's': '♠',
'h': '♥',
'd': '♦',
'c': '♣'
};
return rank + (suitSymbols[suit] || suit);
};
const displayCard = convertCard(card);
const isRed = displayCard.includes('♥') || displayCard.includes('♦');
return React.createElement('div', {
className: `card ${isRed ? 'red' : ''}`
}, displayCard);
};
const PlayerSeat = ({ player, index, isCurrentPlayer, isDealer, isCurrentTurn, stack, currentBet, state, cards }) => {
const safeStack = typeof stack === 'number' ? stack : 0;
const safeCurrentBet = typeof currentBet === 'number' ? currentBet : 0;
const safeState = state || 'WAITING';
const safeCards = Array.isArray(cards) ? cards : [];
if (isCurrentPlayer) {
console.log('Debug - Current player cards:', cards);
console.log('Debug - Safe cards:', safeCards);
console.log('Debug - Cards length:', safeCards.length);
console.log('Debug - isCurrentPlayer:', isCurrentPlayer);
console.log('Debug - Will show cards:', isCurrentPlayer && safeCards.length > 0);
}
return React.createElement('div', {
className: `player-seat bg-gray-800 rounded-lg p-4 text-white relative ${isCurrentTurn ? 'active' : ''} ${safeState !== 'ACTIVE' && safeState !== 'active' ? 'opacity-50' : ''}`
},
// Dealer Button
isDealer && React.createElement('div', {
className: 'absolute -top-2 -right-2 bg-yellow-500 text-black rounded-full w-8 h-8 flex items-center justify-center text-xs font-bold'
}, 'D'),
// Player Name
React.createElement('div', {
className: 'font-bold mb-2 text-center'
}, `${player || '未知'}${isCurrentPlayer ? ' (你)' : ''}`),
// Cards
React.createElement('div', {
className: 'flex gap-1 justify-center mb-2'
},
isCurrentPlayer && safeCards.length > 0
? safeCards.map((card, idx) => React.createElement(Card, { key: idx, card }))
: [React.createElement(Card, { key: 0, isBack: true }), React.createElement(Card, { key: 1, isBack: true })]
),
// Stack and Bet Info
React.createElement('div', { className: 'text-sm text-center' },
React.createElement('div', null, `筹码: $${safeStack}`),
safeCurrentBet > 0 && React.createElement('div', { className: 'text-yellow-400' }, `下注: $${safeCurrentBet}`),
React.createElement('div', {
className: `text-xs mt-1 font-bold ${
safeState === 'allin' ? 'text-purple-400' :
safeState === 'folded' ? 'text-red-400' :
safeState === 'active' ? 'text-green-400' :
'text-gray-400'
}`
}, safeState === 'allin' ? '🎯 ALL-IN' :
safeState === 'folded' ? '❌ 已弃牌' :
safeState === 'active' ? '✅ 活跃' :
safeState.toUpperCase())
)
);
};
// Game Table Component
const GameTable = () => {
const { gameState } = useGame();
return React.createElement('div', { className: 'poker-table relative rounded-full w-96 h-64 mx-auto mb-8' },
// Center Area - Community Cards & Pot
React.createElement('div', { className: 'absolute inset-0 flex flex-col items-center justify-center' },
// Community Cards
React.createElement('div', { className: 'flex gap-2 mb-4' },
Array.from({ length: 5 }, (_, idx) =>
React.createElement(Card, {
key: idx,
card: gameState.boardCards[idx],
isBack: !gameState.boardCards[idx]
})
)
),
// Pot Display
React.createElement('div', { className: 'text-white text-center' },
React.createElement('div', { className: 'text-2xl font-bold' }, `$${gameState.totalPot}`),
React.createElement('div', { className: 'text-sm' }, `${gameState.stage} 阶段`),
gameState.sidePots.length > 0 && React.createElement('div', { className: 'text-xs mt-1' },
`边池: ${gameState.sidePots.map(pot => `$${pot.amount}`).join(', ')}`
)
)
)
);
};
// Hand Type Display Component
const HandStrengthDisplay = () => {
const { gameState } = useGame();
console.log('HandStrengthDisplay Debug:', {
hasHandStrength: !!gameState.handStrength,
playerCardsLength: gameState.playerCards.length,
handStrength: gameState.handStrength
});
if (!gameState.handStrength || gameState.playerCards.length === 0) {
return React.createElement('div', { className: 'bg-gray-800 rounded-lg p-4 mb-4' },
React.createElement('div', { className: 'text-gray-400 text-sm' }, '等待手牌数据...')
);
}
return React.createElement('div', { className: 'bg-gray-800 rounded-lg p-4 mb-4' },
React.createElement('h3', { className: 'text-white font-bold mb-2' }, '当前牌型'),
React.createElement('div', { className: 'text-yellow-400 text-lg font-semibold' }, gameState.handStrength.hand_type),
React.createElement('div', { className: 'text-gray-400 text-sm mt-1' }, gameState.handStrength.description)
);
};
// Game Result Component
const GameResult = () => {
const { gameState, resetGame, leaveTable } = useGame();
if (!gameState.showdown || Object.keys(gameState.showdown).length === 0) {
return null;
}
useEffect(() => {
const timer = setTimeout(() => {
handleContinueGame();
}, 3000);
return () => clearTimeout(timer);
}, [gameState.showdown]);
const handleContinueGame = () => {
resetGame(false);
};
const handleLeaveTable = () => {
if (confirm('确定要离开牌桌吗?你的筹码将被重置。')) {
leaveTable();
}
};
return React.createElement('div', { className: 'bg-gray-800 rounded-lg p-6 mb-4' },
React.createElement('h3', { className: 'text-white font-bold text-xl mb-4 text-center' }, '🎉 游戏结果 - 摊牌'),
React.createElement('div', { className: 'grid grid-cols-2 gap-4' },
Object.entries(gameState.showdown).map(([playerId, handInfo]) => {
const playerName = gameState.players[parseInt(playerId)] || `玩家${playerId}`;
const isWinner = handInfo.is_winner || false;
const winAmount = gameState.winnings && gameState.winnings[playerId] ? gameState.winnings[playerId] : 0;
return React.createElement('div', {
key: playerId,
className: `p-4 rounded-lg ${isWinner ? 'bg-green-700 border-2 border-green-400' : 'bg-gray-700'}`
},
React.createElement('div', { className: 'text-center mb-2' },
React.createElement('div', { className: `font-bold ${isWinner ? 'text-green-200' : 'text-white'}` },
`${playerName} ${isWinner ? '🏆 获胜者' : ''}`),
React.createElement('div', { className: 'text-sm text-gray-300' }, handInfo.hand_type || '无牌型'),
isWinner && winAmount > 0 && React.createElement('div', { className: 'text-yellow-400 text-sm font-bold' },
`+$${winAmount}`)
),
React.createElement('div', { className: 'flex gap-1 justify-center mb-2' },
(handInfo.cards || []).map((card, idx) => React.createElement(Card, { key: idx, card }))
),
React.createElement('div', { className: 'text-xs text-center text-gray-400' },
handInfo.description || '无描述')
);
})
),
React.createElement('div', { className: 'mt-4 pt-4 border-t border-gray-600' },
React.createElement('h4', { className: 'text-white font-bold mb-3 text-center' }, '💰 本轮结果'),
React.createElement('div', { className: 'text-center mb-3' },
React.createElement('div', { className: 'text-yellow-400 font-bold' },
`总奖池: $${gameState.totalPot || 0}`)
),
gameState.winnings && Object.keys(gameState.winnings).length > 0 &&
React.createElement('div', { className: 'space-y-2' },
React.createElement('h5', { className: 'text-white font-semibold mb-2' }, '🏆 奖金分配:'),
Object.entries(gameState.winnings).map(([playerId, amount]) => {
const playerName = gameState.players[parseInt(playerId)] || `玩家${playerId}`;
const currentStack = gameState.stacks[parseInt(playerId)] || 0;
return React.createElement('div', {
key: playerId,
className: 'flex justify-between items-center bg-green-800 p-2 rounded'
},
React.createElement('span', { className: 'text-green-200 font-bold' }, playerName),
React.createElement('div', { className: 'text-right' },
React.createElement('div', { className: 'text-green-400 font-bold' }, `+$${amount}`),
React.createElement('div', { className: 'text-gray-300 text-xs' }, `总筹码: $${currentStack}`)
)
);
})
)
),
React.createElement('div', { className: 'mt-6 pt-4 border-t border-gray-600 flex gap-4 justify-center' },
React.createElement('button', {
onClick: handleContinueGame,
className: 'bg-green-600 hover:bg-green-700 text-white px-6 py-3 rounded-lg font-bold flex items-center gap-2 transition-all'
},
'🎮 继续下一轮'),
React.createElement('button', {
onClick: handleLeaveTable,
className: 'bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg font-bold flex items-center gap-2 transition-all'
},
'🚪 离开牌桌')
)
);
};
// Action Panel Component
const ActionPanel = () => {
const { gameState, applyAction } = useGame();
const [betAmount, setBetAmount] = useState(0);
if (gameState.stage === 'finished' && gameState.showdown && Object.keys(gameState.showdown).length > 0) {
return React.createElement(GameResult);
}
const isMyTurn = gameState.actions.can_act;
useEffect(() => {
if (gameState.actions.min_raise) {
setBetAmount(gameState.actions.min_raise);
}
}, [gameState.actions.min_raise]);
console.log('ActionPanel Debug:', {
playerId: gameState.playerId,
currentTurn: gameState.currentTurn,
canAct: gameState.actions.can_act,
isMyTurn: isMyTurn,
stage: gameState.stage,
actions: gameState.actions
});
if (!isMyTurn) {
const currentPlayerName = gameState.players[gameState.currentTurn] || '未知玩家';
const myState = gameState.playerStates && gameState.playerStates[gameState.playerId];
const reason = gameState.actions.reason || '';
let statusMessage = '等待行动中...';
let statusColor = 'text-gray-400';
if (reason.includes('allin')) {
statusMessage = '🎯 你已 ALL-IN';
statusColor = 'text-purple-400';
} else if (reason.includes('folded')) {
statusMessage = '❌ 你已弃牌';
statusColor = 'text-red-400';
}
return React.createElement('div', { className: 'bg-gray-800 rounded-lg p-4 text-center text-white' },
React.createElement('div', { className: `text-lg mb-2 ${statusColor} font-bold` }, statusMessage),
React.createElement('div', { className: 'text-gray-400' }, `等待 ${currentPlayerName} 行动`),
React.createElement('div', { className: 'text-xs text-gray-500 mt-2' },
`状态: ${reason || '等待中'}`)
);
}
return React.createElement('div', { className: 'bg-gray-800 rounded-lg p-4' },
React.createElement('h3', { className: 'text-white font-bold mb-4 text-center' }, '选择行动'),
// Action Buttons Row 1
React.createElement('div', { className: 'flex gap-2 mb-4 justify-center' },
gameState.actions.can_fold && React.createElement('button', {
className: 'action-button bg-red-600 hover:bg-red-700 text-white px-6 py-2 rounded-lg font-bold',
onClick: () => applyAction('fold'),
disabled: gameState.loading
}, gameState.loading ? '⏳' : '弃牌'),
gameState.actions.can_check && React.createElement('button', {
className: 'action-button bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg font-bold',
onClick: () => applyAction('check'),
disabled: gameState.loading
}, gameState.loading ? '⏳' : '过牌'),
gameState.actions.can_call && React.createElement('button', {
className: 'action-button bg-green-600 hover:bg-green-700 text-white px-6 py-2 rounded-lg font-bold',
onClick: () => applyAction('call'),
disabled: gameState.loading
}, gameState.loading ? '⏳' : `跟注 $${gameState.actions.call_amount || 0}`),
gameState.actions.can_allin && React.createElement('button', {
className: 'action-button bg-purple-600 hover:bg-purple-700 text-white px-6 py-2 rounded-lg font-bold',
onClick: () => applyAction('allin'),
disabled: gameState.loading
}, gameState.loading ? '⏳' : `All-in $${gameState.stacks[gameState.playerId] || 0}`)
),
// Betting Controls
(gameState.actions.can_bet || gameState.actions.can_raise) && React.createElement('div', { className: 'border-t border-gray-600 pt-4' },
React.createElement('div', { className: 'flex items-center gap-2 mb-3' },
React.createElement('label', { className: 'text-white text-sm font-medium' }, '下注金额:'),
React.createElement('input', {
type: 'range',
min: gameState.actions.min_raise || 0,
max: gameState.actions.max_raise || gameState.stacks[gameState.playerId] || 0,
value: betAmount,
onChange: (e) => setBetAmount(parseInt(e.target.value)),
className: 'flex-1'
}),
React.createElement('input', {
type: 'number',
value: betAmount,
onChange: (e) => setBetAmount(parseInt(e.target.value) || 0),
min: gameState.actions.min_raise || 0,
max: gameState.actions.max_raise || 0,
className: 'w-20 px-2 py-1 bg-gray-700 text-white rounded text-center'
})
),
React.createElement('div', { className: 'flex gap-2 justify-center' },
gameState.actions.can_bet && React.createElement('button', {
className: 'action-button bg-yellow-600 hover:bg-yellow-700 text-white px-4 py-2 rounded-lg font-bold',
onClick: () => applyAction('bet', betAmount),
disabled: gameState.loading
}, gameState.loading ? '⏳' : `下注 $${betAmount}`),
gameState.actions.can_raise && React.createElement('button', {
className: 'action-button bg-orange-600 hover:bg-orange-700 text-white px-4 py-2 rounded-lg font-bold',
onClick: () => applyAction('raise', betAmount),
disabled: gameState.loading
}, gameState.loading ? '⏳' : `加注至 $${betAmount}`)
)
)
);
};
// Player Seats Layout Component
const PlayersLayout = () => {
const { gameState } = useGame();
if (!gameState.players || gameState.players.length === 0) {
return React.createElement('div', { className: 'text-white text-center' }, '等待玩家加入...');
}
return React.createElement('div', { className: 'grid grid-cols-3 gap-4 mb-8' },
gameState.players.map((player, index) =>
React.createElement(PlayerSeat, {
key: index,
player: player || '未知玩家',
index,
isCurrentPlayer: index === gameState.playerId,
isDealer: index === gameState.dealerIndex,
isCurrentTurn: index === gameState.currentTurn,
stack: (gameState.stacks && gameState.stacks[index]) || 0,
currentBet: (gameState.currentPot && gameState.currentPot[index]) || 0,
state: (gameState.playerStates && gameState.playerStates[index]) || 'WAITING',
cards: index === gameState.playerId ? (() => {
console.log('PlayersList Debug - gameState.playerCards:', gameState.playerCards);
console.log('PlayersList Debug - index:', index, 'playerId:', gameState.playerId);
return gameState.playerCards || [];
})() : []
})
)
);
};
// Join Game Form Component
const JoinGameForm = () => {
const { joinGame, gameState } = useGame();
const [playerName, setPlayerName] = useState('');
const handleJoinGame = (e) => {
e.preventDefault();
if (playerName.trim()) {
joinGame(playerName.trim());
}
};
return React.createElement('div', { className: 'max-w-md mx-auto bg-gray-800 rounded-lg p-6' },
React.createElement('h2', { className: 'text-2xl font-bold text-white mb-6 text-center' }, 'ShortDeck Poker'),
React.createElement('form', {},
React.createElement('div', { className: 'mb-6' },
React.createElement('label', { className: 'block text-white text-sm font-bold mb-2' }, '玩家名称'),
React.createElement('input', {
type: 'text',
value: playerName,
onChange: (e) => setPlayerName(e.target.value),
placeholder: '输入你的名称',
className: 'w-full px-3 py-2 bg-gray-700 text-white rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500',
disabled: gameState.loading
})
),
React.createElement('div', { className: 'space-y-3' },
React.createElement('button', {
type: 'button',
onClick: handleJoinGame,
className: 'w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition-colors',
disabled: gameState.loading || !playerName.trim()
}, gameState.loading ? '加入中...' : '🎰 加入游戏'),
React.createElement('div', {
className: 'mt-4 p-3 bg-gray-700 rounded-lg text-sm text-gray-300'
}, React.createElement('div', { className: 'font-bold mb-2' }, '💡 如何与AI对战'),
React.createElement('ol', { className: 'list-decimal list-inside space-y-1 text-xs' },
React.createElement('li', null, '点击"加入游戏"按钮'),
React.createElement('li', null, '在新终端中运行: python client2_random_agent.py'),
React.createElement('li', null, 'RandomAgent会自动加入游戏与您对战')))
)
),
gameState.error && React.createElement('div', {
className: 'mt-4 p-3 bg-red-600 text-white rounded-lg text-sm'
}, gameState.error)
);
};
// Main Game Component
const GameApp = () => {
const { gameState, resetGame, leaveTable } = useGame();
if (gameState.playerId === null) {
return React.createElement(JoinGameForm);
}
const handleLeaveTable = () => {
if (confirm('确定要离开牌桌吗?你的筹码将被重置,需要重新加入游戏。')) {
leaveTable();
}
};
return React.createElement('div', { className: 'container mx-auto px-4 py-8' },
// Header
React.createElement('div', { className: 'flex justify-between items-center mb-8' },
React.createElement('h1', { className: 'text-3xl font-bold text-white' }, 'ShortDeck Poker'),
React.createElement('div', { className: 'flex gap-4 items-center' },
React.createElement('div', { className: 'text-white text-sm' },
React.createElement('div', null, `游戏ID: ${(gameState.gameId || '').slice(0, 8) || '未知'}...`),
React.createElement('div', null, `玩家: ${gameState.playerName || '未知'}`)
),
React.createElement('div', { className: 'flex gap-2' },
React.createElement('button', {
onClick: () => resetGame(true),
className: 'bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg text-sm transition-colors'
}, '🔄 重置游戏'),
React.createElement('button', {
onClick: handleLeaveTable,
className: 'bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg text-sm transition-colors'
}, '🚪 离开牌桌')
)
)
),
// Game Table
React.createElement(GameTable),
// Players Layout
React.createElement(PlayersLayout),
// Hand Strength (if available)
React.createElement(HandStrengthDisplay),
// Action Panel
React.createElement(ActionPanel),
// Error Display
gameState.error && React.createElement('div', {
className: 'fixed top-4 right-4 bg-red-600 text-white p-4 rounded-lg shadow-lg max-w-sm'
}, gameState.error)
);
};
// App Initialization
const App = () => {
return React.createElement(GameProvider,
null,
React.createElement(GameApp)
);
};
// Render the App
ReactDOM.render(React.createElement(App), document.getElementById('root'));
console.log('🚀 ShortDeck Poker Client v1.0 - Professional Edition Loaded');
</script>
</body>
</html>

585
client/simple.html Normal file
View File

@@ -0,0 +1,585 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ShortDeck Poker - Professional Client</title>
<!-- React & TypeScript (via CDN for quick setup) -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script crossorigin src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Custom Styles -->
<style>
body {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
font-family: 'Inter', system-ui, sans-serif;
min-height: 100vh;
margin: 0;
padding: 0;
}
.poker-table {
background: radial-gradient(ellipse at center, #059669 0%, #047857 70%, #065f46 100%);
border: 8px solid #92400e;
box-shadow: 0 0 50px rgba(0, 0, 0, 0.7);
}
.card {
width: 60px;
height: 84px;
border-radius: 8px;
background: white;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 0.9rem;
}
.card.red {
color: #dc2626;
}
.card.back {
background: linear-gradient(45deg, #1e40af, #3730a3);
color: white;
}
.player-seat {
transition: all 0.3s ease;
}
.player-seat.active {
box-shadow: 0 0 20px rgba(34, 197, 94, 0.6);
border: 2px solid #10b981;
}
.action-button {
transition: all 0.2s ease;
}
.action-button:hover {
transform: translateY(-2px);
}
</style>
</head>
<body>
<div id="root">
<div style="color: white; text-align: center; padding: 20px;">
正在加载...
</div>
</div>
<script type="text/babel">
console.log('🚀 开始加载 ShortDeck Poker Client');
const { useState, useEffect, useContext, createContext } = React;
if (typeof React === 'undefined') {
document.getElementById('root').innerHTML = '<div style="color: red; text-align: center; padding: 20px;">React加载失败</div>';
}
// API Configuration
const API_BASE_URL = 'http://127.0.0.1:8001';
// Game Context
const GameContext = createContext();
// Game Provider Component
const GameProvider = ({ children }) => {
const [gameState, setGameState] = useState({
playerId: null,
playerName: '',
players: [],
loading: false,
error: null,
});
const joinGame = async (playerName) => {
setGameState(prev => ({ ...prev, loading: true, error: null }));
try {
const response = await axios.post(`${API_BASE_URL}/join`, { name: playerName });
setGameState(prev => ({
...prev,
playerId: response.data.player_id,
playerName: response.data.name,
loading: false
}));
setTimeout(fetchGameInfo, 500);
} catch (error) {
setGameState(prev => ({
...prev,
error: error.response?.data?.detail || '加入游戏失败',
loading: false
}));
}
};
const fetchGameInfo = async () => {
if (gameState.playerId === null) return;
try {
const response = await axios.get(`${API_BASE_URL}/info/${gameState.playerId}`);
const data = response.data;
setGameState(prev => ({
...prev,
gameId: data.game_id || '',
players: data.players || [],
dealerIndex: data.dealer_index || 0,
currentTurn: data.current_turn || 0,
stage: data.stage || 'waiting',
totalPot: data.total_pot || 0,
sidePots: data.side_pots || [],
boardCards: data.board_cards || [],
playerCards: data.player_cards || [],
stacks: data.stacks || [],
playerStates: data.player_states || [],
currentPot: data.current_pot || [],
actions: data.actions || { can_act: false },
error: null
}));
if (data.player_cards && data.player_cards.length > 0) {
fetchHandStrength();
}
} catch (error) {
console.error('Failed to fetch game info:', error);
}
};
const fetchHandStrength = async () => {
if (gameState.playerId === null) return;
try {
const response = await axios.get(`${API_BASE_URL}/hand_strength/${gameState.playerId}`);
if (!response.data.error) {
setGameState(prev => ({
...prev,
handStrength: response.data
}));
}
} catch (error) {
console.error('Failed to fetch hand strength:', error);
}
};
const applyAction = async (action, amount = null) => {
if (gameState.playerId === null) return;
setGameState(prev => ({ ...prev, loading: true }));
try {
const payload = {
player_id: gameState.playerId,
action,
amount
};
await axios.post(`${API_BASE_URL}/apply_action`, payload);
setTimeout(fetchGameInfo, 500);
} catch (error) {
setGameState(prev => ({
...prev,
error: error.response?.data?.detail || '行动失败',
loading: false
}));
}
};
const resetGame = async () => {
try {
await axios.post(`${API_BASE_URL}/reset`);
setGameState({
playerId: null,
playerName: '',
gameId: '',
players: [],
dealerIndex: 0,
currentTurn: 0,
stage: 'waiting',
totalPot: 0,
sidePots: [],
boardCards: [],
playerCards: [],
stacks: [],
playerStates: [],
currentPot: [],
actions: { can_act: false },
handStrength: null,
loading: false,
error: null,
});
} catch (error) {
console.error('Reset failed:', error);
}
};
useEffect(() => {
if (gameState.playerId !== null) {
const interval = setInterval(fetchGameInfo, 2000);
return () => clearInterval(interval);
}
}, [gameState.playerId]);
return React.createElement(GameContext.Provider, {
value: { gameState, joinGame, applyAction, resetGame, fetchGameInfo }
}, children);
};
const useGame = () => {
const context = useContext(GameContext);
if (!context) {
throw new Error('useGame must be used within a GameProvider');
}
return context;
};
// Join Game Form Component
const JoinGameForm = () => {
const { joinGame, gameState } = useGame();
const [playerName, setPlayerName] = useState('');
const handleJoinGame = (e) => {
e.preventDefault();
if (playerName.trim()) {
joinGame(playerName.trim());
}
};
return React.createElement('div', {
className: 'min-h-screen flex items-center justify-center px-4'
},
React.createElement('div', { className: 'max-w-md w-full bg-gray-800 rounded-lg p-6' },
React.createElement('h2', {
className: 'text-2xl font-bold text-white mb-6 text-center'
}, 'ShortDeck Poker'),
React.createElement('form', { onSubmit: handleJoinGame },
React.createElement('div', { className: 'mb-6' },
React.createElement('label', {
className: 'block text-white text-sm font-bold mb-2'
}, '玩家名称'),
React.createElement('input', {
type: 'text',
value: playerName,
onChange: (e) => setPlayerName(e.target.value),
placeholder: '输入你的名称',
className: 'w-full px-3 py-2 bg-gray-700 text-white rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500',
disabled: gameState.loading
})
),
React.createElement('button', {
type: 'submit',
className: 'w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition-colors',
disabled: gameState.loading || !playerName.trim()
}, gameState.loading ? '加入中...' : '🎰 加入游戏'),
React.createElement('div', {
className: 'mt-4 p-3 bg-gray-700 rounded-lg text-sm text-gray-300'
},
React.createElement('div', { className: 'font-bold mb-2' }, '💡 如何与AI对战'),
React.createElement('ol', { className: 'list-decimal list-inside space-y-1 text-xs' },
React.createElement('li', null, '点击"加入游戏"按钮'),
React.createElement('li', null, '在新终端中运行: python client2_random_agent.py'),
React.createElement('li', null, 'RandomAgent会自动加入游戏与您对战')
)
)
),
gameState.error && React.createElement('div', {
className: 'mt-4 p-3 bg-red-600 text-white rounded-lg text-sm'
}, gameState.error)
)
);
};
// Card format conversion function
const formatCard = (card) => {
if (!card) return '';
// Convert backend format (e.g., 'Kd', 'Ah') to frontend format (e.g., 'K♦', 'A♥')
const suitMap = {
's': '♠',
'h': '♥',
'd': '♦',
'c': '♣'
};
// Extract rank and suit from card string like 'Kd'
const rank = card.slice(0, -1); // Everything except last character
const suit = card.slice(-1).toLowerCase(); // Last character, lowercase
return rank + (suitMap[suit] || suit);
};
// Card Component
const Card = ({ card, isBack = false }) => {
if (isBack || !card) {
return React.createElement('div', {
className: 'card back'
}, '🂠');
}
const formattedCard = formatCard(card);
const isRed = formattedCard.includes('♥') || formattedCard.includes('♦');
return React.createElement('div', {
className: `card ${isRed ? 'red' : ''}`
}, formattedCard);
};
// Player Seat Component
const PlayerSeat = ({ player, index, isCurrentPlayer, isDealer, isCurrentTurn, stack, currentBet, state, cards }) => {
return React.createElement('div', {
className: `bg-gray-800 rounded-lg p-4 text-white relative transition-all ${isCurrentTurn ? 'player-seat active' : ''} ${state !== 'ACTIVE' ? 'opacity-50' : ''}`
},
// Dealer Button
isDealer && React.createElement('div', {
className: 'absolute -top-2 -right-2 bg-yellow-500 text-black rounded-full w-8 h-8 flex items-center justify-center text-xs font-bold'
}, 'D'),
// Player Name
React.createElement('div', {
className: 'font-bold mb-2 text-center'
}, `${player}${isCurrentPlayer ? ' (你)' : ''}`),
// Cards
React.createElement('div', {
className: 'flex gap-1 justify-center mb-2'
},
isCurrentPlayer && cards && cards.length > 0
? cards.map((card, idx) => React.createElement(Card, { key: idx, card }))
: [React.createElement(Card, { key: 0, isBack: true }), React.createElement(Card, { key: 1, isBack: true })]
),
// Stack and Bet Info
React.createElement('div', { className: 'text-sm text-center' },
React.createElement('div', null, `筹码: $${stack || 0}`),
currentBet > 0 && React.createElement('div', { className: 'text-yellow-400' }, `下注: $${currentBet}`),
React.createElement('div', { className: 'text-xs text-gray-400' }, state || 'WAITING')
)
);
};
// Action Panel Component
const ActionPanel = () => {
const { gameState, applyAction } = useGame();
const [raiseAmount, setRaiseAmount] = useState('');
if (!gameState.actions.can_act || gameState.loading) {
return React.createElement('div', {
className: 'bg-gray-800 rounded-lg p-4 text-center text-gray-400'
}, gameState.loading ? '处理中...' : '等待其他玩家行动...');
}
const { actions } = gameState;
return React.createElement('div', { className: 'bg-gray-800 rounded-lg p-4' },
React.createElement('h3', { className: 'text-white font-bold mb-4 text-center' }, '选择你的行动'),
React.createElement('div', { className: 'grid grid-cols-2 gap-3 mb-4' },
// Fold
actions.can_fold && React.createElement('button', {
onClick: () => applyAction('fold'),
className: 'action-button bg-red-600 hover:bg-red-700 text-white py-2 px-4 rounded-lg font-bold transition-all'
}, '弃牌 (Fold)'),
// Check
actions.can_check && React.createElement('button', {
onClick: () => applyAction('check'),
className: 'action-button bg-green-600 hover:bg-green-700 text-white py-2 px-4 rounded-lg font-bold transition-all'
}, '过牌 (Check)'),
// Call
actions.can_call && React.createElement('button', {
onClick: () => applyAction('call'),
className: 'action-button bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg font-bold transition-all'
}, `跟注 $${actions.call_amount || 0}`),
// Bet
actions.can_bet && React.createElement('button', {
onClick: () => applyAction('bet', parseInt(raiseAmount) || actions.min_raise),
className: 'action-button bg-purple-600 hover:bg-purple-700 text-white py-2 px-4 rounded-lg font-bold transition-all'
}, '下注 (Bet)')
),
// Raise section
actions.can_raise && React.createElement('div', { className: 'border-t border-gray-600 pt-4' },
React.createElement('div', { className: 'flex gap-2 items-center mb-2' },
React.createElement('input', {
type: 'number',
value: raiseAmount,
onChange: (e) => setRaiseAmount(e.target.value),
placeholder: `最小: ${actions.min_raise || 0}`,
min: actions.min_raise || 0,
max: actions.max_raise || 1000,
className: 'flex-1 px-3 py-2 bg-gray-700 text-white rounded border-0 focus:ring-2 focus:ring-blue-500'
}),
React.createElement('button', {
onClick: () => applyAction('raise', parseInt(raiseAmount) || actions.min_raise),
className: 'action-button bg-orange-600 hover:bg-orange-700 text-white py-2 px-4 rounded-lg font-bold transition-all'
}, '加注 (Raise)')
),
React.createElement('div', { className: 'text-xs text-gray-400' },
`加注范围: $${actions.min_raise || 0} - $${actions.max_raise || 1000}`
)
)
);
};
// Game Table Component
const GameTable = () => {
const { gameState } = useGame();
return React.createElement('div', { className: 'poker-table rounded-full w-96 h-64 mx-auto mb-8 flex items-center justify-center relative' },
// Community Cards
React.createElement('div', { className: 'flex gap-2' },
gameState.boardCards && gameState.boardCards.length > 0
? gameState.boardCards.map((card, idx) => React.createElement(Card, { key: idx, card }))
: [1, 2, 3, 4, 5].map(i => React.createElement('div', {
key: i,
className: 'w-12 h-16 border-2 border-dashed border-gray-400 rounded opacity-30'
}))
),
// Pot Info
React.createElement('div', {
className: 'absolute top-4 left-1/2 transform -translate-x-1/2 bg-yellow-600 text-white px-4 py-2 rounded-full font-bold'
}, `底池: $${gameState.totalPot || 0}`)
);
};
// Players Layout
const PlayersLayout = () => {
const { gameState } = useGame();
if (gameState.players.length === 0) {
return React.createElement('div', {
className: 'text-center text-gray-400 py-8'
}, '等待其他玩家加入...');
}
return React.createElement('div', { className: 'grid grid-cols-1 md:grid-cols-2 gap-4 mb-8' },
gameState.players.map((player, index) =>
React.createElement(PlayerSeat, {
key: index,
player,
index,
isCurrentPlayer: index === gameState.playerId,
isDealer: index === gameState.dealerIndex,
isCurrentTurn: index === gameState.currentTurn,
stack: gameState.stacks[index],
currentBet: gameState.currentPot[index],
state: gameState.playerStates[index],
cards: index === gameState.playerId ? gameState.playerCards : []
})
)
);
};
// Hand Strength Display
const HandStrengthDisplay = () => {
const { gameState } = useGame();
if (!gameState.handStrength) return null;
const { handStrength } = gameState;
const strengthPercent = (handStrength.strength * 100).toFixed(1);
return React.createElement('div', { className: 'bg-gray-800 rounded-lg p-4 mb-4' },
React.createElement('h3', { className: 'text-white font-bold mb-2' }, '手牌强度'),
React.createElement('div', { className: 'mb-2' },
React.createElement('div', { className: 'text-lg font-bold text-yellow-400' }, handStrength.hand_type),
React.createElement('div', { className: 'text-sm text-gray-300' }, handStrength.description)
),
React.createElement('div', { className: 'bg-gray-700 rounded-full h-2 mb-2' },
React.createElement('div', {
className: 'bg-gradient-to-r from-red-500 via-yellow-500 to-green-500 h-2 rounded-full transition-all',
style: { width: `${strengthPercent}%` }
})
),
React.createElement('div', { className: 'text-xs text-gray-400 text-center' },
`强度: ${strengthPercent}%`
)
);
};
// Game View Component
const GameView = () => {
const { gameState, resetGame } = useGame();
return React.createElement('div', { className: 'container mx-auto px-4 py-8' },
// Header
React.createElement('div', { className: 'flex justify-between items-center mb-8' },
React.createElement('h1', { className: 'text-3xl font-bold text-white' }, 'ShortDeck Poker'),
React.createElement('div', { className: 'flex gap-4' },
React.createElement('div', { className: 'text-white text-sm' },
React.createElement('div', null, `游戏ID: ${gameState.gameId.slice(0, 8)}...`),
React.createElement('div', null, `玩家: ${gameState.playerName}`),
React.createElement('div', null, `阶段: ${gameState.stage}`)
),
React.createElement('button', {
onClick: resetGame,
className: 'bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg text-sm'
}, '重置游戏')
)
),
// Game Table
React.createElement(GameTable),
// Players Layout
React.createElement(PlayersLayout),
// Hand Strength (if available)
React.createElement(HandStrengthDisplay),
// Action Panel
React.createElement(ActionPanel),
// Error Display
gameState.error && React.createElement('div', {
className: 'fixed top-4 right-4 bg-red-600 text-white p-4 rounded-lg shadow-lg max-w-sm'
}, gameState.error)
);
};
// Main App Component
const GameApp = () => {
const { gameState } = useGame();
if (gameState.playerId === null) {
return React.createElement(JoinGameForm);
}
return React.createElement(GameView);
};
// App Initialization
const App = () => {
return React.createElement(GameProvider, null,
React.createElement(GameApp)
);
};
try {
ReactDOM.render(React.createElement(App), document.getElementById('root'));
console.log('✅ ShortDeck Poker Client 加载成功');
} catch (error) {
console.error('❌ React 渲染失败:', error);
document.getElementById('root').innerHTML = `
<div style="color: red; text-align: center; padding: 20px;">
<h2>渲染失败</h2>
<p>错误: ${error.message}</p>
</div>
`;
}
</script>
</body>
</html>

243
client2_random_agent.py Normal file
View File

@@ -0,0 +1,243 @@
#!/usr/bin/env python3
import requests
import time
import random
import json
import sys
from typing import Dict, List, Optional
class RandomAgentClient:
def __init__(self, server_url: str = "http://localhost:8001", player_name: str = "RandomBot"):
self.server_url = server_url.rstrip('/')
self.player_name = player_name
self.player_id: Optional[int] = None
self.game_active = False
def join_game(self) -> bool:
response = requests.post(
f"{self.server_url}/join",
json={"name": self.player_name},
timeout=5
)
if response.status_code == 200:
data = response.json()
self.player_id = data["player_id"]
print(f" {self.player_name} 成功加入游戏玩家ID: {self.player_id}")
return True
else:
print(f" 加入游戏失败: {response.status_code} - {response.text}")
return False
def get_game_info(self) -> Optional[Dict]:
if self.player_id is None:
return None
try:
response = requests.get(
f"{self.server_url}/info/{self.player_id}",
timeout=5
)
if response.status_code == 200:
return response.json()
else:
print(f" 获取游戏信息失败: {response.status_code}")
return None
except requests.RequestException as e:
print(f" 获取游戏信息时连接失败: {e}")
return None
def get_valid_actions(self) -> List[str]:
if self.player_id is None:
return []
try:
response = requests.get(
f"{self.server_url}/valid_actions/{self.player_id}",
timeout=5
)
if response.status_code == 200:
data = response.json()
return data.get("valid_actions", [])
else:
return []
except requests.RequestException:
return []
def make_random_action(self, valid_actions, game_info) -> bool:
if not valid_actions:
print(" 没有可用动作")
return False
# 随机选择一个动作, 弃牌率高, todo
action = random.choice(valid_actions)
amount = 10
if action in ["raise", "bet"]:
player_stack = game_info.get("stacks", [1000])[self.player_id] if self.player_id < len(game_info.get("stacks", [])) else 1000
min_bet = max(game_info.get("current_pot", [0])) if game_info.get("current_pot") else 10
max_bet = min(player_stack, player_stack // 2) # 最多下注一半筹码
if max_bet > min_bet:
amount = random.randint(min_bet, max_bet)
else:
amount = min_bet
payload = {
"player_id": self.player_id,
"action": action,
"amount": amount
}
response = requests.post(
f"{self.server_url}/apply_action",
json=payload,
timeout=5
)
if response.status_code == 200:
action_str = f"{action}" + (f" {amount}" if amount else "")
print(f" {self.player_name} 执行动作: {action_str}")
return True
else:
print(f" 动作执行失败: {response.status_code} - {response.text}")
return False
def is_my_turn(self, game_info: Dict) -> bool:
if not game_info or self.player_id is None:
return False
current_turn = game_info.get("current_turn", -1)
return current_turn == self.player_id
def display_game_state(self, game_info: Dict):
if not game_info:
return
print(f"\n游戏状态:")
print(f" 阶段: {game_info.get('stage', 'unknown')}")
print(f" 总奖池: {game_info.get('total_pot', 0)}")
print(f" 当前轮到: 玩家 {game_info.get('current_turn', -1)}")
print(f" 我的ID: {self.player_id}")
print(f" 我的手牌: {game_info.get('player_cards', [])}")
print(f" 公共牌: {game_info.get('board_cards', [])}")
stacks = game_info.get('stacks', [])
if stacks and self.player_id is not None and self.player_id < len(stacks):
print(f" 我的筹码: {stacks[self.player_id]}")
def wait_for_players(self) -> bool:
print(" 等待其他玩家加入游戏...")
for _ in range(60): #60S
game_info = self.get_game_info()
if game_info:
players = game_info.get("players", [])
if len(players) >= 2:
print(f" 游戏开始!玩家列表: {players}")
return True
time.sleep(1)
print(" 等待超时,未能开始游戏......")
return False
def game_loop(self):
print(f" {self.player_name} 开始游戏循环......")
consecutive_errors = 0
while self.game_active and consecutive_errors < 5:
try:
game_info = self.get_game_info()
if not game_info:
consecutive_errors += 1
time.sleep(2)
continue
consecutive_errors = 0
self.display_game_state(game_info)
if self.is_my_turn(game_info):
print(f" 轮到 {self.player_name} 行动...")
valid_actions = self.get_valid_actions()
if valid_actions:
print(f"可用动作: {valid_actions}")
self.make_random_action(valid_actions, game_info)
else:
print(" 没有可用动作")
stage = game_info.get("stage", "")
if stage in ["game_over", "showdown", "finished"]:
print(" 游戏结束")
self.show_final_results(game_info)
time.sleep(3)
print(" 准备下一轮游戏...")
continue
time.sleep(2)
except Exception as e:
print(f" 游戏循环出错: {e}")
consecutive_errors += 1
time.sleep(2)
if consecutive_errors >= 5:
print(" 连续错误过多,退出游戏")
def show_final_results(self, game_info):
print("\n 游戏结果:")
# todo
response = requests.get(f"{self.server_url}/showdown", timeout=5)
if response.status_code == 200:
showdown_data = response.json()
print(json.dumps(showdown_data, indent=2))
def run(self):
print(f" 启动 RandomAgent 客户端: {self.player_name}")
print(f" 连接服务器: {self.server_url}")
if not self.join_game():
return False
if not self.wait_for_players():
return False
self.game_active = True
self.game_loop()
return True
def main():
import argparse
parser = argparse.ArgumentParser(description="RandomAgent")
parser.add_argument("--server", default="http://localhost:8001")
parser.add_argument("--name", default="RandomBot")
parser.add_argument("--seed", type=int)
args = parser.parse_args()
if args.seed:
random.seed(args.seed)
print(f" 设置随机种子: {args.seed}")
client = RandomAgentClient(args.server, args.name)
success = client.run()
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,19 @@
from .simulation import Simulation
from .agent import Agent, HumanAgent
from .game_stage import GameStage, BlindConfig
from .hand_evaluator import HandEvaluator
from .hand_ranking import HandRanking
from .card import Card
from .side_pot import SidePot
__all__ = [
"Simulation",
"Agent",
"HumanAgent",
"GameStage",
"BlindConfig",
"HandEvaluator",
"HandRanking",
"Card",
"SidePot"
]

Binary file not shown.

View File

@@ -1,4 +1,3 @@
"""ShortDeck card model (6-A, 36 cards)."""
from __future__ import annotations
from enum import IntEnum

View File

@@ -73,6 +73,7 @@ class HandRanking:
def get_strength(self) -> int:
# 返回牌力 还是 牌型+点数
# 基础强度 = 牌型强度 * 1000000
# todo
strength = self.hand_type.strength * 1000000
for i, rank in enumerate(self.key_ranks):

View File

@@ -99,6 +99,5 @@ class SidePotManager:
return winnings
def reset(self):
"""重置边池管理器"""
self.pots.clear()
self.player_total_investment.clear()

View File

@@ -42,6 +42,9 @@ class Simulation:
self.side_pot_manager = SidePotManager()
self.stacks: List[int] = [1000] * len(agents) # 默认筹码
# 用于结算
self.hand_completed = False
self.new_round()
def new_round(self):
@@ -54,6 +57,7 @@ class Simulation:
self.current_stage = GameStage.PREFLOP
self.player_states = [PlayerState.ACTIVE] * len(self.agents)
self.betting_round_complete = False
self.hand_completed = False # 重置完成标志
# 重置下注状态
self.pot = [0] * len(self.agents)
@@ -141,25 +145,19 @@ class Simulation:
return max(0, max_pot - self.pot[pid])
def get_min_raise_amount(self, pid) -> int:
"""最小加注金额"""
call_amount = self.get_call_amount(pid)
min_raise = call_amount + max(self.last_raise_amount, self.blind_config.big_blind)
return min_raise
def get_max_bet_amount(self, pid) -> int:
"""最大下注金额(剩余筹码)"""
if pid >= len(self.stacks):
return 0
return self.stacks[pid]
def is_all_in_amount(self, pid, amount) -> bool:
"""检查是否为allin"""
return amount >= self.stacks[pid]
def validate_bet_amount(self, pid, action, amount) -> tuple[bool, str, int]:
"""
验证下注金额合法性
"""
if pid >= len(self.stacks):
return False, "无效玩家", amount
@@ -178,12 +176,16 @@ class Simulation:
if call_amount == 0:
return False, "不需要跟注", 0
# All-in call
if call_amount >= available_stack:
return True, "", available_stack
return True, "", call_amount
elif action == "allin":
if available_stack <= 0:
return False, "没有筹码进行 all-in", 0
return True, "", available_stack
elif action in ["bet", "raise"]:
if amount <= 0:
return False, "无效下注金额", amount
@@ -207,6 +209,9 @@ class Simulation:
return False, "无效行为", amount
def get_available_actions(self, pid: int) -> dict:
if self.current_stage in [GameStage.FINISHED, GameStage.SHOWDOWN]:
return {"can_act": False, "reason": "游戏已结束" if self.current_stage == GameStage.FINISHED else "摊牌阶段"}
if pid != self.current_turn:
return {"can_act": False, "reason": "不是你的回合"}
@@ -214,7 +219,7 @@ class Simulation:
return {"can_act": False, "reason": "无效玩家"}
state = self.player_states[pid]
if state in [PlayerState.FOLDED, PlayerState.ALLIN, PlayerState.OUT]:
if state in [PlayerState.FOLDED, PlayerState.ALLIN]:
return {"can_act": False, "reason": f"Player state: {state}"}
call_amount = self.get_call_amount(pid)
@@ -225,7 +230,7 @@ class Simulation:
"can_fold": True,
"can_check": call_amount == 0,
"can_call": call_amount > 0 and call_amount < available_stack,
"can_bet": max(self.pot) == 0 and available_stack > 0,
"can_bet": call_amount == 0 and available_stack > 0,
"can_raise": call_amount > 0 and available_stack > call_amount,
"can_allin": available_stack > 0,
"call_amount": call_amount,
@@ -241,27 +246,33 @@ class Simulation:
"""
检查当前下注轮是否完成
"""
active_players = [i for i, state in enumerate(self.player_states)
if state in (PlayerState.ACTIVE, PlayerState.CALLED)]
# 首先检查是否只剩一个未弃牌的玩家
non_folded_players = [i for i, state in enumerate(self.player_states)
if state != PlayerState.FOLDED]
if len(active_players) <= 1:
if len(non_folded_players) <= 1:
return True
active_or_allin_players = [i for i, state in enumerate(self.player_states)
if state in (PlayerState.ACTIVE, PlayerState.CALLED, PlayerState.ALLIN)]
all_allin_or_folded = all(state in (PlayerState.ALLIN, PlayerState.FOLDED)
for state in self.player_states)
if all_allin_or_folded:
return True
# 检查所有active玩家是否都已投入相同金额且所有人都已经行动过
max_pot = self.get_current_max_bet()
# 统计还需要行动的玩家
players_need_action = []
for i in active_players:
for i in active_or_allin_players:
# allin
if self.player_states[i] == PlayerState.ALLIN:
continue
# 投入金额不足的玩家需要行动
continue
if self.pot[i] < max_pot:
players_need_action.append(i)
# Active状态的玩家如果还没有在本轮行动过也需要行动
elif self.player_states[i] == PlayerState.ACTIVE:
# 在翻前,大盲玩家即使投入了足够金额,也有权行动一次
if (self.current_stage == GameStage.PREFLOP and
i == self.blind_config.get_bb_position(len(self.agents), self.dealer_position)):
# 检查大盲是否已经行动过(除了盲注)
@@ -289,6 +300,12 @@ class Simulation:
self.complete_hand()
return
if self.current_stage == GameStage.SHOWDOWN:
self.current_stage = GameStage.FINISHED
self.complete_hand()
return
# 重置下注轮状态
self.betting_round_complete = False
@@ -306,6 +323,7 @@ class Simulation:
def get_next_active_player(self, start_pos) -> Optional[int]:
for i in range(len(self.agents)):
pos = (start_pos + i) % len(self.agents)
# 只有ACTIVE状态的玩家可以行动ALLIN和FOLDED的玩家不能行动
if self.player_states[pos] == PlayerState.ACTIVE:
return pos
return None
@@ -313,7 +331,7 @@ class Simulation:
def get_side_pots(self) -> List:
active_players = [
i for i, state in enumerate(self.player_states)
if state not in [PlayerState.FOLDED, PlayerState.OUT]
if state not in [PlayerState.FOLDED]
]
return self.side_pot_manager.create_side_pots(active_players)
@@ -375,6 +393,29 @@ class Simulation:
raise ValueError("跟注金额>0, 无法过牌,需要跟注或弃牌")
self.player_states[pid] = PlayerState.CALLED
elif action == "allin":
# all-in
actual_amount = self.stacks[pid]
if actual_amount <= 0:
raise ValueError("没有可用筹码进行 all-in")
self.player_states[pid] = PlayerState.ALLIN
self.pot[pid] += actual_amount
self.stacks[pid] = 0
self.total_pot += actual_amount
self.side_pot_manager.add_investment(pid, actual_amount)
# 更新最后加注金额(如果 all-in 金额超过跟注金额)
call_amount = self.get_call_amount(pid)
raise_amount = actual_amount - call_amount
if raise_amount > 0:
self.last_raise_amount = raise_amount
self.min_raise = raise_amount
for i, state in enumerate(self.player_states):
if i != pid and state == PlayerState.CALLED:
self.player_states[i] = PlayerState.ACTIVE
elif action in ("bet", "raise"):
if amount is None:
raise ValueError(f"{action} 需要指定金额")
@@ -446,7 +487,6 @@ class Simulation:
def evaluate_player_hand(self, pid: int) -> Optional[HandRanking]:
"""评估玩家手牌强度"""
if pid >= len(self.agents):
return None
@@ -454,22 +494,17 @@ class Simulation:
return None
try:
# 获取玩家手牌
player_cards = self.player_cards(pid)
# 获取公共牌
board_cards = self.board_cards(self.current_stage.value)
# 至少需要5张牌才能评估
all_cards = player_cards + board_cards
if len(all_cards) < 5:
return None
# 如果正好5张牌直接评估
if len(all_cards) == 5:
return HandEvaluator.evaluate5Cards(all_cards)
# 如果超过5张牌找最佳组合
return HandEvaluator.evaluateHand(all_cards)
except Exception as e:
@@ -478,7 +513,7 @@ class Simulation:
def get_active_players(self) -> List[int]:
return [i for i, state in enumerate(self.player_states)
if state not in [PlayerState.FOLDED, PlayerState.OUT]]
if state not in [PlayerState.FOLDED]]
def is_hand_complete(self) -> bool:
active_players = self.get_active_players()
@@ -522,9 +557,8 @@ class Simulation:
winner_id = list(winners.keys())[0]
return {winner_id: self.total_pot}
# 多人摊牌,使用边池分配
# 多人摊牌
if len(winners) > 1:
#转换HandRanking为数值强度
hand_strengths = {}
for pid, ranking in winners.items():
if ranking is not None:
@@ -539,16 +573,31 @@ class Simulation:
def complete_hand(self) -> Dict:
if not self.is_hand_complete():
return {"complete": False, "message": "牌局未结束"}
if self.hand_completed:
return {
"complete": True,
"winners": [],
"winnings": {},
"final_stacks": self.stacks.copy(),
"showdown_hands": {},
"message": "手牌已完成"
}
winners = self.determine_winners()
winnings = self.distribute_pot()
# 更新筹码
for pid, amount in winnings.items():
if pid < len(self.stacks):
self.stacks[pid] += amount
self.total_pot = 0
self.pot = [0] * len(self.agents)
self.side_pot_manager.reset()
self.current_stage = GameStage.FINISHED
self.hand_completed = True
result = {
"complete": True,
@@ -557,14 +606,22 @@ class Simulation:
"final_stacks": self.stacks.copy(),
"showdown_hands": {}
}
active_players = [i for i, state in enumerate(self.player_states)
if state != PlayerState.FOLDED]
# 摊牌信息
for pid, ranking in winners.items():
if ranking is not None:
for pid in active_players:
player_hand = self.player_cards(pid)
if len(player_hand) >= 2:
evaluator = HandEvaluator()
board_cards = self.board_cards()
ranking = evaluator.evaluate(player_hand, board_cards)
result["showdown_hands"][pid] = {
"cards": [str(card) for card in self.player_cards(pid)],
"hand_type": ranking.hand_type.type_name,
"description": str(ranking)
"cards": [str(card) for card in player_hand],
"hand_type": ranking.hand_type.type_name if ranking else "无牌型",
"description": str(ranking) if ranking else "无效手牌",
"is_winner": pid in winners
}
return result

View File

@@ -4,3 +4,121 @@
{"history": [{"pid": 0, "action": "check", "amount": null}], "players": ["Agent0", "Agent1"], "player_cards": ["Ac6s", "8hQs"], "board": "9s8s9h7cJh"}
{"history": [{"pid": 0, "action": "check", "amount": null}], "players": ["Agent0", "Agent1"], "player_cards": ["Kc6c", "9hKs"], "board": "8dJs7h7dTs"}
{"history": [{"pid": 0, "action": "check", "amount": null}], "players": ["Agent0", "Agent1"], "player_cards": ["AhTd", "QcTc"], "board": "9hKdKcQh7h"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "bet", "amount": 269}], "players": ["Agent0", "Agent1"], "player_cards": ["AsAd", "8dJc"], "board": "7s8cKcJdTh"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "bet", "amount": 474}], "players": ["Agent0", "Agent1", "Agent2", "Agent3"], "player_cards": ["6s9s", "Ks7c", "6hQs", "6cAd"], "board": "7hQh7d8dAs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 3, "action": "bet", "amount": 486}], "players": ["Agent0", "Agent1", "Agent2", "Agent3"], "player_cards": ["QsAs", "6sAc", "6hKd", "Tc7c"], "board": "7dTdQcKsKc"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["AhTc", "As9c"], "board": "9hKd8sJc7d"}
{"history": [{"pid": 0, "action": "bet", "amount": 123}], "players": ["Agent0"], "player_cards": ["TdKs"], "board": "AhQs7c9hQc"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 4}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["AdKd", "JhQc", "7d7c"], "board": "Kh9c7hTc8h"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}], "players": ["Agent0", "Agent1"], "player_cards": ["Qh6s", "Ac9c"], "board": "QdKcKdQs7h"}
{"history": [{"pid": 0, "action": "bet", "amount": 477}], "players": ["Agent0"], "player_cards": ["9d6d"], "board": "KdKsQdKhJs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}], "players": ["Agent0", "Agent1"], "player_cards": ["TcJs", "KcAd"], "board": "Qh6s7dTd8h"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["As9d", "AhQs", "Ad6d"], "board": "6s6h9hAc8h"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["ThAh", "KsJd"], "board": "Js8sTc6hTd"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["TcAh", "Kh8d", "TdKc"], "board": "Jd8hJs9h7h"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}], "players": ["Agent0", "Agent1"], "player_cards": ["7hTh", "QsTd"], "board": "JcKc9cAh9s"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["8s6h", "7sKd", "TdJs"], "board": "QhJdJh7d7c"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["KhQh", "7cJc"], "board": "AdAh7sQsTc"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["8c9d", "Ah8d"], "board": "6c6dTsQsJs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["TdJs", "9cQd"], "board": "8cTc8sAs9s"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}], "players": ["Agent0", "Agent1"], "player_cards": ["Qc7h", "QsAc"], "board": "Jc8hQhJh6s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 299}], "players": ["Agent0", "Agent1"], "player_cards": ["Th7s", "Ac6c"], "board": "QcKc7dQs8d"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}], "players": ["Agent0", "Agent1"], "player_cards": ["Kc6s", "JdAc"], "board": "Th8s7c9h9c"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 3}], "players": ["Agent0", "Agent1"], "player_cards": ["7sTh", "Kh6c"], "board": "7cKdKcAcJd"}
{"history": [{"pid": 3, "action": "small_blind", "amount": 1}, {"pid": 4, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}], "players": ["Agent0", "Agent1", "Agent2", "Agent3", "Agent4"], "player_cards": ["Ts8c", "9dJs", "As6d", "Kd8s", "Tc8d"], "board": "QdThQcAdTd"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Qc7s", "7hJh"], "board": "Jd9sTcQh6h"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 276}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["7dTc", "9d6d", "7cAs"], "board": "Qc6h8c9sTs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 310}], "players": ["Agent0", "Agent1"], "player_cards": ["Td6s", "9h9d"], "board": "QcKs6dKh9s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Td7c", "Qh7s"], "board": "8dKs9dTsJs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["8cKc", "7d6h"], "board": "9dTcJh6d7h"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 66}], "players": ["Agent0", "Agent1"], "player_cards": ["Ad6h", "8h7s"], "board": "Ts6c8cThAs"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2", "Agent3"], "player_cards": ["9s9d", "AsTh", "7d9h", "Kh7s"], "board": "7c6dKd6hJh"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 4, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2", "Agent3", "Agent4"], "player_cards": ["9cKc", "AhQc", "7hQd", "Ac8h", "JsTd"], "board": "QhQsTcTsKh"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 382}], "players": ["Agent0", "Agent1"], "player_cards": ["Qh8c", "6sAd"], "board": "9s9h7h6h7c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Tc8c", "As8s"], "board": "Qs7cJd7dQh"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Ah7d", "KcKd"], "board": "6cQdQhTh8c"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 13}], "players": ["Agent0", "Agent1"], "player_cards": ["KdTs", "8s6h"], "board": "ThKhJsAc8d"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Ac7c", "Jc9h"], "board": "JdAsQh6hKh"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Ks8s", "Qh9h"], "board": "8cTd7cJdAs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 15}], "players": ["Agent0", "Agent1"], "player_cards": ["8s6h", "9dTh"], "board": "JdJh9c8cTc"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 33}], "players": ["Agent0", "Agent1"], "player_cards": ["Qh8c", "TcAd"], "board": "9dTdJdJh6s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 22}], "players": ["Agent0", "Agent1"], "player_cards": ["8cTd", "9sKd"], "board": "8h6d7cTsKc"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["KdKc", "Td7s", "TsQd"], "board": "9hAh7dAsAd"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2", "Agent3"], "player_cards": ["8sAs", "Ac6d", "8d9s", "Kh7s"], "board": "6cJdTs8cTh"}
{"history": [{"pid": 3, "action": "small_blind", "amount": 1}, {"pid": 4, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2", "Agent3", "Agent4"], "player_cards": ["7c6d", "8d9d", "JdQs", "KsAs", "JsAd"], "board": "Td9c9sQhQd"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["9cQs", "8cQc"], "board": "9h9sThAhJs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6d6s", "9s8d"], "board": "7hJdAhTd6h"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Tc9h", "AsKs"], "board": "ThKdKc8cAd"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Kc9d", "8h7c"], "board": "Jc7hJhQsJs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}], "players": ["Agent0", "Agent1"], "player_cards": ["6cAd", "JcJh"], "board": "QcQh9cQd8c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Qc9s", "9cTh"], "board": "Ac8sKhTd6s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 108}], "players": ["Agent0", "Agent1"], "player_cards": ["KhTc", "9cQs"], "board": "7sTdAs8d9h"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6dQd", "AhTd"], "board": "9dJh7sAsQh"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6hQc", "JcJh"], "board": "Qh6c7c9c6s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 101}], "players": ["Agent0", "Agent1"], "player_cards": ["8cTs", "KdTd"], "board": "8dJc9s9cQd"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 46}], "players": ["Agent0", "Agent1"], "player_cards": ["Ad9d", "Ah7d"], "board": "8dTsJc9s7c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}], "players": ["Agent0", "Agent1"], "player_cards": ["TsQh", "7dQd"], "board": "8h6sTcJdQs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}], "players": ["Agent0", "Agent1"], "player_cards": ["TcTd", "AhKc"], "board": "6s9cAcJs7s"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}], "players": ["Agent0", "Agent1"], "player_cards": ["Ts8d", "QdQs"], "board": "TcJdKhJs7c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}], "players": ["Agent0", "Agent1"], "player_cards": ["Qc7h", "Jd7s"], "board": "8c9sAhQdQh"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 205}], "players": ["Agent0", "Agent1"], "player_cards": ["8d9h", "6s8c"], "board": "Tc9d6dQsKs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["7hAs", "JdTc"], "board": "6sTd8cQdKh"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 118}], "players": ["Agent0", "Agent1"], "player_cards": ["JdTh", "TdJh"], "board": "Qh7dKc8sAs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["8dKs", "Qh9h"], "board": "Td7c8h9cKd"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 131}], "players": ["Agent0", "Agent1"], "player_cards": ["Qh6h", "Qc9d"], "board": "7hJsTd7cKh"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["7hTs", "As9h"], "board": "6d6c8cJs7d"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}], "players": ["Agent0", "Agent1"], "player_cards": ["9hTh", "7c6h"], "board": "8h8d6cQh7d"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 108}], "players": ["Agent0", "Agent1"], "player_cards": ["TcAh", "9h9c"], "board": "Qc6hJc7hAc"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 61}], "players": ["Agent0", "Agent1"], "player_cards": ["7cKd", "8s9c"], "board": "6dQsTs8dTc"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 937}], "players": ["Agent0", "Agent1"], "player_cards": ["JhTd", "Qs6s"], "board": "Qd7c9cQc7d"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["TdAh", "JdAd"], "board": "Js9cTc8h7c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["8c8h", "Jh7d"], "board": "7cAs9hKdTs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["TsJs", "Kd7c"], "board": "8dKs6h8h9d"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 404}], "players": ["Agent0", "Agent1"], "player_cards": ["KhJh", "8cTc"], "board": "Qh7d8sQs6s"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Qh6s", "9s7d"], "board": "6h8cKh8hJh"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["AsKc", "QsJc"], "board": "KsQcAd9cTh"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1404}], "players": ["Agent0", "Agent1"], "player_cards": ["AsTc", "KhJd"], "board": "9d6h9cQhKs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["JcQh", "8hQc"], "board": "As6h7sTc6c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}], "players": ["Agent0", "Agent1"], "player_cards": ["Ac6s", "9dAh"], "board": "AsTs8h8c7d"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 247}], "players": ["Agent0", "Agent1"], "player_cards": ["As7d", "Kh9h"], "board": "Jh6sJc7h6c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["AsQs", "Qd6d"], "board": "Tc8c8dTdQc"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 663}], "players": ["Agent0", "Agent1"], "player_cards": ["9sQs", "7d6s"], "board": "7cKh7h9d7s"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 554}], "players": ["Agent0", "Agent1"], "player_cards": ["7d9h", "8s7s"], "board": "TsAh8cQdJs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 509}], "players": ["Agent0", "Agent1"], "player_cards": ["Ah8d", "AsKh"], "board": "7h6h7sKc6s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Kh6h", "9cAs"], "board": "9dQs8dKsAd"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 644}], "players": ["Agent0", "Agent1"], "player_cards": ["Kc6s", "Tc8h"], "board": "AsTs6h7hJh"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1254}], "players": ["Agent0", "Agent1"], "player_cards": ["AdKs", "Ac7s"], "board": "Td8h7d6h6c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1257}], "players": ["Agent0", "Agent1"], "player_cards": ["8h6s", "KsTc"], "board": "Qc8d8sKh6c"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["7cAd", "6dJh"], "board": "QdQh7hTd8s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6d7d", "TdAh"], "board": "Ad7s8s9cKd"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Kc9s", "TcJc"], "board": "Ad7c6c8s9c"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["9s9c", "QcQs"], "board": "JsJh8h6dTh"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2", "Agent3"], "player_cards": ["TsQd", "Ad6s", "8s9d", "6h9s"], "board": "TcKd8dJs7h"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["TdAd", "6h8d"], "board": "9h6c9cKdJs"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["QdJc", "9c6s", "9s9h"], "board": "KdAsTsKh7d"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["9h8d", "9d9s"], "board": "7sQsAdKd9c"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["QsJd", "KsAd"], "board": "8d6sJs7cKh"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["8dQh", "ThQc"], "board": "Ks9cAdTd8h"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6hTh", "QcKs"], "board": "As6sJh9c9d"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["QhJd", "9s7s"], "board": "Td9d9c8d9h"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Ah6s", "6h7d"], "board": "AdQdQhTs8d"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["7hKh", "8dJh"], "board": "TsKcQsKd7d"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["8s6d", "9sAd"], "board": "Qh8h9c8dTs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["KhQs", "Ah9h"], "board": "Qc8dQhKcAd"}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2", "Agent3"], "player_cards": ["9h7c", "JdQc", "Tc7d", "8c9c"], "board": "Kc6cKs7h7s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 384}], "players": ["Agent0", "Agent1"], "player_cards": ["7sAd", "KsAs"], "board": "QhAcKhTc6d"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 4}], "players": ["Agent0", "Agent1"], "player_cards": ["Ts7c", "Td8d"], "board": "KcTh6cAc6d"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 93}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["JhQd", "ThAc", "9cAd"], "board": "Qs6h8cAh7s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["9dJd", "Ad7c"], "board": "KsTdJcAc8h"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["Qs9c", "8hKc"], "board": "QdQhJs6sTh"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["QsKd", "As7d"], "board": "9s8c7c9c8s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 75}], "players": ["Agent0", "Agent1"], "player_cards": ["Ks6h", "9s7s"], "board": "9d7d6cJd6d"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6cAh", "9cKc"], "board": "6dTcTsAsQs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}], "players": ["Agent0", "Agent1", "Agent2"], "player_cards": ["9c9d", "Kh6d", "9hTc"], "board": "KcJhJcKd7h"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 296}], "players": ["Agent0", "Agent1"], "player_cards": ["Js8c", "Tc9d"], "board": "AdAsJhQhTs"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["8cJd", "6dAs"], "board": "9d6s9s6hKh"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6h7d", "6dAh"], "board": "KcKh8sThKs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6cTh", "QdJc"], "board": "8hQcKsJhJs"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["8dQc", "JsQd"], "board": "TsTcJdAdKh"}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["6dQd", "Jd6c"], "board": "AdJhThQs8s"}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}], "players": ["Agent0", "Agent1"], "player_cards": ["KsQs", "7sTh"], "board": "9c9dQh6sJs"}

View File

@@ -0,0 +1,7 @@
from .arena_adapter import ArenaGame
from .persistence import append_game_history
__all__ = [
"ArenaGame",
"append_game_history"
]

Binary file not shown.

View File

@@ -1,8 +1,8 @@
import uuid
import random
from typing import List, Optional, Dict
from shortdeck_arena.simulation import Simulation
from shortdeck_arena.agent import Agent, HumanAgent
from shortdeck_arena.game_stage import BlindConfig
from shortdeck_arena import Simulation, Agent, HumanAgent, BlindConfig
class ArenaGame:
@@ -42,6 +42,51 @@ class ArenaGame:
self.sim.new_round()
return player_id
def get_valid_actions(self, player_id) -> List[str]:
if not self.sim:
return []
try:
actions_info = self.sim.get_available_actions(player_id)
if isinstance(actions_info, dict) and actions_info.get("can_act", False):
valid_actions = []
if actions_info.get("can_fold", False):
valid_actions.append("fold")
if actions_info.get("can_check", False):
valid_actions.append("check")
if actions_info.get("can_call", False):
valid_actions.append("call")
if actions_info.get("can_bet", False):
valid_actions.append("bet")
if actions_info.get("can_raise", False):
valid_actions.append("raise")
return valid_actions
else:
return []
# 是否需要添加日志
except Exception as e:
print(f"Error getting valid actions: {e}")
valid_actions = ["fold"]
try:
if hasattr(self.sim, 'current_bet') and self.sim.current_bet > 0:
valid_actions.append("call")
else:
valid_actions.append("check")
if hasattr(self.sim, 'stacks') and player_id < len(self.sim.stacks):
if self.sim.stacks[player_id] > getattr(self.sim, 'current_bet', 0):
if getattr(self.sim, 'current_bet', 0) > 0:
valid_actions.append("raise")
else:
valid_actions.append("bet")
except Exception:
pass
return valid_actions
def apply_action(self, player_id, action, amount: Optional[int] = None) -> dict:
if not self.sim:
@@ -50,6 +95,16 @@ class ArenaGame:
try:
self.sim.apply_action(player_id, action, amount)
if (hasattr(self.sim, 'current_stage') and
getattr(self.sim.current_stage, 'value', '') == 'finished' and
hasattr(self.sim, 'hand_completed') and
self.sim.hand_completed):
import time
time.sleep(10)
print("游戏结束,自动开始新一轮...")
self.reset_hand_keep_chips()
self.sim.dump_data()
return {"success": True, "message": f"Applied {action}"}
@@ -59,41 +114,100 @@ class ArenaGame:
def info(self, player_id: Optional[int] = None) -> Dict:
if not self.sim:
return {"error": "游戏未初始化"}
return {
"game_id": self.game_id,
"players": self.player_names,
"dealer_index": 0,
"current_turn": 0,
"stage": "waiting",
"total_pot": 0,
"side_pots": [],
"player_cards": [],
"board_cards": [],
"stacks": [self.starting_stack] * len(self.agents),
"player_states": ["WAITING"] * len(self.agents),
"current_pot": [0] * len(self.agents),
"actions": {"can_act": False, "reason": "游戏未开始"}
}
info_data = {
"game_id": self.game_id,
"players": self.player_names,
"dealer_index": self.sim.dealer_position,
"current_turn": self.sim.current_turn,
"stage": self.sim.current_stage.value,
"total_pot": self.sim.total_pot,
"side_pots": [{"amount": pot.amount, "eligible_players": list(pot.eligible_players)}
for pot in self.sim.get_side_pots()],
"dealer_index": getattr(self.sim, 'dealer_position', 0),
"current_turn": getattr(self.sim, 'current_turn', 0),
"stage": getattr(self.sim.current_stage, 'value', 'pre_flop') if hasattr(self.sim, 'current_stage') else 'pre_flop',
"total_pot": getattr(self.sim, 'total_pot', 0),
"side_pots": [],
}
try:
side_pots = self.sim.get_side_pots()
info_data["side_pots"] = [{"amount": pot.amount, "eligible_players": list(pot.eligible_players)}
for pot in side_pots]
except Exception:
info_data["side_pots"] = []
if player_id is not None and 0 <= player_id < len(self.sim.stacks):
try:
player_cards = self.sim.player_cards(player_id)
info_data["player_cards"] = [str(card) for card in player_cards]
except Exception:
print(f"DEBUG - Player {player_id} cards: {info_data['player_cards']} (raw: {player_cards})")
except Exception as e:
print(f"DEBUG - Error getting player {player_id} cards: {e}")
info_data["player_cards"] = []
info_data["actions"] = self.sim.get_available_actions(player_id)
try:
actions_result = self.sim.get_available_actions(player_id)
info_data["actions"] = actions_result
except Exception as e:
info_data["actions"] = {"can_act": False, "reason": f"Error getting actions: {str(e)}"}
else:
info_data["player_cards"] = []
info_data["actions"] = {"can_act": False, "reason": "Invalid player"}
try:
board_cards = self.sim.board_cards(self.sim.current_stage.value)
stage_value = getattr(self.sim.current_stage, 'value', 'pre_flop') if hasattr(self.sim, 'current_stage') else 'pre_flop'
board_cards = self.sim.board_cards(stage_value)
info_data["board_cards"] = [str(card) for card in board_cards]
except Exception:
info_data["board_cards"] = []
info_data["stacks"] = self.sim.stacks.copy()
info_data["player_states"] = [state.value for state in self.sim.player_states]
info_data["current_pot"] = self.sim.pot.copy()
try:
info_data["stacks"] = self.sim.stacks.copy() if hasattr(self.sim, 'stacks') else []
except Exception:
info_data["stacks"] = []
try:
info_data["player_states"] = [state.value for state in self.sim.player_states] if hasattr(self.sim, 'player_states') else []
except Exception:
info_data["player_states"] = []
try:
info_data["current_pot"] = self.sim.pot.copy() if hasattr(self.sim, 'pot') else []
except Exception:
info_data["current_pot"] = []
if (hasattr(self.sim, 'current_stage') and
getattr(self.sim.current_stage, 'value', '') == 'finished' and
self.sim.is_hand_complete()):
result = self.sim.complete_hand()
if result.get("complete", False):
info_data["showdown_hands"] = result.get("showdown_hands", {})
info_data["winnings"] = result.get("winnings", {})
info_data["winners"] = result.get("winners", [])
if not hasattr(self, '_result_shown_count'):
self._result_shown_count = 0
self._result_shown_count += 1
if self._result_shown_count >= 3:
print(" 自动开始新一轮游戏...")
self.sim.new_round()
self._result_shown_count = 0
info_data["stage"] = "preflop"
## todo
return info_data
@@ -163,4 +277,26 @@ class ArenaGame:
@property
def history(self) -> List[Dict]:
return self.sim.history if self.sim else []
return self.sim.history if self.sim else []
def reset_hand_keep_chips(self):
if not self.sim or len(self.agents) < 2:
return
if hasattr(self.sim, 'hand_completed') and not self.sim.hand_completed:
if self.sim.is_hand_complete():
self.sim.complete_hand()
current_stacks = self.sim.stacks.copy()
self.sim = Simulation(self.agents, blind_config=self.blind_config)
self.sim.stacks = current_stacks
self.sim.new_round()
def full_reset(self):
self.agents = []
self.player_names = []
self.sim = None
self.game_id = str(uuid.uuid4())

View File

@@ -0,0 +1,68 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 404}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 404}, {"pid": 1, "action": "call", "amount": 403}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 404}, {"pid": 1, "action": "call", "amount": 403}, {"pid": 1, "action": "allin", "amount": 595}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 404}, {"pid": 1, "action": "call", "amount": 403}, {"pid": 1, "action": "allin", "amount": 595}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "allin", "amount": 1403}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "allin", "amount": 1403}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1404}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1404}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 492}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 492}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 492}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 247}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 247}, {"pid": 1, "action": "call", "amount": 246}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 247}, {"pid": 1, "action": "call", "amount": 246}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 247}, {"pid": 1, "action": "call", "amount": 246}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 247}, {"pid": 1, "action": "call", "amount": 246}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 78}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 78}, {"pid": 1, "action": "raise", "amount": 156}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 78}, {"pid": 1, "action": "raise", "amount": 156}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 663}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 663}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 554}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 554}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 509}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 509}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 509}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 509}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 644}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 644}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1254}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1254}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1257}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 1257}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 55}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 55}, {"pid": 1, "action": "call", "amount": 52}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 55}, {"pid": 1, "action": "call", "amount": 52}, {"pid": 1, "action": "bet", "amount": 107}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 55}, {"pid": 1, "action": "call", "amount": 52}, {"pid": 1, "action": "bet", "amount": 107}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}]}

View File

@@ -0,0 +1,36 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 205}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 205}, {"pid": 1, "action": "call", "amount": 204}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 205}, {"pid": 1, "action": "call", "amount": 204}, {"pid": 0, "action": "bet", "amount": 257}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 205}, {"pid": 1, "action": "call", "amount": 204}, {"pid": 0, "action": "bet", "amount": 257}, {"pid": 1, "action": "call", "amount": 257}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 205}, {"pid": 1, "action": "call", "amount": 204}, {"pid": 0, "action": "bet", "amount": 257}, {"pid": 1, "action": "call", "amount": 257}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 34}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 34}, {"pid": 1, "action": "call", "amount": 34}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 118}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 118}, {"pid": 1, "action": "call", "amount": 117}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 118}, {"pid": 1, "action": "call", "amount": 117}, {"pid": 1, "action": "bet", "amount": 235}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 118}, {"pid": 1, "action": "call", "amount": 117}, {"pid": 1, "action": "bet", "amount": 235}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 113}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 113}, {"pid": 1, "action": "call", "amount": 113}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 113}, {"pid": 1, "action": "call", "amount": 113}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 131}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 131}, {"pid": 1, "action": "call", "amount": 130}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 131}, {"pid": 1, "action": "call", "amount": 130}, {"pid": 0, "action": "bet", "amount": 132}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 131}, {"pid": 1, "action": "call", "amount": 130}, {"pid": 0, "action": "bet", "amount": 132}, {"pid": 1, "action": "call", "amount": 132}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 131}, {"pid": 1, "action": "call", "amount": 130}, {"pid": 0, "action": "bet", "amount": 132}, {"pid": 1, "action": "call", "amount": 132}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 131}, {"pid": 1, "action": "call", "amount": 130}, {"pid": 0, "action": "bet", "amount": 132}, {"pid": 1, "action": "call", "amount": 132}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 4}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 4}, {"pid": 1, "action": "raise", "amount": 603}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 4}, {"pid": 1, "action": "raise", "amount": 603}, {"pid": 1, "action": "bet", "amount": 603}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 4}, {"pid": 1, "action": "raise", "amount": 603}, {"pid": 1, "action": "bet", "amount": 603}, {"pid": 1, "action": "bet", "amount": 603}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 108}]}

View File

@@ -0,0 +1,7 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 3}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 3}, {"pid": 1, "action": "call", "amount": 2}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 3}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 1, "action": "bet", "amount": 5}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 3}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 1, "action": "bet", "amount": 5}, {"pid": 0, "action": "call", "amount": 5}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 3}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 1, "action": "bet", "amount": 5}, {"pid": 0, "action": "call", "amount": 5}, {"pid": 1, "action": "bet", "amount": 5}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 3}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 1, "action": "bet", "amount": 5}, {"pid": 0, "action": "call", "amount": 5}, {"pid": 1, "action": "bet", "amount": 5}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 3, "action": "small_blind", "amount": 1}, {"pid": 4, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,9 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 18}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 18}, {"pid": 0, "action": "call", "amount": 18}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 18}, {"pid": 0, "action": "call", "amount": 18}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 18}, {"pid": 0, "action": "call", "amount": 18}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 400}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 18}, {"pid": 0, "action": "call", "amount": 18}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 400}, {"pid": 1, "action": "call", "amount": 400}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 18}, {"pid": 0, "action": "call", "amount": 18}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 400}, {"pid": 1, "action": "call", "amount": 400}, {"pid": 0, "action": "bet", "amount": 420}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 18}, {"pid": 0, "action": "call", "amount": 18}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 400}, {"pid": 1, "action": "call", "amount": 400}, {"pid": 0, "action": "bet", "amount": 420}, {"pid": 1, "action": "raise", "amount": 580}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 18}, {"pid": 0, "action": "call", "amount": 18}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 400}, {"pid": 1, "action": "call", "amount": 400}, {"pid": 0, "action": "bet", "amount": 420}, {"pid": 1, "action": "raise", "amount": 580}, {"pid": 0, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,5 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 2, "action": "call", "amount": 1}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 2, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 4}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 2, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 4}, {"pid": 2, "action": "call", "amount": 4}]}

View File

@@ -0,0 +1,9 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}

View File

@@ -0,0 +1,20 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 299}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 299}, {"pid": 1, "action": "call", "amount": 298}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 299}, {"pid": 1, "action": "call", "amount": 298}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 299}, {"pid": 1, "action": "call", "amount": 298}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 320}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 299}, {"pid": 1, "action": "call", "amount": 298}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 320}, {"pid": 1, "action": "call", "amount": 320}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 299}, {"pid": 1, "action": "call", "amount": 298}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 320}, {"pid": 1, "action": "call", "amount": 320}, {"pid": 0, "action": "bet", "amount": 376}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,7 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 384}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 384}, {"pid": 1, "action": "call", "amount": 383}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 384}, {"pid": 1, "action": "call", "amount": 383}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 4}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 4}, {"pid": 1, "action": "call", "amount": 3}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 4}, {"pid": 1, "action": "call", "amount": 3}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 93}]}

View File

@@ -0,0 +1,4 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 310}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 310}, {"pid": 1, "action": "call", "amount": 309}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 310}, {"pid": 1, "action": "call", "amount": 309}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}

View File

@@ -0,0 +1,32 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 340}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 340}, {"pid": 1, "action": "allin", "amount": 999}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 340}, {"pid": 1, "action": "allin", "amount": 999}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 207}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 207}, {"pid": 1, "action": "call", "amount": 207}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 207}, {"pid": 1, "action": "call", "amount": 207}, {"pid": 0, "action": "bet", "amount": 217}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 207}, {"pid": 1, "action": "call", "amount": 207}, {"pid": 0, "action": "bet", "amount": 217}, {"pid": 1, "action": "call", "amount": 217}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 207}, {"pid": 1, "action": "call", "amount": 207}, {"pid": 0, "action": "bet", "amount": 217}, {"pid": 1, "action": "call", "amount": 217}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 6}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 6}, {"pid": 1, "action": "call", "amount": 6}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 22}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 22}, {"pid": 1, "action": "call", "amount": 22}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 22}, {"pid": 1, "action": "call", "amount": 22}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}

View File

@@ -0,0 +1,6 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 61}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 61}, {"pid": 1, "action": "call", "amount": 60}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 61}, {"pid": 1, "action": "call", "amount": 60}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 61}, {"pid": 1, "action": "call", "amount": 60}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 61}, {"pid": 1, "action": "call", "amount": 60}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "allin", "amount": 937}]}

View File

@@ -0,0 +1 @@
{"history": [{"pid": 0, "action": "bet", "amount": 682}]}

View File

@@ -0,0 +1,5 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 486}]}

View File

@@ -0,0 +1,6 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 203}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 203}, {"pid": 1, "action": "call", "amount": 203}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 203}, {"pid": 1, "action": "call", "amount": 203}, {"pid": 0, "action": "check", "amount": 0}]}

View File

@@ -0,0 +1,3 @@
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 3, "action": "bet", "amount": 486}]}

View File

@@ -0,0 +1,22 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 215}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 215}, {"pid": 1, "action": "call", "amount": 213}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 215}, {"pid": 1, "action": "call", "amount": 213}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 215}, {"pid": 1, "action": "call", "amount": 213}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 3}, {"pid": 0, "action": "raise", "amount": 215}, {"pid": 1, "action": "call", "amount": 213}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 40}]}

View File

@@ -0,0 +1,6 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 393}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 393}, {"pid": 1, "action": "call", "amount": 393}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 393}, {"pid": 1, "action": "call", "amount": 393}, {"pid": 0, "action": "bet", "amount": 395}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 393}, {"pid": 1, "action": "call", "amount": 393}, {"pid": 0, "action": "bet", "amount": 395}, {"pid": 1, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,3 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}]}

View File

@@ -0,0 +1,5 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "bet", "amount": 269}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "bet", "amount": 474}]}

View File

@@ -0,0 +1,3 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,48 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 382}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 382}, {"pid": 1, "action": "call", "amount": 381}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 382}, {"pid": 1, "action": "call", "amount": 381}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 382}, {"pid": 1, "action": "call", "amount": 381}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 382}, {"pid": 1, "action": "call", "amount": 381}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 3}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 95}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 95}, {"pid": 1, "action": "call", "amount": 92}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 95}, {"pid": 1, "action": "call", "amount": 92}, {"pid": 0, "action": "bet", "amount": 224}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 95}, {"pid": 1, "action": "call", "amount": 92}, {"pid": 0, "action": "bet", "amount": 224}, {"pid": 1, "action": "call", "amount": 224}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 95}, {"pid": 1, "action": "call", "amount": 92}, {"pid": 0, "action": "bet", "amount": 224}, {"pid": 1, "action": "call", "amount": 224}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 3}, {"pid": 0, "action": "raise", "amount": 95}, {"pid": 1, "action": "call", "amount": 92}, {"pid": 0, "action": "bet", "amount": 224}, {"pid": 1, "action": "call", "amount": 224}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 13}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 13}, {"pid": 1, "action": "call", "amount": 12}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 13}, {"pid": 1, "action": "call", "amount": 12}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 25}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 25}, {"pid": 0, "action": "call", "amount": 25}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 25}, {"pid": 0, "action": "call", "amount": 25}, {"pid": 1, "action": "bet", "amount": 25}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 25}, {"pid": 0, "action": "call", "amount": 25}, {"pid": 1, "action": "bet", "amount": 25}, {"pid": 0, "action": "raise", "amount": 118}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 25}, {"pid": 0, "action": "call", "amount": 25}, {"pid": 1, "action": "bet", "amount": 25}, {"pid": 0, "action": "raise", "amount": 118}, {"pid": 1, "action": "call", "amount": 93}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "bet", "amount": 25}, {"pid": 0, "action": "call", "amount": 25}, {"pid": 1, "action": "bet", "amount": 25}, {"pid": 0, "action": "raise", "amount": 118}, {"pid": 1, "action": "call", "amount": 93}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 15}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 15}, {"pid": 1, "action": "call", "amount": 14}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 15}, {"pid": 1, "action": "call", "amount": 14}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 33}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 33}, {"pid": 1, "action": "call", "amount": 32}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 33}, {"pid": 1, "action": "call", "amount": 32}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 22}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 22}, {"pid": 1, "action": "call", "amount": 21}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 22}, {"pid": 1, "action": "call", "amount": 21}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 22}, {"pid": 1, "action": "call", "amount": 21}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}]}
{"history": [{"pid": 3, "action": "small_blind", "amount": 1}, {"pid": 4, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}]}

View File

@@ -0,0 +1,4 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 296}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 296}, {"pid": 1, "action": "call", "amount": 295}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 296}, {"pid": 1, "action": "call", "amount": 295}, {"pid": 1, "action": "allin", "amount": 703}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 296}, {"pid": 1, "action": "call", "amount": 295}, {"pid": 1, "action": "allin", "amount": 703}, {"pid": 0, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,7 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "allin", "amount": 1001}]}

View File

@@ -0,0 +1,21 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 360}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 360}, {"pid": 1, "action": "call", "amount": 360}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 360}, {"pid": 1, "action": "call", "amount": 360}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 360}, {"pid": 1, "action": "call", "amount": 360}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 360}, {"pid": 1, "action": "call", "amount": 360}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 157}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 157}, {"pid": 1, "action": "call", "amount": 157}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 157}, {"pid": 1, "action": "call", "amount": 157}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 157}, {"pid": 1, "action": "call", "amount": 157}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 157}, {"pid": 1, "action": "call", "amount": 157}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}

View File

@@ -0,0 +1 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 75}]}

View File

@@ -0,0 +1,2 @@
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 2, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,12 @@
{"history": [{"pid": 0, "action": "bet", "amount": 477}]}
{"history": [{"pid": 0, "action": "bet", "amount": 477}]}
{"history": [{"pid": 0, "action": "bet", "amount": 477}]}
{"history": [{"pid": 0, "action": "bet", "amount": 477}]}
{"history": [{"pid": 0, "action": "bet", "amount": 477}]}
{"history": [{"pid": 0, "action": "bet", "amount": 477}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 2, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 2, "action": "check", "amount": 0}, {"pid": 2, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 2, "action": "check", "amount": 0}, {"pid": 2, "action": "check", "amount": 0}, {"pid": 2, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,3 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 276}]}

View File

@@ -0,0 +1,2 @@
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "raise", "amount": 4}]}

View File

@@ -0,0 +1,40 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 108}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 108}, {"pid": 1, "action": "call", "amount": 107}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 108}, {"pid": 1, "action": "call", "amount": 107}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 108}, {"pid": 1, "action": "call", "amount": 107}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 108}, {"pid": 1, "action": "call", "amount": 107}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 62}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 62}, {"pid": 1, "action": "call", "amount": 62}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 62}, {"pid": 1, "action": "call", "amount": 62}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 62}, {"pid": 1, "action": "call", "amount": 62}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 124}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 62}, {"pid": 1, "action": "call", "amount": 62}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 124}, {"pid": 0, "action": "raise", "amount": 341}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 62}, {"pid": 1, "action": "call", "amount": 62}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 124}, {"pid": 0, "action": "raise", "amount": 341}, {"pid": 1, "action": "call", "amount": 217}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "bet", "amount": 62}, {"pid": 1, "action": "call", "amount": 62}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "bet", "amount": 124}, {"pid": 0, "action": "raise", "amount": 341}, {"pid": 1, "action": "call", "amount": 217}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 101}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 101}, {"pid": 1, "action": "call", "amount": 100}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 101}, {"pid": 1, "action": "call", "amount": 100}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 101}, {"pid": 1, "action": "call", "amount": 100}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 157}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 101}, {"pid": 1, "action": "call", "amount": 100}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 157}, {"pid": 1, "action": "call", "amount": 157}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 101}, {"pid": 1, "action": "call", "amount": 100}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 157}, {"pid": 1, "action": "call", "amount": 157}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 46}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 46}, {"pid": 1, "action": "call", "amount": 45}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 46}, {"pid": 1, "action": "call", "amount": 45}, {"pid": 0, "action": "bet", "amount": 65}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 46}, {"pid": 1, "action": "call", "amount": 45}, {"pid": 0, "action": "bet", "amount": 65}, {"pid": 1, "action": "call", "amount": 65}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 46}, {"pid": 1, "action": "call", "amount": 45}, {"pid": 0, "action": "bet", "amount": 65}, {"pid": 1, "action": "call", "amount": 65}, {"pid": 0, "action": "bet", "amount": 112}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 46}, {"pid": 1, "action": "call", "amount": 45}, {"pid": 0, "action": "bet", "amount": 65}, {"pid": 1, "action": "call", "amount": 65}, {"pid": 0, "action": "bet", "amount": 112}, {"pid": 1, "action": "call", "amount": 112}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 46}, {"pid": 1, "action": "call", "amount": 45}, {"pid": 0, "action": "bet", "amount": 65}, {"pid": 1, "action": "call", "amount": 65}, {"pid": 0, "action": "bet", "amount": 112}, {"pid": 1, "action": "call", "amount": 112}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 0}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 0}, {"pid": 1, "action": "bet", "amount": 224}, {"pid": 0, "action": "fold", "amount": 0}]}

View File

@@ -0,0 +1,2 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 2, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}]}

View File

@@ -0,0 +1,17 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 142}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 142}, {"pid": 1, "action": "call", "amount": 142}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 142}, {"pid": 1, "action": "call", "amount": 142}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 142}, {"pid": 1, "action": "call", "amount": 142}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 2}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 2}, {"pid": 1, "action": "call", "amount": 2}, {"pid": 0, "action": "bet", "amount": 325}]}
{"history": [{"pid": 3, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}]}

View File

@@ -0,0 +1,2 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "allin", "amount": 998}]}

View File

@@ -0,0 +1,5 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}]}
{"history": [{"pid": 1, "action": "small_blind", "amount": 1}, {"pid": 0, "action": "big_blind", "amount": 2}, {"pid": 1, "action": "call", "amount": 1}, {"pid": 0, "action": "fold", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}]}

View File

@@ -0,0 +1 @@
{"history": [{"pid": 0, "action": "bet", "amount": 123}]}

View File

@@ -0,0 +1,7 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 66}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 66}, {"pid": 1, "action": "call", "amount": 65}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 66}, {"pid": 1, "action": "call", "amount": 65}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 66}, {"pid": 1, "action": "call", "amount": 65}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "raise", "amount": 66}, {"pid": 1, "action": "call", "amount": 65}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 2}]}
{"history": [{"pid": 2, "action": "small_blind", "amount": 1}, {"pid": 3, "action": "big_blind", "amount": 2}, {"pid": 4, "action": "call", "amount": 2}]}

View File

@@ -0,0 +1,7 @@
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 332}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 332}, {"pid": 1, "action": "call", "amount": 332}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 332}, {"pid": 1, "action": "call", "amount": 332}, {"pid": 0, "action": "bet", "amount": 334}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 332}, {"pid": 1, "action": "call", "amount": 332}, {"pid": 0, "action": "bet", "amount": 334}, {"pid": 1, "action": "call", "amount": 334}]}
{"history": [{"pid": 0, "action": "small_blind", "amount": 1}, {"pid": 1, "action": "big_blind", "amount": 2}, {"pid": 0, "action": "call", "amount": 1}, {"pid": 1, "action": "check", "amount": 0}, {"pid": 0, "action": "bet", "amount": 332}, {"pid": 1, "action": "call", "amount": 332}, {"pid": 0, "action": "bet", "amount": 334}, {"pid": 1, "action": "call", "amount": 334}, {"pid": 0, "action": "fold", "amount": 0}]}

View File

@@ -1,12 +1,35 @@
import sys
import os
from pathlib import Path
project_root = Path(__file__).resolve().parent.parent
if str(project_root) not in sys.path:
sys.path.insert(0, str(project_root))
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
from typing import List, Optional, Dict, Any
from .persistence import append_game_history
from .arena_adapter import ArenaGame
from shortdeck_server.persistence import append_game_history
from shortdeck_server.arena_adapter import ArenaGame
app = FastAPI(title="ShortDeck Poker Server", version="1.0.0")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app = FastAPI(title="shortdeck-server")
GAME = ArenaGame()
client_path = project_root / "client"
if client_path.exists():
app.mount("/client", StaticFiles(directory=str(client_path)), name="client")
class JoinRequest(BaseModel):
name: str
@@ -19,16 +42,67 @@ class JoinResponse(BaseModel):
class ActionRequest(BaseModel):
player_id: int
action: str # "fold", "call", "raise", "check", "bet"
amount: int | None = None
amount: Optional[int] = None
class ApiResponse(BaseModel):
success: bool = True
message: Optional[str] = None
data: Optional[Dict[str, Any]] = None
error: Optional[str] = None
class GameInfo(BaseModel):
game_id: str
players: List[str]
dealer_index: int
current_turn: int
stage: str
total_pot: int
side_pots: List[Dict[str, Any]]
player_cards: List[str]
board_cards: List[str]
stacks: List[int]
player_states: List[str]
current_pot: List[int]
actions: Dict[str, Any]
class HandStrength(BaseModel):
hand_type: str
description: str
strength: float
cards: List[str]
class Game1v1Response(BaseModel):
success: bool
message: str
human_player_id: Optional[int] = None
ai_player_id: Optional[int] = None
game_id: Optional[str] = None
@app.post("/reset_game")
def reset_game():
global GAME
try:
GAME = ArenaGame()
return {"success": True, "message": "游戏已重置"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e
@app.post("/join", response_model=JoinResponse)
def join(req: JoinRequest):
try:
print(f"收到加入请求: {req.name}")
player_id = GAME.join_game(req.name)
print(f"玩家 {req.name} 成功加入ID: {player_id}")
return JoinResponse(player_id=player_id, name=req.name)
except ValueError as e:
print(f"加入游戏失败 - ValueError: {e}")
raise HTTPException(status_code=400, detail=str(e)) from e
return JoinResponse(player_id=player_id, name=req.name)
except Exception as e:
print(f"加入游戏失败 - Exception: {e}")
import traceback
traceback.print_exc()
raise HTTPException(status_code=500, detail=str(e)) from e
@app.get("/get_game_state")
@@ -40,11 +114,78 @@ def get_game_state(player_id):
return state
@app.post("/apply_action")
@app.post("/apply_action", response_model=Dict[str, Any])
def apply_action(req: ActionRequest):
try:
GAME.apply_action(req.player_id, req.action, req.amount)
result = GAME.apply_action(req.player_id, req.action, req.amount)
append_game_history(GAME.game_id, {"history": GAME.history})
return result
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e)) from e
return {"ok": True}
@app.get("/valid_actions/{player_id}")
def get_valid_actions(player_id: int):
try:
actions = GAME.get_valid_actions(player_id)
return {"valid_actions": actions}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e
@app.get("/hand_strength/{player_id}")
def get_hand_strength(player_id: int):
try:
strength = GAME.get_hand_strength(player_id)
return strength
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e
@app.get("/winners")
def get_winners():
try:
winners = GAME.get_winners()
return winners
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e
@app.post("/reset")
def reset_game(request: dict = None):
try:
global GAME
keep_chips = False
if request and isinstance(request, dict):
keep_chips = request.get("keep_chips", False)
if keep_chips and GAME and len(GAME.agents) >= 2:
GAME.reset_hand_keep_chips()
message = "游戏重置,筹码保持"
else:
GAME = ArenaGame()
message = "游戏完全重置"
return {"ok": True, "message": message}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e
@app.get("/hand_complete")
def check_hand_complete():
try:
is_complete = GAME.check_hand_complete()
return {"hand_complete": is_complete}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e
if __name__ == "__main__":
import uvicorn
print(" Starting ShortDeck Poker Server...")
print(" Server will run on http://localhost:8001")
print(" API docs available at http://localhost:8001/docs")
uvicorn.run(
app,
host="127.0.0.1",
port=8001,
reload=False
)

View File

@@ -7,6 +7,7 @@ from typing import Any, Dict, Optional
import requests
## 注掉
BASE_PATH = "/get_game_state"
APPLY_PATH = "/apply_action"

View File

@@ -1,33 +0,0 @@
from __future__ import annotations
from shortdeck_server.arena_adapter import ArenaGame
def test_join_and_actions():
g = ArenaGame(starting_stack=100, max_players=3, small_blind=1, big_blind=2)
pid0 = g.join_game("aa")
pid1 = g.join_game("bb")
assert pid0 == 0
assert pid1 == 1
state = g.info()
# 在短牌扑克中,玩家加入后盲注已自动扣除
# 小盲(pid0): 100-1=99, 大盲(pid1): 100-2=98
assert state["stacks"] == [99, 98]
# 验证轮次管理heads-up时小盲先行动
assert g.current_turn == 0
# 测试错误的玩家尝试行动
result = g.apply_action(1, "fold")
assert result["success"] == False
assert "不是玩家" in result["message"] or "turn" in result["message"].lower()
# 小盲玩家call (跟注到大盲)
g.apply_action(0, "call")
assert g.current_turn == 1
# 大盲玩家加注
g.apply_action(1, "bet", 10)
assert g.pot >= 10 # 底池至少包含加注金额
assert g.history[-1]["action"] == "bet"

75
waitress_server.py Normal file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python3
import sys
import os
from pathlib import Path
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))
if __name__ == "__main__":
print("🚀 使用Waitress启动原始FastAPI扑克服务器...")
print("📍 服务器地址: http://127.0.0.1:8005")
print("🎮 游戏界面: http://127.0.0.1:8005/client/index.html")
print("✅ 使用原始ArenaGame实现")
print("🪟 Windows优化版本")
try:
from shortdeck_server.main import app
from waitress import serve
def wsgi_app(environ, start_response):
import asyncio
import json
from urllib.parse import parse_qs
method = environ['REQUEST_METHOD']
path = environ['PATH_INFO']
query_string = environ.get('QUERY_STRING', '')
scope = {
'type': 'http',
'method': method,
'path': path,
'query_string': query_string.encode(),
'headers': [(k.lower().replace('_', '-').encode(), v.encode())
for k, v in environ.items() if k.startswith('HTTP_')],
}
response_data = {'status': 500, 'headers': [], 'body': b''}
async def receive():
content_length = int(environ.get('CONTENT_LENGTH', 0))
if content_length > 0:
body = environ['wsgi.input'].read(content_length)
return {'type': 'http.request', 'body': body}
return {'type': 'http.request', 'body': b''}
async def send(message):
if message['type'] == 'http.response.start':
response_data['status'] = message['status']
response_data['headers'] = message.get('headers', [])
elif message['type'] == 'http.response.body':
response_data['body'] += message.get('body', b'')
try:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(app(scope, receive, send))
loop.close()
except Exception as e:
response_data['status'] = 500
response_data['body'] = f"Server Error: {str(e)}".encode()
status = f"{response_data['status']} OK"
headers = [(h[0].decode(), h[1].decode()) for h in response_data['headers']]
start_response(status, headers)
return [response_data['body']]
serve(wsgi_app, host='127.0.0.1', port=8005, threads=4)
except KeyboardInterrupt:
print("\n 服务器停止")
except Exception as e:
print(f" 服务器错误: {e}")
import traceback
traceback.print_exc()