acpc_dealer 2.4.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/Brickfile +6 -0
  3. data/README.md +7 -6
  4. data/Rakefile +30 -14
  5. data/acpc_dealer.gemspec +2 -1
  6. data/bin/acpc_dealer +4 -0
  7. data/ext/hand_evaluator/extconf.rb +10 -0
  8. data/lib/acpc_dealer/version.rb +1 -1
  9. data/lib/hand_evaluator.bundle +0 -0
  10. data/spec/dealer_runner_spec.rb +76 -72
  11. metadata +19 -82
  12. data/vendor/project_acpc_server/LICENCE +0 -23
  13. data/vendor/project_acpc_server/Makefile +0 -35
  14. data/vendor/project_acpc_server/README +0 -113
  15. data/vendor/project_acpc_server/README.submission +0 -42
  16. data/vendor/project_acpc_server/acpc_play_match.pl +0 -101
  17. data/vendor/project_acpc_server/bm_run_matches.c +0 -238
  18. data/vendor/project_acpc_server/bm_server.c +0 -1604
  19. data/vendor/project_acpc_server/bm_server.config +0 -78
  20. data/vendor/project_acpc_server/bm_widget.c +0 -230
  21. data/vendor/project_acpc_server/dealer.c +0 -1293
  22. data/vendor/project_acpc_server/evalHandTables +0 -4269
  23. data/vendor/project_acpc_server/example_player.c +0 -204
  24. data/vendor/project_acpc_server/example_player.limit.2p.sh +0 -3
  25. data/vendor/project_acpc_server/example_player.limit.3p.sh +0 -3
  26. data/vendor/project_acpc_server/example_player.nolimit.2p.sh +0 -3
  27. data/vendor/project_acpc_server/example_player.nolimit.3p.sh +0 -3
  28. data/vendor/project_acpc_server/game.c +0 -1792
  29. data/vendor/project_acpc_server/game.h +0 -253
  30. data/vendor/project_acpc_server/holdem.limit.2p.reverse_blinds.game +0 -13
  31. data/vendor/project_acpc_server/holdem.limit.3p.game +0 -13
  32. data/vendor/project_acpc_server/holdem.nolimit.2p.reverse_blinds.game +0 -12
  33. data/vendor/project_acpc_server/holdem.nolimit.3p.game +0 -12
  34. data/vendor/project_acpc_server/kuhn.limit.3p.game +0 -14
  35. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player.sf1.sh +0 -3
  36. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player.sf2.sh +0 -3
  37. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player.sf3.sh +0 -3
  38. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/LICENCE +0 -23
  39. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/Makefile +0 -127
  40. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/README.md +0 -35
  41. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/CExceptionConfig.h +0 -12
  42. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/dealer_connection.c +0 -49
  43. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/dealer_connection.h +0 -22
  44. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/kuhn_3p_equilibrium_player.c +0 -483
  45. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/kuhn_3p_equilibrium_player.h +0 -108
  46. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/main.c +0 -84
  47. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/player_config.c +0 -253
  48. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/player_config.h +0 -21
  49. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/support/test_helper.c +0 -45
  50. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/support/test_helper.h +0 -27
  51. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/test_kuhn_3p_equilibrium_player.c +0 -698
  52. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/test_kuhn_3p_equilibrium_player_sub_family_1.c +0 -324
  53. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/test_kuhn_3p_equilibrium_player_sub_family_2.c +0 -262
  54. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/test_kuhn_3p_equilibrium_player_sub_family_3.c +0 -177
  55. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/docs/license.txt +0 -30
  56. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/docs/readme.txt +0 -242
  57. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/lib/CException.c +0 -43
  58. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/lib/CException.h +0 -86
  59. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/release/build.info +0 -2
  60. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/release/version.info +0 -2
  61. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/History.md +0 -27
  62. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/Makefile +0 -8
  63. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/Readme.md +0 -103
  64. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/package.json +0 -9
  65. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/src/commander.c +0 -250
  66. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/src/commander.h +0 -88
  67. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/test.c +0 -34
  68. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/colour_prompt.rb +0 -94
  69. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/colour_reporter.rb +0 -39
  70. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/generate_config.yml +0 -36
  71. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/generate_module.rb +0 -202
  72. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/generate_test_runner.rb +0 -316
  73. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/test_file_filter.rb +0 -23
  74. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/unity_test_summary.rb +0 -139
  75. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/docs/Unity Summary.txt +0 -216
  76. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/docs/license.txt +0 -31
  77. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/release/build.info +0 -2
  78. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/release/version.info +0 -2
  79. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/src/unity.c +0 -1146
  80. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/src/unity.h +0 -245
  81. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/src/unity_internals.h +0 -546
  82. data/vendor/project_acpc_server/net.c +0 -218
  83. data/vendor/project_acpc_server/net.h +0 -62
  84. data/vendor/project_acpc_server/play_match.pl +0 -99
  85. data/vendor/project_acpc_server/protocol.md +0 -239
  86. data/vendor/project_acpc_server/protocol.odt +0 -0
  87. data/vendor/project_acpc_server/protocol.pdf +0 -0
  88. data/vendor/project_acpc_server/rng.c +0 -139
  89. data/vendor/project_acpc_server/rng.h +0 -63
  90. data/vendor/project_acpc_server/validate_submission.pl +0 -546
@@ -1,218 +0,0 @@
1
- /*
2
- Copyright (C) 2011 by the Computer Poker Research Group, University of Alberta
3
- */
4
-
5
- #include <unistd.h>
6
- #include <netdb.h>
7
- #include <string.h>
8
- #include <sys/socket.h>
9
- #include <sys/time.h>
10
- #include <netinet/in.h>
11
- #include <netinet/tcp.h>
12
- #include "net.h"
13
-
14
-
15
- ReadBuf *createReadBuf( int fd )
16
- {
17
- ReadBuf *readBuf = (ReadBuf*)malloc( sizeof( ReadBuf ) );
18
- if( readBuf == 0 ) {
19
-
20
- return readBuf;
21
- }
22
-
23
- readBuf->fd = fd;
24
- readBuf->bufStart = 0;
25
- readBuf->bufEnd = 0;
26
-
27
- return readBuf;
28
- }
29
-
30
- void destroyReadBuf( ReadBuf *readBuf )
31
- {
32
- close( readBuf->fd );
33
- free( readBuf );
34
- }
35
-
36
- /* get a newline terminated line and place it as a string in 'line'
37
- terminates the string with a 0 character
38
- if timeoutMicros is non-negative, do not spend more than
39
- that number of microseconds waiting to read data
40
- return number of characters read (including newline, excluding 0)
41
- 0 on end of file, or -1 on error or timeout */
42
- ssize_t getLine( ReadBuf *readBuf,
43
- size_t maxLen,
44
- char *line,
45
- int64_t timeoutMicros )
46
- {
47
- int haveStartTime, c;
48
- ssize_t len;
49
- fd_set fds;
50
- struct timeval start, tv;
51
-
52
- /* reserve space for string terminator */
53
- --maxLen;
54
- if( maxLen < 0 ) {
55
- return -1;
56
- }
57
-
58
- /* read the line */
59
- haveStartTime = 0;
60
- len = 0;
61
- while( len < maxLen ) {
62
-
63
- if( readBuf->bufStart >= readBuf->bufEnd ) {
64
- /* buffer is empty */
65
-
66
- if( timeoutMicros >= 0 ) {
67
- /* figure out how much time is left for reading */
68
- uint64_t timeLeft;
69
-
70
- timeLeft = timeoutMicros;
71
- if( haveStartTime ) {
72
-
73
- gettimeofday( &tv, NULL );
74
- timeLeft -= (uint64_t)( tv.tv_sec - start.tv_sec ) * 1000000
75
- + ( tv.tv_usec - start.tv_usec );
76
- if( timeLeft < 0 ) {
77
-
78
- timeLeft = 0;
79
- }
80
- } else {
81
-
82
- haveStartTime = 1;
83
- gettimeofday( &start, NULL );
84
- }
85
- tv.tv_sec = timeLeft / 1000000;
86
- tv.tv_usec = timeLeft % 1000000;
87
-
88
- /* wait for file descriptor to be ready */
89
- FD_ZERO( &fds );
90
- FD_SET( readBuf->fd, &fds );
91
- if( select( readBuf->fd + 1, &fds, NULL, NULL, &tv ) < 1 ) {
92
- /* no input ready within time, or an actual error */
93
-
94
- return -1;
95
- }
96
- }
97
-
98
- /* try reading a buffer full of data */
99
- readBuf->bufStart = 0;
100
- readBuf->bufEnd = read( readBuf->fd, readBuf->buf, READBUF_LEN );
101
- if( readBuf->bufEnd == 0 ) {
102
- /* end of input */
103
-
104
- break;
105
- } else if( readBuf->bufEnd < 0 ) {
106
- /* error condition */
107
-
108
- readBuf->bufEnd = 0;
109
- return -1;
110
- }
111
- }
112
-
113
- /* keep adding to the string until we see a newline */
114
- c = readBuf->buf[ readBuf->bufStart ];
115
- ++readBuf->bufStart;
116
- line[ len ] = c;
117
- ++len;
118
- if( c == '\n' ) {
119
-
120
- break;
121
- }
122
- }
123
-
124
- /* terminate the string */
125
- line[ len ] = 0;
126
- return len;
127
- }
128
-
129
-
130
- int connectTo( char *hostname, uint16_t port )
131
- {
132
- int sock;
133
- struct hostent *hostent;
134
- struct sockaddr_in addr;
135
-
136
- hostent = gethostbyname( hostname );
137
- if( hostent == NULL ) {
138
-
139
- fprintf( stderr, "ERROR: could not look up address for %s\n", hostname );
140
- return -1;
141
- }
142
-
143
- if( ( sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
144
-
145
- fprintf( stderr, "ERROR: could not open socket\n" );
146
- return -1;
147
- }
148
-
149
- addr.sin_family = AF_INET;
150
- addr.sin_port = htons( port );
151
- memcpy( &addr.sin_addr, hostent->h_addr_list[ 0 ], hostent->h_length );
152
-
153
- if( connect( sock, (struct sockaddr *)&addr, sizeof( addr ) ) < 0 ) {
154
-
155
- fprintf( stderr, "ERROR: could not connect to %s:%"PRIu16"\n",
156
- hostname, port );
157
- return -1;
158
- }
159
-
160
- return sock;
161
- }
162
-
163
- int getListenSocket( uint16_t *desiredPort )
164
- {
165
- int sock, t;
166
- struct sockaddr_in addr;
167
-
168
- if( ( sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
169
-
170
- return -1;
171
- }
172
-
173
- /* allow fast socket reuse - ignore failure */
174
- t = 1;
175
- setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &t, sizeof( int ) );
176
-
177
- /* bind the socket to the port */
178
- if( *desiredPort != 0 ) {
179
-
180
- addr.sin_family = AF_INET;
181
- addr.sin_port = htons( *desiredPort );
182
- addr.sin_addr.s_addr = htonl( INADDR_ANY );
183
- if( bind( sock, (struct sockaddr *)&addr, sizeof( addr ) ) < 0 ) {
184
-
185
- return -1;
186
- }
187
- } else {
188
-
189
- t = 0;
190
- while( 1 ) {
191
- addr.sin_family = AF_INET;
192
- *desiredPort = ( random() % 64512 ) + 1024;
193
- addr.sin_port = htons( *desiredPort );
194
- addr.sin_addr.s_addr = htonl( INADDR_ANY );
195
- if( bind( sock, (struct sockaddr *)&addr, sizeof( addr ) ) < 0 ) {
196
-
197
- if( t < NUM_PORT_CREATION_ATTEMPTS ) {
198
-
199
- ++t;
200
- continue;
201
- } else {
202
-
203
- return -1;
204
- }
205
- }
206
-
207
- break;
208
- }
209
- }
210
-
211
- /* listen on the socket */
212
- if( listen( sock, 8 ) < 0 ) {
213
-
214
- return -1;
215
- }
216
-
217
- return sock;
218
- }
@@ -1,62 +0,0 @@
1
- /*
2
- Copyright (C) 2011 by the Computer Poker Research Group, University of Alberta
3
- */
4
-
5
- #ifndef _NET_H
6
- #define _NET_H
7
-
8
- #include <stdlib.h>
9
- #include <stdio.h>
10
- #include <sys/types.h>
11
- #define __STDC_FORMAT_MACROS
12
- #include <inttypes.h>
13
-
14
-
15
- #define READBUF_LEN 4096
16
- #define NUM_PORT_CREATION_ATTEMPTS 10
17
-
18
-
19
- /* buffered I/O on file descriptors
20
-
21
- Yes... this is basically re-implementing bits of a standard FILE.
22
- Unfortunately, trying to mix timeouts and FILE streams either
23
- a) doesn't work, or b) is fairly system specific */
24
- typedef struct {
25
- int fd;
26
- int bufStart;
27
- int bufEnd;
28
- char buf[ READBUF_LEN ];
29
- } ReadBuf;
30
-
31
-
32
- /* open a socket to hostname/port
33
- returns file descriptor on success, <0 on failure */
34
- int connectTo( char *hostname, uint16_t port );
35
-
36
- /* try opening a socket suitable for connecting to
37
- if *desiredPort>0, uses specified port, otherwise use a random port
38
- returns actual port in *desiredPort
39
- returns file descriptor for socket, or -1 on failure */
40
- int getListenSocket( uint16_t *desiredPort );
41
-
42
-
43
- /* create a read buffer structure
44
- returns 0 on failure */
45
- ReadBuf *createReadBuf( int fd );
46
-
47
- /* destroy a read buffer - like fdopen, it will close the file descriptor */
48
- void destroyReadBuf( ReadBuf *readBuf );
49
-
50
- /* get a newline terminated line and place it as a string in 'line'
51
- terminates the string with a 0 character
52
- if timeoutMicros is non-negative, do not spend more than
53
- that number of microseconds waiting to read data
54
- return number of characters read (including newline, excluding 0)
55
- 0 on end of file, or -1 on error or timeout */
56
- ssize_t getLine( ReadBuf *readBuf,
57
- size_t maxLen,
58
- char *line,
59
- int64_t timeoutMicros );
60
-
61
-
62
- #endif
@@ -1,99 +0,0 @@
1
- #!/usr/bin/perl
2
-
3
- # Copyright (C) 2011 by the Computer Poker Research Group, University of Alberta
4
-
5
- use Socket;
6
-
7
- $hostname = `hostname` or die "could not get hostname";
8
- chomp $hostname;
9
- @hostent = gethostbyname( $hostname );
10
- $#hostent >= 4 or die "could not look up $hostname";
11
- $hostip = inet_ntoa( $hostent[ 4 ] );
12
-
13
- $#ARGV >= 3 or die "usage: play_match.pl matchName gameDefFile #Hands rngSeed player1name player1exe player2name player2exe ... [options]";
14
-
15
- $numPlayers = -1;
16
- open FILE, '<', $ARGV[ 1 ] or die "couldn't open game definition $ARGV[ 1 ]";
17
- while( $_ = <FILE> ) {
18
-
19
- @_ = split;
20
-
21
- if( uc( $_[ 0 ] ) eq 'NUMPLAYERS' ) {
22
- $numPlayers = $_[ $#_ ];
23
- }
24
- }
25
- close FILE;
26
-
27
- $numPlayers > 1 or die "couldn't get number of players from $ARGV[ 1 ]";
28
-
29
-
30
- $#ARGV >= 3 + $numPlayers * 2 or die "too few players on command line";
31
-
32
- pipe STDINREADPIPE, STDINWRITEPIPE or die "couldn't create stdin pipe";
33
- pipe STDOUTREADPIPE, STDOUTWRITEPIPE or die "couldn't create stdout pipe";
34
-
35
- $dealerPID = fork();
36
- if( $dealerPID == 0 ) {
37
- # we're the child
38
-
39
- # replace standard in and standard out with pipe
40
- close STDINWRITEPIPE;
41
- close STDOUTREADPIPE;
42
- open STDIN, '<&STDINREADPIPE' or die "can't dup STDIN";
43
- open STDOUT, '>&STDOUTWRITEPIPE' or die "can't dup STDOUT";
44
- open STDERR, ">>$ARGV[ 0 ].err" or die "can't open log file $ARGV[ 0 ].err";
45
-
46
- @args = ( "dealer", $ARGV[ 0 ], $ARGV[ 1 ],
47
- $ARGV[ 2 ], $ARGV[ 3 ] );
48
-
49
- # add names to the arguments
50
- for( $p = 0; $p < $numPlayers; ++$p ) {
51
- push @args, $ARGV[ 4 + $p * 2 ];
52
- }
53
-
54
- # add any extra arguments (options?) to the arguments
55
- for( $i = 4 + $numPlayers * 2; $i <= $#ARGV; ++$i ) {
56
- push @args, $ARGV[ $i ];
57
- }
58
- exec { "./dealer" } @args or die "Couldn't run dealer";
59
- }
60
-
61
- close STDINREADPIPE;
62
- close STDOUTWRITEPIPE;
63
-
64
- $_ = <STDOUTREADPIPE> or die "couldn't read port description from dealer";
65
- @_ = split;
66
- $#_ + 1 >= $numPlayers or die "couldn't get enough ports from $_";
67
-
68
- for( $p = 0; $p < $numPlayers; ++$p ) {
69
-
70
- $playerPID[ $p ] = fork();
71
-
72
- if( $playerPID[ $p ] == 0 ) {
73
- # we're the child
74
-
75
- # log standard out and standard error
76
- open STDOUT, ">$ARGV[ 0 ].player$p.std"
77
- or die "can't dup player $p STDOUT";
78
- open STDERR, ">$ARGV[ 0 ].player$p.err"
79
- or die "can't dup player $p STDERR";
80
-
81
- exec { $ARGV[ 4 + $p * 2 + 1 ] } ( $ARGV[ 4 + $p * 2 + 1 ],
82
- $hostip, $_[ $p ] )
83
- or die "couldn't run $ARGV[ 4 + $p * 2 + 1 ] for player $p";
84
- }
85
- }
86
-
87
- $_ = <STDOUTREADPIPE>;
88
-
89
- for( $p = 0; $p < $numPlayers; ++$p ) {
90
- waitpid( $playerPID[ $p ], 0 );
91
- }
92
-
93
- waitpid( $dealerPID, 0 );
94
-
95
- $_ or die "couldn't get values from dealer";
96
-
97
- print $_;
98
-
99
- exit( 0 );
@@ -1,239 +0,0 @@
1
- ACPC Protocol Specification, version 2.0.0, October 2010
2
- =======================================
3
-
4
- This document describes the format of messages between the ACPC `dealer` program and a player. Communication is over *TCP*, where players connect to `dealer` with a port number that `dealer` will print to `STDOUT` upon starting. All messages are terminated by a
5
- carriage return and a new line (`\r\n` or *ASCII* characters 13 and 10, respectively).
6
- <!-- @todo Does the dealer still ever send comments or GUI commands?/do we still want users to be aware of this? Why would we waste the bandwidth to send players comments? -->
7
- Any message from the server which starts with '#' or ';' is a comment or GUI command, and may be safely ignored.
8
- The first message from a player must be a version string
9
-
10
- VERSION:2.0.0\r\n
11
-
12
- After this, the server will repeatedly send *match state* strings to players describing their view of the match after every event,including an initial state, states where the player is not acting, and the final state when the game is over.
13
-
14
- Match States
15
- --------------
16
- <!-- @todo -->
17
-
18
- ACPC Representation of Actions
19
- ---------------------------------
20
-
21
- Action ACPC Representation
22
- ------ -------------------
23
- check or call `c`
24
- fold `f`
25
- bet or raise (limit) `r`
26
- bet or raise **to** 100 (no-limit) `r100`
27
-
28
- Sending Actions
29
- -----------------
30
- If the player is acting, it must respond by returning a message with the same state, with their action, in ACPC format, appended. For example, had the player received the match state <!-- @todo -->
31
-
32
-
33
- <serverMessage> := <matchState> '\r\n'
34
- <matchState> := 'MATCHSTATE:' <position> <handNumber> <betting> <cards>
35
- <position> := <unsigned integer> ':'
36
- <handNumber>:= <unsigned integer> ':'
37
- <betting> := { <limitBetting> } { <nolimitBetting> } ':'
38
- <limitBetting> := ( <round1LimitBetting>
39
- { | <round1LimitBetting> '/' <round2LimitBetting> … } )
40
- <roundXLimitBetting> = <limitAction>*
41
- <limitAction> := <fold> | <call> | <limitRaise>
42
- <fold> := 'f'
43
- <call> := 'c'
44
- <limitRaise> := 'r'
45
- <nolimitBetting> := ( <round1NolimitBetting>
46
- { | <round1NolimitBetting> '/' <round2NolimitBetting> … } )
47
- <roundXNolimitBetting> := <noLimitAction>*
48
- <noLimitAction> := <fold> | <call> | <nolimitRaise>
49
- <nolmitRaise> := 'r' <nolimitRaiseSize>
50
- <nolimitRaiseSize> := <unsigned integer>
51
- <cards> := <holeCards> <boardCards>
52
- <holeCards> := <player1Cards> '|' <player2Cards> { '|' <player3Cards> … }
53
- <boardCards> := <round1BoardCards> { '/' <round2BoardCards> … }
54
- <playerXCards> := '' | <card> { <card> … }
55
- <roundXBoardCards> := { <card> … }
56
- <card> := <rank> <suit>
57
- <rank> := '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'T' | 'J' | 'Q' | 'K' | 'A'
58
- <suit> := 's' | 'h' | 'd' | 'c'
59
- <clientResponse> := <matchState> ':' { <limitAction> } { <noLimitAction> } '\r\n'
60
- Parts of the specification in brackets indicate game specific definitions. For example, in Texas
61
- Hold'em, there are four rounds with zero, three, one, and one board cards on the rounds respectively, so
62
- the actual definition would be
63
- <round1BoardCards> := ''
64
- <round2BoardCards> := <card> <card> <card>
65
- <round3BoardCards> := <card>
66
- <round4BoardCards> := <card>
67
- The <position> field tells the client their position relative to the dealer button. A value of 0 indicates
68
- that for the current hand, the client is the first player after the button (the small blind in ring games, or
69
- the big blind in reverse-blind heads-up games.)
70
- The <handNumber> is simply an identifier for the current hand. Clients should make no assumption
71
- about these values, other than that it will be unique across hands within a match, and that it will not
72
- change within a single hand.
73
- <betting> is a list of actions taken by all players. There is no distinction made between calling and
74
- checking, or betting and raising. In no-limit betting strings, the raise action includes a size, which
75
- indicates the total number of chips the player will have put into the pot after raising (ie the value they
76
- are raising to, not the value they are raising by.) Valid betting strings will be described in a later
77
- section.
78
- <cards> is the complete set of cards visible to the player, given their <position>. <holecards>
79
- describes the view of the private cards, and the number of <playerCards> sections is determined by the
80
- game being player. For example, heads-up games will have two sections, 3 player ring games will have
81
- 3 sections, and so on. Each <playerCard> section will either be an empty string, indicating that the
82
- player does not know what those cards are, or a number of <card> strings determined by the game. A
83
- <card> is simply two characters, one for the rank and one for the suit. The <boardCards> description
84
- will also have a number of sections, one for each round, up to the current round as indicated by the
85
- <betting>. The number of <cards> in each section is fixed, and determined by the game. Note that if it
86
- ever becomes desirable to play a game with board cards in the first round, the protocol should probably
87
- be changed again to add a separator between the hole cards and board cards.
88
- A valid <betting> string consists of a sequence of valid actions for successive acting players. Calling is
89
- always valid. Folding is only valid if the acting player would need to add money to the pot to call. To
90
- describe raises, it is worth making a distinction between raising by and raising to. Unless this
91
- document specifically mention otherwise, when it speaks of a raise size, it is talking about a raise to a
92
- value, using the term to mean the total number of chips the player will have put into the pot, including
93
- chips added in previous rounds. In contrast, raising by a value is adding that number of chips to the pot
94
- after calling the current bet.
95
- A raise is valid if a) it raises by at least one chip, b) the player has sufficient money in their stack to
96
- raise to the value, and c) the raise would put the player all-in (they have spent all their chips) or the
97
- amount they are raising by is at least as large as the big blind and the raise-by amount for any other
98
- raise in the round. This description properly handles some odd cases where some players may be all-
99
- in. Informally, at the beginning of a round a player may bet as low as the big blind, and each
100
- subsequent raise must increase the bet by at least as much as the last raise. In limit betting games, there
101
- may also be a limit on the number of raises in a round, and any raise action over this limit is not valid.
102
- An active player is one that has not folded, and is not all-in. Label the players from 0 to N-1, where N
103
- is the number of players in the game. After an action by player p, the next acting player is p' for the
104
- minimum d>0 such that p' is active and p' =(p+d) modulo N. That is, the next player around the table
105
- who has at least two valid actions. The first player in a round is specified by the game.
106
- A betting round ends when all active players remaining have either called, or were the player which
107
- initiated the current bet. The game is over if the all betting rounds have finished, or if there are not at
108
- least two active players left in the game. If all players but one have folded, the remaining player wins
109
- the entire pot, and does not show other players their cards. Otherwise, the game has ended in a
110
- showdown and all non-folding players show everyone their cards.
111
- Values in a showdown are determined by the rank of a players best hand, constructed from their hole
112
- cards and the public board cards. Folding players have a lower rank than any non-folding player.
113
- Every pot of money is split evenly between all participating players with the highest rank. There is a
114
- separate pot for every distinct amount j of money spent by a player (whether they fold or not), and a
115
- player is participating in the pot if they spent at least that much money (again, whether they fold or
116
- not.) The size of the pot is equal to the number of participating players multiplied by (j - the size of the
117
- next smallest amount spent by a player).
118
- Changes from Version 1
119
- There a number of changes from the first version of the protocol. Ring games are now documented.
120
- No-limit games no longer give a value for a call, and there are no blinds in the string. The question of
121
- whether all-in players got to act was previously left unspecified, and different implementations had
122
- different behaviour. Folding is no longer allowed if the player could have called for free. Finally, this
123
- updated description also covers the protocol for no-limit ring games, in the event that this game is
124
- added to the competition.
125
- It is also strongly suggested to the chair that on a failed responses from a client, whether the message
126
- was malformed, the action was invalid, or the player did not respond in time, the entire match should
127
- be ended. If the problem can not be fixed easily by a very short interaction with the team, the program
128
- should be disqualified. The previous choice of having the player call in some cases, or fold all
129
- remaining hands led to some situations where the results of the competition depended on the chair's
130
- decision on exactly how to handle incorrect behaviour. Teams with buggy programs also took up large
131
- amounts of the chair's time. As long as players are given sufficient time for testing, using the exact
132
- same code used for the competition, it is not unreasonable to expect players to be able to run without
133
- producing error messages or warnings.
134
- Examples
135
- The rest of this document is examples of messages to and from a client in various games. Messages
136
- from the server are prefaced with S->. Responses from the client are prefaced with <-C.
137
- Two player limit Texas Hold'em
138
- S-> MATCHSTATE:0:0::TdAs|
139
- S-> MATCHSTATE:0:0:r:TdAs|
140
- <-C MATCHSTATE:0:0:r:TdAs|:r
141
- S-> MATCHSTATE:0:0:rr:TdAs|
142
- S-> MATCHSTATE:0:0:rrc/:TdAs|/2c8c3h
143
- <-C MATCHSTATE:0:0:rrc/:TdAs|/2c8c3h:r
144
- S-> MATCHSTATE:0:0:rrc/r:TdAs|/2c8c3h
145
- S-> MATCHSTATE:0:0:rrc/rc/:TdAs|/2c8c3h/9c
146
- <-C MATCHSTATE:0:0:rrc/rc/:TdAs|/2c8c3h/9c:c
147
- S-> MATCHSTATE:0:0:rrc/rc/c:TdAs|/2c8c3h/9c
148
- S-> MATCHSTATE:0:0:rrc/rc/cr:TdAs|/2c8c3h/9c
149
- <-C MATCHSTATE:0:0:rrc/rc/cr:TdAs|/2c8c3h/9c:c
150
- S-> MATCHSTATE:0:0:rrc/rc/crc/:TdAs|/2c8c3h/9c/Kh
151
- <-C MATCHSTATE:0:0:rrc/rc/crc/:TdAs|/2c8c3h/9c/Kh:c
152
- S-> MATCHSTATE:0:0:rrc/rc/crc/c:TdAs|/2c8c3h/9c/Kh
153
- S-> MATCHSTATE:0:0:rrc/rc/crc/cr:TdAs|/2c8c3h/9c/Kh
154
- <-C MATCHSTATE:0:0:rrc/rc/crc/cr:TdAs|/2c8c3h/9c/Kh:c
155
- S-> MATCHSTATE:0:0:rrc/rc/crc/crc:TdAs|8hTc/2c8c3h/9c/Kh
156
- S-> MATCHSTATE:1:1::|Qd7c
157
- <-C MATCHSTATE:1:1::|Qd7c:r
158
- S-> MATCHSTATE:1:1:r:|Qd7c
159
- S-> MATCHSTATE:1:1:rr:|Qd7c
160
- <-C MATCHSTATE:1:1:rr:|Qd7c:c
161
- S-> MATCHSTATE:1:1:rrc/:|Qd7c/2h8h5c
162
- S-> MATCHSTATE:1:1:rrc/r:|Qd7c/2h8h5c
163
- <-C MATCHSTATE:1:1:rrc/r:|Qd7c/2h8h5c:c
164
- S-> MATCHSTATE:1:1:rrc/rc/:|Qd7c/2h8h5c/Th
165
- S-> MATCHSTATE:1:1:rrc/rc/r:|Qd7c/2h8h5c/Th
166
- <-C MATCHSTATE:1:1:rrc/rc/r:|Qd7c/2h8h5c/Th:f
167
- S-> MATCHSTATE:1:1:rrc/rc/rf:|Qd7c/2h8h5c/Th
168
- S-> MATCHSTATE:0:2::9d7s|
169
- S-> MATCHSTATE:0:2:r:9d7s|
170
- <-C MATCHSTATE:0:2:r:9d7s|:c
171
- S-> MATCHSTATE:0:2:rc/:9d7s|/5d2cJc
172
- <-C MATCHSTATE:0:2:rc/:9d7s|/5d2cJc:c
173
- S-> MATCHSTATE:0:2:rc/c:9d7s|/5d2cJc
174
- S-> MATCHSTATE:0:2:rc/cc/:9d7s|/5d2cJc/3d
175
- <-C MATCHSTATE:0:2:rc/cc/:9d7s|/5d2cJc/3d:c
176
- S-> MATCHSTATE:0:2:rc/cc/c:9d7s|/5d2cJc/3d
177
- S-> MATCHSTATE:0:2:rc/cc/cr:9d7s|/5d2cJc/3d
178
- <-C MATCHSTATE:0:2:rc/cc/cr:9d7s|/5d2cJc/3d:f
179
- S-> MATCHSTATE:0:2:rc/cc/crf:9d7s|/5d2cJc/3d
180
- Two player no-limit Texas Hold'em
181
- S-> MATCHSTATE:0:30::9s8h|
182
- S-> MATCHSTATE:0:30:c:9s8h|
183
- <-C MATCHSTATE:0:30:c:9s8h|:c
184
- S-> MATCHSTATE:0:30:cc/:9s8h|/8c8d5c
185
- <-C MATCHSTATE:0:30:cc/:9s8h|/8c8d5c:r250
186
- S-> MATCHSTATE:0:30:cc/r250:9s8h|/8c8d5c
187
- S-> MATCHSTATE:0:30:cc/r250c/:9s8h|/8c8d5c/6s
188
- <-C MATCHSTATE:0:30:cc/r250c/:9s8h|/8c8d5c/6s:r500
189
- S-> MATCHSTATE:0:30:cc/r250c/r500:9s8h|/8c8d5c/6s
190
- S-> MATCHSTATE:0:30:cc/r250c/r500c/:9s8h|/8c8d5c/6s/2d
191
- <-C MATCHSTATE:0:30:cc/r250c/r500c/:9s8h|/8c8d5c/6s/2d:r1250
192
- S-> MATCHSTATE:0:30:cc/r250c/r500c/r1250:9s8h|/8c8d5c/6s/2d
193
- S-> MATCHSTATE:0:30:cc/r250c/r500c/r1250c:9s8h|9c6h/8c8d5c/6s/2d
194
- S-> MATCHSTATE:1:31::|JdTc
195
- <-C MATCHSTATE:1:31::|JdTc:r300
196
- S-> MATCHSTATE:1:31:r300:|JdTc
197
- S-> MATCHSTATE:1:31:r300r900:|JdTc
198
- <-C MATCHSTATE:1:31:r300r900:|JdTc:c
199
- S-> MATCHSTATE:1:31:r300r900c/:|JdTc/6dJc9c
200
- S-> MATCHSTATE:1:31:r300r900c/r1800:|JdTc/6dJc9c
201
- <-C MATCHSTATE:1:31:r300r900c/r1800:|JdTc/6dJc9c:r3600
202
- S-> MATCHSTATE:1:31:r300r900c/r1800r3600:|JdTc/6dJc9c
203
- S-> MATCHSTATE:1:31:r300r900c/r1800r3600r9000:|JdTc/6dJc9c
204
- <-C MATCHSTATE:1:31:r300r900c/r1800r3600r9000:|JdTc/6dJc9c:c
205
- S-> MATCHSTATE:1:31:r300r900c/r1800r3600r9000c/:|JdTc/6dJc9c/Kh
206
- S-> MATCHSTATE:1:31:r300r900c/r1800r3600r9000c/r20000:|JdTc/6dJc9c/Kh
207
- <-C MATCHSTATE:1:31:r300r900c/r1800r3600r9000c/r20000:|JdTc/6dJc9c/Kh:c
208
- S-> MATCHSTATE:1:31:r300r900c/r1800r3600r9000c/r20000c/:KsJs|JdTc/6dJc9c/Kh/Qc
209
- Three player limit Texas Hold'em
210
- S-> MATCHSTATE:2:55::||AsTs
211
- <-C MATCHSTATE:2:55::||AsTs:r
212
- S-> MATCHSTATE:2:55:r:||AsTs
213
- S-> MATCHSTATE:2:55:rc:||AsTs
214
- S-> MATCHSTATE:2:55:rcc/:||AsTs/4cJh8h
215
- S-> MATCHSTATE:2:55:rcc/r:||AsTs/4cJh8h
216
- S-> MATCHSTATE:2:55:rcc/rf:||AsTs/4cJh8h
217
- <-C MATCHSTATE:2:55:rcc/rf:||AsTs/4cJh8h:c
218
- S-> MATCHSTATE:2:55:rcc/rfc/:||AsTs/4cJh8h/Kd
219
- S-> MATCHSTATE:2:55:rcc/rfc/r:||AsTs/4cJh8h/Kd
220
- <-C MATCHSTATE:2:55:rcc/rfc/r:||AsTs/4cJh8h/Kd:c
221
- S-> MATCHSTATE:2:55:rcc/rfc/rc/:||AsTs/4cJh8h/Kd/8c
222
- S-> MATCHSTATE:2:55:rcc/rfc/rc/r:||AsTs/4cJh8h/Kd/8c
223
- <-C MATCHSTATE:2:55:rcc/rfc/rc/r:||AsTs/4cJh8h/Kd/8c:f
224
- S-> MATCHSTATE:2:55:rcc/rfc/rc/rf:||AsTs/4cJh8h/Kd/8c
225
- S-> MATCHSTATE:0:90::Ad6h||
226
- S-> MATCHSTATE:0:90:c:Ad6h||
227
- <-C MATCHSTATE:0:90:c:Ad6h||:r
228
- S-> MATCHSTATE:0:90:cr:Ad6h||
229
- S-> MATCHSTATE:0:90:crf:Ad6h||
230
- S-> MATCHSTATE:0:90:crfc/:Ad6h||/TsKd7h
231
- <-C MATCHSTATE:0:90:crfc/:Ad6h||/TsKd7h:r
232
- S-> MATCHSTATE:0:90:crfc/r:Ad6h||/TsKd7h
233
- S-> MATCHSTATE:0:90:crfc/rc/:Ad6h||/TsKd7h/Kh
234
- <-C MATCHSTATE:0:90:crfc/rc/:Ad6h||/TsKd7h/Kh:r
235
- S-> MATCHSTATE:0:90:crfc/rc/r:Ad6h||/TsKd7h/Kh
236
- S-> MATCHSTATE:0:90:crfc/rc/rc/:Ad6h||/TsKd7h/Kh/6d
237
- <-C MATCHSTATE:0:90:crfc/rc/rc/:Ad6h||/TsKd7h/Kh/6d:r
238
- S-> MATCHSTATE:0:90:crfc/rc/rc/r:Ad6h||/TsKd7h/Kh/6d
239
- S-> MATCHSTATE:0:90:crfc/rc/rc/rc:Ad6h||Td2h/TsKd7h/Kh/6d