refactored handle_gtp_cmd(), added id for gtp command, added tests

AuthorKonata <konata@posteo.jp>
Date
Commitae9e88931159c8088e77ede4486f903035d527b1
Parent647a567
4 files changed, 152 insertions(+), 43 deletions(-)
Msimple-go.c
@@ -134,21 +134,21 @@ bool play_at(game_state* game, go_coordinate y, go_coordinate x)
134134 can_place = true;
135135 else if(left == EMPTY)
136136 can_place = true;
137- else if(up == friendly && group_attachable(game, y, x-1))
137+ else if(left == friendly && group_attachable(game, y, x-1))
138138 can_place = true;
139139
140140 if(down == enemy && group_killable(game, y+1, x))
141141 can_place = true;
142142 else if(down == EMPTY)
143143 can_place = true;
144- else if(up == friendly && group_attachable(game, y+1, x))
144+ else if(down == friendly && group_attachable(game, y+1, x))
145145 can_place = true;
146146
147147 if(right == enemy && group_killable(game, y, x+1))
148148 can_place = true;
149149 else if(right == EMPTY)
150150 can_place = true;
151- else if(up == friendly && group_attachable(game, y, x+1))
151+ else if(right == friendly && group_attachable(game, y, x+1))
152152 can_place = true;
153153
154154 if(!can_place)
Msimple-go.h
@@ -31,22 +31,22 @@ typedef struct game_state
3131 } game_state;
3232
3333
34-go_board* create_board(unsigned int size);
34+go_board* create_board(go_coordinate size);
3535 void delete_board(go_board* board);
36-game_state* create_game(unsigned int size, float komi);
36+game_state* create_game(go_coordinate size, float komi);
3737 void delete_game(game_state* game);
3838
39-bool check_bounds(const go_board* board, unsigned int y, unsigned int x);
40-char get_board_at(const go_board* board, unsigned int y, unsigned int x);
41-void set_board_at(go_board* board, unsigned int y, unsigned int x, char item);
39+bool check_bounds(const go_board* board, go_coordinate y, go_coordinate x);
40+char get_board_at(const go_board* board, go_coordinate y, go_coordinate x);
41+void set_board_at(go_board* board, go_coordinate y, go_coordinate x, char item);
4242
4343 void kill_group(go_board* board, go_board* overlay);
44-bool group_killable(game_state* game, unsigned int y, unsigned int x);
45-bool group_attachable(const game_state* game, unsigned int y, unsigned int x);
46-bool play_at(game_state* game, unsigned int y, unsigned int x);
44+bool group_killable(game_state* game, go_coordinate y, go_coordinate x);
45+bool group_attachable(const game_state* game, go_coordinate y, go_coordinate x);
46+bool play_at(game_state* game, go_coordinate y, go_coordinate x);
4747
4848 void print_board(go_board* board);
49-void find_group(const go_board* board, go_board* overlay, unsigned int y, unsigned int x);
49+void find_group(const go_board* board, go_board* overlay, go_coordinate y, go_coordinate x);
5050 unsigned long count_liberties(go_board* board, go_board* overlay);
5151
5252
Msimple-gtp.c
@@ -1,18 +1,39 @@
11 #include "simple-gtp.h"
22
3-char* cmd_error(const char* msg)
3+typedef struct msg_formatted
44 {
5- char* ret = malloc(strlen("? ") + strlen(msg) + 1);
6- strcpy(ret, "? ");
5+ char* command;
6+ Vector* arguments;
7+ char* id;
8+} msg_formatted;
9+
10+char* cmd_error(const char* msg, char* id)
11+{
12+ char* ret = malloc(strlen("? ") + strlen(msg) + (id ? strlen(id) : 0) + 3);
13+ strcpy(ret, "?");
14+ if(id)
15+ {
16+ strcat(ret, id);
17+ free(id);
18+ }
19+ strcat(ret, " ");
720 strcat(ret, msg);
21+ strcat(ret, "\n\n");
822 return ret;
923 }
1024
11-char* cmd_success(const char* msg)
25+char* cmd_success(const char* msg, char* id)
1226 {
13- char* ret = malloc(strlen("= ") + strlen(msg) + 2);
14- strcpy(ret, "= ");
27+ char* ret = malloc(strlen("= ") + strlen(msg) + (id ? strlen(id) : 0) + 3);
28+ strcpy(ret, "=");
29+ if(id)
30+ {
31+ strcat(ret, id);
32+ free(id);
33+ }
34+ strcat(ret, " ");
1535 strcat(ret, msg);
36+ strcat(ret, "\n\n");
1637 return ret;
1738 }
1839
@@ -20,21 +41,29 @@ const char* const known_commands_string = "protocol_version\nname\nversion\nknow
2041 const char* known_commands_array[] = {"protocol_version","name","version","known_command","list_commands","quit","boardsize","clear_board","komi","play","genmove","showboard"};
2142 int cmd_count = sizeof(known_commands_array)/sizeof(known_commands_array[0]);
2243
23-char* handle_gtp_cmd(const char* msg, game_state* game)
44+static msg_formatted format_msg(const char* msg)
2445 {
25- if(!msg || !strlen(msg))
46+ msg_formatted formatted = {0};
47+
48+ size_t index = 0;
49+
50+ while(isdigit(msg[index]) || msg[index] == '-')
51+ index++;
52+
53+ if(index)
2654 {
27- char* ret = calloc(1,1);
28- return ret;
55+ formatted.id = malloc(index+1);
56+ strncpy(formatted.id, msg, index);
57+ formatted.id[index] = '\0';
2958 }
3059
31- char* command = malloc(strlen(msg) + 1);
32- sscanf(msg, "%s", command);
60+ formatted.command = malloc(strlen(msg+index) + 1);
61+ sscanf(msg+index, "%s", formatted.command);
3362
34- Vector* arguments = new_vector();
63+ formatted.arguments = new_vector();
3564
36- char* tmp_msg = malloc(strlen(msg)+1);
37- strcpy(tmp_msg, msg);
65+ char* tmp_msg = malloc(strlen(msg+index)+1);
66+ strcpy(tmp_msg, msg+index);
3867
3968
4069 char* current = strtok(tmp_msg, " ");
@@ -44,14 +73,32 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
4473 {
4574 tmp_arg = malloc(strlen(current)+1);
4675 strcpy(tmp_arg, current);
47- vector_push(arguments, tmp_arg);
76+ vector_push(formatted.arguments, tmp_arg);
4877 current = strtok(NULL, " ");
4978 }
5079
51- if(arguments->length > 1)
52- vector_remove(arguments,0,free);
80+ if(formatted.arguments->length > 1)
81+ vector_remove(formatted.arguments, 0, free);
82+
83+ free(tmp_msg);
5384
54- char* (*func_ptr)(const char*) = cmd_error;
85+ return formatted;
86+}
87+
88+char* handle_gtp_cmd(const char* msg, game_state* game)
89+{
90+ if(!msg || !strlen(msg))
91+ {
92+ char* ret = calloc(1,1);
93+ return ret;
94+ }
95+
96+ msg_formatted formatted = format_msg(msg);
97+ char* command = formatted.command;
98+ Vector* arguments = formatted.arguments;
99+ char* id = formatted.id;
100+
101+ char* (*func_ptr)(const char*, char* id) = cmd_error;
55102 const char* func_args = "unknown command";
56103
57104 if(strcmp(command, "protocol_version") == 0)
@@ -102,6 +149,8 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
102149 func_args = "komi not a float";
103150 }
104151 } else if(strcmp(command, "clear_board") == 0) {
152+ func_ptr = cmd_success;
153+ func_args = "";
105154 unsigned int size = game->board->size;
106155 delete_board(game->board);
107156 game->board = create_board(size);
@@ -109,13 +158,14 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
109158 char* color = malloc(6);
110159 char y;
111160 int x;
112- if((arguments->length == 2 || arguments->length == 3) &&
113- (snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) &&
114- (strcmp(color, "white") == 0 || strcmp(color, "black") == 0) &&
115- (sscanf(vector_at(arguments,1), "%c", &y) > 0) &&
116- ((unsigned char)(tolower(y) - 'a') < game->board->size) &&
117- (sscanf((char*)vector_at(arguments,1)+1, "%d", &x) > 0) &&
118- ((unsigned int)x <= game->board->size) && (unsigned int)x > 0)
161+ if((arguments->length == 2 || arguments->length == 3) && //either its "a 10" or "a10"
162+ (snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) && //"white" and "black" are only 6 chars
163+ (strcmp(color, "white") == 0 || strcmp(color, "black") == 0) && // check color
164+ (sscanf(vector_at(arguments,1), "%c", &y) > 0) && //get vertical coordinate
165+ ((unsigned char)(tolower(y) - 'a') < game->board->size) && // check range
166+ ((sscanf((char*)vector_at(arguments,1)+1, "%d", &x) > 0) || // get horizontal coordinate if no space between
167+ ((arguments->length == 3) && (sscanf((char*)vector_at(arguments,2), "%d", &x) > 0))) && // get horizontal coordinate if space between
168+ ((unsigned int)x <= game->board->size) && ((unsigned int)x > 0)) // check range
119169 {
120170 if(play_at(game, (unsigned char)(y-'a'), (unsigned int)x-1))
121171 {
@@ -131,6 +181,8 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
131181 }
132182 free(color);
133183 } else if(strcmp(command, "genmove") == 0) {
184+ func_ptr = cmd_success;
185+ func_args = "";
134186 unsigned int y;
135187 unsigned int x;
136188 do
@@ -143,7 +195,6 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
143195
144196 free(command);
145197 delete_vector(arguments, free);
146- free(tmp_msg);
147198
148- return func_ptr(func_args);
199+ return func_ptr(func_args, id);
149200 }
Mtest.c
@@ -62,19 +62,76 @@ void test2(void)
6262
6363 void test3(void)
6464 {
65- puts("test2 running");
65+ puts("test3 running");
6666
6767 game_state* test_game = create_game(11, 0);
6868
69- char* ret =handle_gtp_cmd("play white a9", test_game);
69+ char* ret =handle_gtp_cmd("play white a 10", test_game);
7070 printf("%s\n", ret);
7171 free(ret);
7272 print_board(test_game->board);
7373
74+ ret =handle_gtp_cmd("version", test_game);
75+ printf("%s\n", ret);
76+ free(ret);
77+
78+ ret =handle_gtp_cmd("komi -6.5", test_game);
79+ printf("%s\n", ret);
80+ printf("%f\n", test_game->komi);
81+ free(ret);
82+
83+ ret =handle_gtp_cmd("protocol_version", test_game);
84+ printf("%s\n", ret);
85+ free(ret);
86+
87+ ret =handle_gtp_cmd("known_command play", test_game);
88+ printf("%s\n", ret);
89+ free(ret);
90+
91+ ret =handle_gtp_cmd("known_command what", test_game);
92+ printf("%s\n", ret);
93+ free(ret);
94+
95+ ret =handle_gtp_cmd("list_commands", test_game);
96+ printf("%s\n", ret);
97+ free(ret);
98+
99+ ret =handle_gtp_cmd("1clear_board", test_game);
100+ printf("%s\n", ret);
101+ free(ret);
102+
103+ ret =handle_gtp_cmd("2boardsize 26", test_game);
104+ printf("%s\n", ret);
105+ free(ret);
106+
107+ ret =handle_gtp_cmd("genmove", test_game);
108+ printf("%s\n", ret);
109+ free(ret);
110+
111+ print_board(test_game->board);
112+
74113
75114 delete_game(test_game);
76115
77- puts("test2 finished");
116+ puts("test3 finished");
117+}
118+
119+void test4(void)
120+{
121+ puts("test4 running");
122+
123+ game_state* test_game = create_game(19, 6.5);
124+ go_board* test_board = test_game->board;
125+ set_board_at(test_board, 2, 3, WHITE);
126+ set_board_at(test_board, 2, 5, WHITE);
127+ set_board_at(test_board, 1, 4, WHITE);
128+ set_board_at(test_board, 3, 4, BLACK);
129+ play_at(test_game, 2,4);
130+
131+ print_board(test_game->board);
132+
133+ delete_game(test_game);
134+ puts("test4 finished");
78135 }
79136
80137
@@ -83,5 +140,6 @@ int main(int argc, char** argv)
83140 test1();
84141 test2();
85142 test3();
143+ test4();
86144
87145 }