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)
can_place = true;
else if(left == EMPTY)
can_place = true;
else if(up == friendly && group_attachable(game, y, x-1))
else if(left == friendly && group_attachable(game, y, x-1))
can_place = true;
if(down == enemy && group_killable(game, y+1, x))
can_place = true;
else if(down == EMPTY)
can_place = true;
else if(up == friendly && group_attachable(game, y+1, x))
else if(down == friendly && group_attachable(game, y+1, x))
can_place = true;
if(right == enemy && group_killable(game, y, x+1))
can_place = true;
else if(right == EMPTY)
can_place = true;
else if(up == friendly && group_attachable(game, y, x+1))
else if(right == friendly && group_attachable(game, y, x+1))
can_place = true;
if(!can_place)
▾Msimple-go.h
@@ -31,22 +31,22 @@ typedef struct game_state
} game_state;
go_board* create_board(unsigned int size);
go_board* create_board(go_coordinate size);
void delete_board(go_board* board);
game_state* create_game(unsigned int size, float komi);
game_state* create_game(go_coordinate size, float komi);
void delete_game(game_state* game);
bool check_bounds(const go_board* board, unsigned int y, unsigned int x);
char get_board_at(const go_board* board, unsigned int y, unsigned int x);
void set_board_at(go_board* board, unsigned int y, unsigned int x, char item);
bool check_bounds(const go_board* board, go_coordinate y, go_coordinate x);
char get_board_at(const go_board* board, go_coordinate y, go_coordinate x);
void set_board_at(go_board* board, go_coordinate y, go_coordinate x, char item);
void kill_group(go_board* board, go_board* overlay);
bool group_killable(game_state* game, unsigned int y, unsigned int x);
bool group_attachable(const game_state* game, unsigned int y, unsigned int x);
bool play_at(game_state* game, unsigned int y, unsigned int x);
bool group_killable(game_state* game, go_coordinate y, go_coordinate x);
bool group_attachable(const game_state* game, go_coordinate y, go_coordinate x);
bool play_at(game_state* game, go_coordinate y, go_coordinate x);
void print_board(go_board* board);
void find_group(const go_board* board, go_board* overlay, unsigned int y, unsigned int x);
void find_group(const go_board* board, go_board* overlay, go_coordinate y, go_coordinate x);
unsigned long count_liberties(go_board* board, go_board* overlay);
▾Msimple-gtp.c
@@ -1,18 +1,39 @@
#include "simple-gtp.h"
char* cmd_error(const char* msg)
typedef struct msg_formatted
{
char* ret = malloc(strlen("? ") + strlen(msg) + 1);
strcpy(ret, "? ");
char* command;
Vector* arguments;
char* id;
} msg_formatted;
char* cmd_error(const char* msg, char* id)
{
char* ret = malloc(strlen("? ") + strlen(msg) + (id ? strlen(id) : 0) + 3);
strcpy(ret, "?");
if(id)
{
strcat(ret, id);
free(id);
}
strcat(ret, " ");
strcat(ret, msg);
strcat(ret, "\n\n");
return ret;
}
char* cmd_success(const char* msg)
char* cmd_success(const char* msg, char* id)
{
char* ret = malloc(strlen("= ") + strlen(msg) + 2);
strcpy(ret, "= ");
char* ret = malloc(strlen("= ") + strlen(msg) + (id ? strlen(id) : 0) + 3);
strcpy(ret, "=");
if(id)
{
strcat(ret, id);
free(id);
}
strcat(ret, " ");
strcat(ret, msg);
strcat(ret, "\n\n");
return ret;
}
@@ -20,21 +41,29 @@ const char* const known_commands_string = "protocol_version\nname\nversion\nknow
const char* known_commands_array[] = {"protocol_version","name","version","known_command","list_commands","quit","boardsize","clear_board","komi","play","genmove","showboard"};
int cmd_count = sizeof(known_commands_array)/sizeof(known_commands_array[0]);
char* handle_gtp_cmd(const char* msg, game_state* game)
static msg_formatted format_msg(const char* msg)
{
if(!msg || !strlen(msg))
msg_formatted formatted = {0};
size_t index = 0;
while(isdigit(msg[index]) || msg[index] == '-')
index++;
if(index)
{
char* ret = calloc(1,1);
return ret;
formatted.id = malloc(index+1);
strncpy(formatted.id, msg, index);
formatted.id[index] = '\0';
}
char* command = malloc(strlen(msg) + 1);
sscanf(msg, "%s", command);
formatted.command = malloc(strlen(msg+index) + 1);
sscanf(msg+index, "%s", formatted.command);
Vector* arguments = new_vector();
formatted.arguments = new_vector();
char* tmp_msg = malloc(strlen(msg)+1);
strcpy(tmp_msg, msg);
char* tmp_msg = malloc(strlen(msg+index)+1);
strcpy(tmp_msg, msg+index);
char* current = strtok(tmp_msg, " ");
@@ -44,14 +73,32 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
{
tmp_arg = malloc(strlen(current)+1);
strcpy(tmp_arg, current);
vector_push(arguments, tmp_arg);
vector_push(formatted.arguments, tmp_arg);
current = strtok(NULL, " ");
}
if(arguments->length > 1)
vector_remove(arguments,0,free);
if(formatted.arguments->length > 1)
vector_remove(formatted.arguments, 0, free);
free(tmp_msg);
char* (*func_ptr)(const char*) = cmd_error;
return formatted;
}
char* handle_gtp_cmd(const char* msg, game_state* game)
{
if(!msg || !strlen(msg))
{
char* ret = calloc(1,1);
return ret;
}
msg_formatted formatted = format_msg(msg);
char* command = formatted.command;
Vector* arguments = formatted.arguments;
char* id = formatted.id;
char* (*func_ptr)(const char*, char* id) = cmd_error;
const char* func_args = "unknown command";
if(strcmp(command, "protocol_version") == 0)
@@ -102,6 +149,8 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
func_args = "komi not a float";
}
} else if(strcmp(command, "clear_board") == 0) {
func_ptr = cmd_success;
func_args = "";
unsigned int size = game->board->size;
delete_board(game->board);
game->board = create_board(size);
@@ -109,13 +158,14 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
char* color = malloc(6);
char y;
int x;
if((arguments->length == 2 || arguments->length == 3) &&
(snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) &&
(strcmp(color, "white") == 0 || strcmp(color, "black") == 0) &&
(sscanf(vector_at(arguments,1), "%c", &y) > 0) &&
((unsigned char)(tolower(y) - 'a') < game->board->size) &&
(sscanf((char*)vector_at(arguments,1)+1, "%d", &x) > 0) &&
((unsigned int)x <= game->board->size) && (unsigned int)x > 0)
if((arguments->length == 2 || arguments->length == 3) && //either its "a 10" or "a10"
(snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) && //"white" and "black" are only 6 chars
(strcmp(color, "white") == 0 || strcmp(color, "black") == 0) && // check color
(sscanf(vector_at(arguments,1), "%c", &y) > 0) && //get vertical coordinate
((unsigned char)(tolower(y) - 'a') < game->board->size) && // check range
((sscanf((char*)vector_at(arguments,1)+1, "%d", &x) > 0) || // get horizontal coordinate if no space between
((arguments->length == 3) && (sscanf((char*)vector_at(arguments,2), "%d", &x) > 0))) && // get horizontal coordinate if space between
((unsigned int)x <= game->board->size) && ((unsigned int)x > 0)) // check range
{
if(play_at(game, (unsigned char)(y-'a'), (unsigned int)x-1))
{
@@ -131,6 +181,8 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
}
free(color);
} else if(strcmp(command, "genmove") == 0) {
func_ptr = cmd_success;
func_args = "";
unsigned int y;
unsigned int x;
do
@@ -143,7 +195,6 @@ char* handle_gtp_cmd(const char* msg, game_state* game)
free(command);
delete_vector(arguments, free);
free(tmp_msg);
return func_ptr(func_args);
return func_ptr(func_args, id);
}
▾Mtest.c
@@ -62,19 +62,76 @@ void test2(void)
void test3(void)
{
puts("test2 running");
puts("test3 running");
game_state* test_game = create_game(11, 0);
char* ret =handle_gtp_cmd("play white a9", test_game);
char* ret =handle_gtp_cmd("play white a 10", test_game);
printf("%s\n", ret);
free(ret);
print_board(test_game->board);
ret =handle_gtp_cmd("version", test_game);
printf("%s\n", ret);
free(ret);
ret =handle_gtp_cmd("komi -6.5", test_game);
printf("%s\n", ret);
printf("%f\n", test_game->komi);
free(ret);
ret =handle_gtp_cmd("protocol_version", test_game);
printf("%s\n", ret);
free(ret);
ret =handle_gtp_cmd("known_command play", test_game);
printf("%s\n", ret);
free(ret);
ret =handle_gtp_cmd("known_command what", test_game);
printf("%s\n", ret);
free(ret);
ret =handle_gtp_cmd("list_commands", test_game);
printf("%s\n", ret);
free(ret);
ret =handle_gtp_cmd("1clear_board", test_game);
printf("%s\n", ret);
free(ret);
ret =handle_gtp_cmd("2boardsize 26", test_game);
printf("%s\n", ret);
free(ret);
ret =handle_gtp_cmd("genmove", test_game);
printf("%s\n", ret);
free(ret);
print_board(test_game->board);
delete_game(test_game);
puts("test2 finished");
puts("test3 finished");
}
void test4(void)
{
puts("test4 running");
game_state* test_game = create_game(19, 6.5);
go_board* test_board = test_game->board;
set_board_at(test_board, 2, 3, WHITE);
set_board_at(test_board, 2, 5, WHITE);
set_board_at(test_board, 1, 4, WHITE);
set_board_at(test_board, 3, 4, BLACK);
play_at(test_game, 2,4);
print_board(test_game->board);
delete_game(test_game);
puts("test4 finished");
}
@@ -83,5 +140,6 @@ int main(int argc, char** argv)
test1();
test2();
test3();
test4();
}