refactored play_func(), added final_score to known_commands, fixed type issues, fixed coordinate issues with I and higher coords,fixed captured point counting, added cutils.wrap file for real this time
Minclude/simple-go/simple-go.h
| @@ -15,7 +15,7 @@ | |||
|---|---|---|---|
| 15 | 15 | #define NO_FIELD '\0' | |
| 16 | 16 | #define COUNTED '+' | |
| 17 | 17 | ||
| 18 | - | typedef unsigned int go_coordinate; | |
| 18 | + | typedef size_t go_coordinate; | |
| 19 | 19 | typedef char go_symbol; | |
| 20 | 20 | ||
| 21 | 21 | typedef struct go_board | |
| @@ -51,7 +51,7 @@ bool check_bounds(const go_board* board, go_coordinate y, go_coordinate x); | |||
|---|---|---|---|
| 51 | 51 | char get_board_at(const go_board* board, go_coordinate y, go_coordinate x); | |
| 52 | 52 | void set_board_at(go_board* board, go_coordinate y, go_coordinate x, char item); | |
| 53 | 53 | ||
| 54 | - | void kill_group(go_board* board, const go_board* overlay); | |
| 54 | + | void kill_group(game_state* game, const go_board* overlay); | |
| 55 | 55 | bool group_killable(game_state* game, go_coordinate y, go_coordinate x); | |
| 56 | 56 | bool group_attachable(const game_state* game, go_coordinate y, go_coordinate x); | |
| 57 | 57 | bool play_at(game_state* game, go_coordinate y, go_coordinate x, go_symbol color); | |
Msrc/simple-go.c
| @@ -47,14 +47,21 @@ bool check_bounds(const go_board* board, go_coordinate y, go_coordinate x) | |||
|---|---|---|---|
| 47 | 47 | return false; | |
| 48 | 48 | } | |
| 49 | 49 | ||
| 50 | - | void kill_group(go_board* board, const go_board* overlay) | |
| 50 | + | void kill_group(game_state* game, const go_board* overlay) | |
| 51 | 51 | { | |
| 52 | + | go_board* board = game->board; | |
| 53 | + | double* captured = NULL; | |
| 52 | 54 | for(go_coordinate y = 0; y < board->size; y++) | |
| 53 | 55 | { | |
| 54 | 56 | for(go_coordinate x = 0; x < board->size; x++) | |
| 55 | 57 | { | |
| 56 | 58 | if(get_board_at(overlay, y, x) == GROUP) | |
| 59 | + | { | |
| 60 | + | if(!captured) | |
| 61 | + | captured = get_board_at(board, y, x) == BLACK ? &game->white_captured : &game->black_captured; | |
| 57 | 62 | set_board_at(board, y, x, EMPTY); | |
| 63 | + | (*captured)++; | |
| 64 | + | } | |
| 58 | 65 | } | |
| 59 | 66 | } | |
| 60 | 67 | } | |
| @@ -134,7 +141,7 @@ bool group_killable(game_state* game, go_coordinate y, go_coordinate x) | |||
|---|---|---|---|
| 134 | 141 | find_group(game->board, enemy_group, y, x); | |
| 135 | 142 | if(count_liberties(game->board, enemy_group) <= 1) | |
| 136 | 143 | { | |
| 137 | - | kill_group(game->board, enemy_group); | |
| 144 | + | kill_group(game, enemy_group); | |
| 138 | 145 | delete_board(enemy_group); | |
| 139 | 146 | return true; | |
| 140 | 147 | } else { | |
| @@ -376,10 +383,10 @@ go_score* score_game(const game_state* game) | |||
|---|---|---|---|
| 376 | 383 | if((belongs = group_belongs(board, overlay)) == WHITE) | |
| 377 | 384 | { | |
| 378 | 385 | vector_push(ret->white_groups, overlay); | |
| 379 | - | ret->white_points += group_size(overlay); | |
| 386 | + | ret->white_points += (double)group_size(overlay); | |
| 380 | 387 | } else if(belongs == BLACK) { | |
| 381 | 388 | vector_push(ret->black_groups, overlay); | |
| 382 | - | ret->black_points += group_size(overlay); | |
| 389 | + | ret->black_points += (double)group_size(overlay); | |
| 383 | 390 | } else { | |
| 384 | 391 | delete_board(overlay); | |
| 385 | 392 | } | |
Msrc/simple-gtp-func.c
| @@ -1,7 +1,7 @@ | |||
|---|---|---|---|
| 1 | 1 | #include <simple-go/simple-gtp-func.h> | |
| 2 | 2 | ||
| 3 | - | const char* const known_commands_string = "protocol_version\nname\nversion\nknown_command\nlist_commands\nquit\nboardsize\nclear_board\nkomi\nplay\ngenmove\nshowboard"; | |
| 4 | - | const char* known_commands_array[] = {"protocol_version","name","version","known_command","list_commands","quit","boardsize","clear_board","komi","play","genmove","showboard", NULL}; | |
| 3 | + | const char* const known_commands_string = "protocol_version\nname\nversion\nknown_command\nlist_commands\nquit\nboardsize\nclear_board\nkomi\nplay\ngenmove\nshowboard\nfinal_score"; | |
| 4 | + | const char* known_commands_array[] = {"protocol_version","name","version","known_command","list_commands","quit","boardsize","clear_board","komi","play","genmove","showboard", "final_score", NULL}; | |
| 5 | 5 | ||
| 6 | 6 | static char* cmd_error(const char* msg, const char* id) | |
| 7 | 7 | { | |
| @@ -101,7 +101,7 @@ char* komi_func(const Vector* arguments, const char* id, game_state* game) | |||
|---|---|---|---|
| 101 | 101 | ||
| 102 | 102 | char* clear_board_func(const Vector* arguments, const char* id, game_state* game) | |
| 103 | 103 | { | |
| 104 | - | unsigned int size = game->board->size; | |
| 104 | + | go_coordinate size = game->board->size; | |
| 105 | 105 | delete_board(game->board); | |
| 106 | 106 | game->board = create_board(size); | |
| 107 | 107 | return cmd_success(NULL, id); | |
| @@ -110,32 +110,42 @@ char* clear_board_func(const Vector* arguments, const char* id, game_state* game | |||
|---|---|---|---|
| 110 | 110 | char* play_func(const Vector* arguments, const char* id, game_state* game) | |
| 111 | 111 | { | |
| 112 | 112 | char* color = malloc(6); | |
| 113 | - | char x; | |
| 114 | - | int y; | |
| 115 | - | if((arguments->length == 2 || arguments->length == 3) && //either its "a 10" or "a10" | |
| 116 | - | (snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) && //"white" and "black" are only 6 chars | |
| 117 | - | (strcmp(color, "white") == 0 || strcmp(color, "black") == 0 || | |
| 118 | - | strcmp(color, "w") == 0 || strcmp(color, "b") == 0) && // check color | |
| 119 | - | (sscanf(vector_at(arguments,1), "%c", &x) > 0) && // get horizontal coordinate | |
| 120 | - | ((unsigned char)(tolower(x) - 'a') < game->board->size) && // check range | |
| 121 | - | ((sscanf((char*)vector_at(arguments,1)+1, "%d", &y) > 0) || // get vertical coordinate if no space between | |
| 122 | - | ((arguments->length == 3) && (sscanf((char*)vector_at(arguments,2), "%d", &y) > 0))) && // get vertical coordinate if space between | |
| 123 | - | ((unsigned int)y <= game->board->size) && y > 0) // check range | |
| 113 | + | char xchar; | |
| 114 | + | size_t x; | |
| 115 | + | size_t y; | |
| 116 | + | ||
| 117 | + | if(!(arguments->length == 2 || arguments->length == 3)) //allow "a 10" or "a10" | |
| 118 | + | goto error; | |
| 119 | + | if(snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) <= 0) //"white" and "black" are only 6 chars | |
| 120 | + | goto error; | |
| 121 | + | if(!(strcmp_nocase(color, "white") == 0 || strcmp_nocase(color, "black") == 0 || // check color | |
| 122 | + | strcmp_nocase(color, "w") == 0 || strcmp_nocase(color, "b") == 0)) | |
| 123 | + | goto error; | |
| 124 | + | if(sscanf(vector_at(arguments,1), "%c", &xchar) <= 0) // get horizontal coordinate | |
| 125 | + | goto error; | |
| 126 | + | ||
| 127 | + | x = (size_t)tolower(xchar) - 'a'; | |
| 128 | + | x = x >= 9 ? x-1 : x; //skip J | |
| 129 | + | if((x < 'i' && x >= game->board->size) || (x > 'i' && x-1 >= game->board->size)) // check range | |
| 130 | + | goto error; | |
| 131 | + | if(!((arguments->length == 2) && (sscanf((char*)vector_at(arguments,1)+1, "%zu", &y) > 0)) && // get vertical coordinate if no space between | |
| 132 | + | !((arguments->length == 3) && (sscanf((char*)vector_at(arguments,2), "%zu", &y) > 0))) // get vertical coordinate if space between | |
| 133 | + | goto error; | |
| 134 | + | if(y > game->board->size) | |
| 135 | + | goto error; | |
| 136 | + | ||
| 137 | + | if(play_at(game, game->board->size-y, x, (strcmp(color, "white") == 0 || strcmp(color, "w") == 0) ? WHITE : BLACK)) | |
| 124 | 138 | { | |
| 125 | - | ||
| 126 | - | if(play_at(game, game->board->size-(unsigned int)y, (unsigned char)(x-'a'), (strcmp(color, "white") == 0 || strcmp(color, "w") == 0) ? WHITE : BLACK)) | |
| 127 | - | { | |
| 128 | - | free(color); | |
| 129 | - | return cmd_success(NULL, id); | |
| 130 | - | } else { | |
| 131 | - | free(color); | |
| 132 | - | return cmd_error("illegal move", id); | |
| 133 | - | } | |
| 139 | + | free(color); | |
| 140 | + | return cmd_success(NULL, id); | |
| 134 | 141 | } else { | |
| 135 | 142 | free(color); | |
| 136 | - | return cmd_error("invalid color or coordinate", id); | |
| 143 | + | return cmd_error("illegal move", id); | |
| 137 | 144 | } | |
| 138 | 145 | ||
| 146 | + | error: | |
| 147 | + | free(color); | |
| 148 | + | return cmd_error("invalid color or coordinate", id); | |
| 139 | 149 | } | |
| 140 | 150 | ||
| 141 | 151 | char* genmove_func(const Vector* arguments, const char* id, game_state* game) | |
Msrc/test.c
| @@ -4,7 +4,8 @@ | |||
|---|---|---|---|
| 4 | 4 | static void test1(void) | |
| 5 | 5 | { | |
| 6 | 6 | puts("test1 running"); | |
| 7 | - | go_board* test_board = create_board(5); | |
| 7 | + | game_state* test_game = create_game(5, 6.5); | |
| 8 | + | go_board* test_board = test_game->board; | |
| 8 | 9 | ||
| 9 | 10 | set_board_at(test_board, 2, 2, WHITE); | |
| 10 | 11 | set_board_at(test_board, 2, 3, WHITE); | |
| @@ -22,13 +23,13 @@ static void test1(void) | |||
|---|---|---|---|
| 22 | 23 | ||
| 23 | 24 | print_board(test_overlay); | |
| 24 | 25 | ||
| 25 | - | printf("liberties: %d\n", count_liberties(test_board,test_overlay)); | |
| 26 | + | printf("liberties: %ld\n", count_liberties(test_board,test_overlay)); | |
| 26 | 27 | ||
| 27 | - | kill_group(test_board, test_overlay); | |
| 28 | + | kill_group(test_game, test_overlay); | |
| 28 | 29 | ||
| 29 | 30 | print_board(test_board); | |
| 30 | 31 | ||
| 31 | - | delete_board(test_board); | |
| 32 | + | delete_game(test_game); | |
| 32 | 33 | delete_board(test_overlay); | |
| 33 | 34 | puts("test1 finished"); | |
| 34 | 35 | } | |