Prototype for gtp protocol
M.gitignore
| @@ -1,6 +1,13 @@ | |||
|---|---|---|---|
| 1 | 1 | # Binaries | |
| 2 | 2 | test | |
| 3 | 3 | ||
| 4 | + | #cutils files | |
| 5 | + | cutils.h | |
| 6 | + | cutils_endian.h | |
| 7 | + | dyn_string.h | |
| 8 | + | libcutils.so | |
| 9 | + | vector.h | |
| 10 | + | ||
| 4 | 11 | # Prerequisites | |
| 5 | 12 | *.d | |
| 6 | 13 | ||
| @@ -52,4 +59,4 @@ test | |||
|---|---|---|---|
| 52 | 59 | modules.order | |
| 53 | 60 | Module.symvers | |
| 54 | 61 | Mkfile.old | |
| 55 | - | dkms.conf | |
| 62 | + | dkms.conf | |
MMakefile
| @@ -1,4 +1,3 @@ | |||
|---|---|---|---|
| 1 | 1 | all: | |
| 2 | - | gcc -Og -g test.c simple-go.c -o test -std=c11 \ | |
| 3 | - | -Wall -Wextra -Wpedantic -Wnull-dereference -Wshadow -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wstrict-overflow=5 -Wunreachable-code -Wno-unused-parameter \ | |
| 4 | - | -fsanitize=undefined | |
| 2 | + | gcc -L./ -lcutils -O0 -g test.c simple-go.c simple-gtp.c -o test -std=c11 \ | |
| 3 | + | -Wall -Wextra -Wpedantic -Wnull-dereference -Wshadow -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wstrict-overflow=5 -Wunreachable-code -Wno-unused-parameter -Wno-missing-prototypes \ | |
Msimple-go.c
| @@ -1,12 +1,12 @@ | |||
|---|---|---|---|
| 1 | 1 | #include "simple-go.h" | |
| 2 | 2 | ||
| 3 | - | go_board* create_board(size_t size) | |
| 3 | + | go_board* create_board(unsigned int size) | |
| 4 | 4 | { | |
| 5 | 5 | go_board* board = malloc(sizeof(*board)); | |
| 6 | 6 | assert(board); | |
| 7 | 7 | board->field_array = malloc(size*size*sizeof(*board->field_array)); | |
| 8 | 8 | assert(board->field_array); | |
| 9 | - | for(size_t i = 0; i < size*size; i++) | |
| 9 | + | for(unsigned int i = 0; i < size*size; i++) | |
| 10 | 10 | { | |
| 11 | 11 | board->field_array[i] = EMPTY; | |
| 12 | 12 | } | |
| @@ -21,11 +21,12 @@ void delete_board(go_board* board) | |||
|---|---|---|---|
| 21 | 21 | free(board); | |
| 22 | 22 | } | |
| 23 | 23 | ||
| 24 | - | game_state* create_game(size_t size) | |
| 24 | + | game_state* create_game(unsigned int size, float komi) | |
| 25 | 25 | { | |
| 26 | 26 | game_state* game = malloc(sizeof(*game)); | |
| 27 | 27 | game->board = create_board(size); | |
| 28 | 28 | game->black_turn = true; | |
| 29 | + | game->komi = komi; | |
| 29 | 30 | ||
| 30 | 31 | return game; | |
| 31 | 32 | } | |
| @@ -36,7 +37,7 @@ void delete_game(game_state* game) | |||
|---|---|---|---|
| 36 | 37 | free(game); | |
| 37 | 38 | } | |
| 38 | 39 | ||
| 39 | - | bool check_bounds(go_board* board, size_t y, size_t x) | |
| 40 | + | bool check_bounds(go_board* board, unsigned int y, unsigned int x) | |
| 40 | 41 | { | |
| 41 | 42 | if(y < board->size && x < board->size) | |
| 42 | 43 | return true; | |
| @@ -46,9 +47,9 @@ bool check_bounds(go_board* board, size_t y, size_t x) | |||
|---|---|---|---|
| 46 | 47 | ||
| 47 | 48 | void kill_group(go_board* board, go_board* overlay) | |
| 48 | 49 | { | |
| 49 | - | for(size_t y = 0; y < board->size; y++) | |
| 50 | + | for(unsigned int y = 0; y < board->size; y++) | |
| 50 | 51 | { | |
| 51 | - | for(size_t x = 0; x < board->size; x++) | |
| 52 | + | for(unsigned int x = 0; x < board->size; x++) | |
| 52 | 53 | { | |
| 53 | 54 | if(get_board_at(overlay, y, x) == GROUP) | |
| 54 | 55 | set_board_at(board, y, x, EMPTY); | |
| @@ -58,9 +59,9 @@ void kill_group(go_board* board, go_board* overlay) | |||
|---|---|---|---|
| 58 | 59 | ||
| 59 | 60 | void print_board(go_board* board) | |
| 60 | 61 | { | |
| 61 | - | for(size_t y = 0; y < board->size; y++) | |
| 62 | + | for(unsigned int y = 0; y < board->size; y++) | |
| 62 | 63 | { | |
| 63 | - | for(size_t x = 0; x < board->size; x++) | |
| 64 | + | for(unsigned int x = 0; x < board->size; x++) | |
| 64 | 65 | { | |
| 65 | 66 | putchar(get_board_at(board,y,x)); | |
| 66 | 67 | putchar(' '); | |
| @@ -69,7 +70,7 @@ void print_board(go_board* board) | |||
|---|---|---|---|
| 69 | 70 | } | |
| 70 | 71 | } | |
| 71 | 72 | ||
| 72 | - | bool play_at(game_state* game, size_t y, size_t x) | |
| 73 | + | bool play_at(game_state* game, unsigned int y, unsigned int x) | |
| 73 | 74 | { | |
| 74 | 75 | //check out-of-bounds | |
| 75 | 76 | if(!check_bounds(game->board, y, x)) | |
| @@ -116,6 +117,7 @@ bool play_at(game_state* game, size_t y, size_t x) | |||
|---|---|---|---|
| 116 | 117 | kill_group(game->board, enemy_group); | |
| 117 | 118 | can_place = true; | |
| 118 | 119 | } | |
| 120 | + | delete_board(enemy_group); | |
| 119 | 121 | } else if(left == EMPTY) { | |
| 120 | 122 | can_place = true; | |
| 121 | 123 | } else { | |
| @@ -135,6 +137,7 @@ bool play_at(game_state* game, size_t y, size_t x) | |||
|---|---|---|---|
| 135 | 137 | kill_group(game->board, enemy_group); | |
| 136 | 138 | can_place = true; | |
| 137 | 139 | } | |
| 140 | + | delete_board(enemy_group); | |
| 138 | 141 | } else if(down == EMPTY) { | |
| 139 | 142 | can_place = true; | |
| 140 | 143 | } else { | |
| @@ -154,6 +157,7 @@ bool play_at(game_state* game, size_t y, size_t x) | |||
|---|---|---|---|
| 154 | 157 | kill_group(game->board, enemy_group); | |
| 155 | 158 | can_place = true; | |
| 156 | 159 | } | |
| 160 | + | delete_board(enemy_group); | |
| 157 | 161 | } else if(right == EMPTY) { | |
| 158 | 162 | can_place = true; | |
| 159 | 163 | } else { | |
| @@ -172,7 +176,7 @@ bool play_at(game_state* game, size_t y, size_t x) | |||
|---|---|---|---|
| 172 | 176 | return true; | |
| 173 | 177 | } | |
| 174 | 178 | ||
| 175 | - | char get_board_at(go_board* board, size_t y, size_t x) | |
| 179 | + | char get_board_at(go_board* board, unsigned int y, unsigned int x) | |
| 176 | 180 | { | |
| 177 | 181 | if(check_bounds(board, y, x)) | |
| 178 | 182 | return board->field_array[y*board->size+x]; | |
| @@ -180,45 +184,46 @@ char get_board_at(go_board* board, size_t y, size_t x) | |||
|---|---|---|---|
| 180 | 184 | return INVALID_FIELD; | |
| 181 | 185 | } | |
| 182 | 186 | ||
| 183 | - | void set_board_at(go_board* board, size_t y, size_t x, char item) | |
| 187 | + | void set_board_at(go_board* board, unsigned int y, unsigned int x, char item) | |
| 184 | 188 | { | |
| 185 | 189 | if(check_bounds(board,y,x)) | |
| 186 | 190 | board->field_array[y*board->size+x] = item; | |
| 187 | 191 | } | |
| 188 | 192 | ||
| 189 | - | void find_group(go_board* board, go_board* overlay, size_t y, size_t x) | |
| 193 | + | void find_group(go_board* board, go_board* overlay, unsigned int y, unsigned int x) | |
| 190 | 194 | { | |
| 191 | 195 | assert(board->size == overlay->size); | |
| 192 | - | assert(check_bounds(board, y, x)); | |
| 193 | - | ||
| 194 | - | set_board_at(overlay, y, x, GROUP); | |
| 195 | - | char field = get_board_at(board,y,x); | |
| 196 | + | if(check_bounds(board, y, x)) | |
| 197 | + | { | |
| 198 | + | set_board_at(overlay, y, x, GROUP); | |
| 199 | + | char field = get_board_at(board,y,x); | |
| 196 | 200 | ||
| 197 | - | if(get_board_at(board,y-1,x) == field && get_board_at(overlay,y-1,x) == EMPTY) | |
| 198 | - | find_group(board, overlay, y-1, x); | |
| 201 | + | if(get_board_at(board,y-1,x) == field && get_board_at(overlay,y-1,x) == EMPTY) | |
| 202 | + | find_group(board, overlay, y-1, x); | |
| 199 | 203 | ||
| 200 | - | if(get_board_at(board,y,x-1) == field && get_board_at(overlay,y,x-1) == EMPTY) | |
| 201 | - | find_group(board, overlay, y, x-1); | |
| 204 | + | if(get_board_at(board,y,x-1) == field && get_board_at(overlay,y,x-1) == EMPTY) | |
| 205 | + | find_group(board, overlay, y, x-1); | |
| 202 | 206 | ||
| 203 | - | if(get_board_at(board,y+1,x) == field && get_board_at(overlay,y+1,x) == EMPTY) | |
| 204 | - | find_group(board, overlay, y+1, x); | |
| 207 | + | if(get_board_at(board,y+1,x) == field && get_board_at(overlay,y+1,x) == EMPTY) | |
| 208 | + | find_group(board, overlay, y+1, x); | |
| 205 | 209 | ||
| 206 | - | if(get_board_at(board,y,x+1) == field && get_board_at(overlay,y,x+1) == EMPTY) | |
| 207 | - | find_group(board, overlay, y, x+1); | |
| 210 | + | if(get_board_at(board,y,x+1) == field && get_board_at(overlay,y,x+1) == EMPTY) | |
| 211 | + | find_group(board, overlay, y, x+1); | |
| 212 | + | } | |
| 208 | 213 | } | |
| 209 | 214 | ||
| 210 | - | size_t count_liberties(go_board* board, go_board* overlay) | |
| 215 | + | unsigned long count_liberties(go_board* board, go_board* overlay) | |
| 211 | 216 | { | |
| 212 | 217 | assert(board->size == overlay->size); | |
| 213 | 218 | ||
| 214 | 219 | go_board* tmpoverlay = create_board(board->size); | |
| 215 | 220 | memcpy(tmpoverlay->field_array, overlay->field_array, board->size*board->size); | |
| 216 | 221 | ||
| 217 | - | size_t liberties = 0; | |
| 222 | + | unsigned long liberties = 0; | |
| 218 | 223 | ||
| 219 | - | for(size_t y = 0; y < board->size; y++) | |
| 224 | + | for(unsigned int y = 0; y < board->size; y++) | |
| 220 | 225 | { | |
| 221 | - | for(size_t x = 0; x < board->size; x++) | |
| 226 | + | for(unsigned int x = 0; x < board->size; x++) | |
| 222 | 227 | { | |
| 223 | 228 | if(get_board_at(overlay, y, x) == GROUP) | |
| 224 | 229 | { | |
Msimple-go.h
| @@ -17,31 +17,32 @@ | |||
|---|---|---|---|
| 17 | 17 | typedef struct go_board | |
| 18 | 18 | { | |
| 19 | 19 | char* field_array; | |
| 20 | - | size_t size; | |
| 20 | + | unsigned int size; | |
| 21 | 21 | } go_board; | |
| 22 | 22 | ||
| 23 | 23 | typedef struct game_state | |
| 24 | 24 | { | |
| 25 | 25 | go_board* board; | |
| 26 | + | float komi; | |
| 26 | 27 | bool black_turn; | |
| 27 | 28 | } game_state; | |
| 28 | 29 | ||
| 29 | 30 | ||
| 30 | - | go_board* create_board(size_t size); | |
| 31 | + | go_board* create_board(unsigned int size); | |
| 31 | 32 | void delete_board(go_board* board); | |
| 32 | - | game_state* create_game(size_t size); | |
| 33 | + | game_state* create_game(unsigned int size, float komi); | |
| 33 | 34 | void delete_game(game_state* game); | |
| 34 | 35 | ||
| 35 | - | bool check_bounds(go_board* board, size_t y, size_t x); | |
| 36 | - | char get_board_at(go_board* board, size_t y, size_t x); | |
| 37 | - | void set_board_at(go_board* board, size_t y, size_t x, char item); | |
| 36 | + | bool check_bounds(go_board* board, unsigned int y, unsigned int x); | |
| 37 | + | char get_board_at(go_board* board, unsigned int y, unsigned int x); | |
| 38 | + | void set_board_at(go_board* board, unsigned int y, unsigned int x, char item); | |
| 38 | 39 | ||
| 39 | 40 | void kill_group(go_board* board, go_board* overlay); | |
| 40 | - | bool play_at(game_state* game, size_t y, size_t x); | |
| 41 | + | bool play_at(game_state* game, unsigned int y, unsigned int x); | |
| 41 | 42 | ||
| 42 | 43 | void print_board(go_board* board); | |
| 43 | - | void find_group(go_board* board, go_board* overlay, size_t y, size_t x); | |
| 44 | - | size_t count_liberties(go_board* board, go_board* overlay); | |
| 44 | + | void find_group(go_board* board, go_board* overlay, unsigned int y, unsigned int x); | |
| 45 | + | unsigned long count_liberties(go_board* board, go_board* overlay); | |
| 45 | 46 | ||
| 46 | 47 | ||
| 47 | 48 | ||
Asimple-gtp.c
| @@ -0,0 +1,147 @@ | |||
|---|---|---|---|
| 1 | + | #include "simple-gtp.h" | |
| 2 | + | ||
| 3 | + | char* cmd_error(const char* msg) | |
| 4 | + | { | |
| 5 | + | char* ret = malloc(strlen("? ") + strlen(msg) + 1); | |
| 6 | + | strcpy(ret, "? "); | |
| 7 | + | strcat(ret, msg); | |
| 8 | + | return ret; | |
| 9 | + | } | |
| 10 | + | ||
| 11 | + | char* cmd_success(const char* msg) | |
| 12 | + | { | |
| 13 | + | char* ret = malloc(strlen("= ") + strlen(msg) + 2); | |
| 14 | + | strcpy(ret, "= "); | |
| 15 | + | strcat(ret, msg); | |
| 16 | + | return ret; | |
| 17 | + | } | |
| 18 | + | ||
| 19 | + | const char* const known_commands_string = "protocol_version\nname\nversion\nknown_command\nlist_commands\nquit\nboardsize\nclear_board\nkomi\nplay\ngenmove\nshowboard"; | |
| 20 | + | const char* known_commands_array[] = {"protocol_version","name","version","known_command","list_commands","quit","boardsize","clear_board","komi","play","genmove","showboard"}; | |
| 21 | + | int cmd_count = sizeof(known_commands_array)/sizeof(known_commands_array[0]); | |
| 22 | + | ||
| 23 | + | char* handle_gtp_cmd(const char* msg, game_state* game) | |
| 24 | + | { | |
| 25 | + | if(!msg || !strlen(msg)) | |
| 26 | + | { | |
| 27 | + | char* ret = calloc(1,1); | |
| 28 | + | return ret; | |
| 29 | + | } | |
| 30 | + | ||
| 31 | + | char* command = malloc(strlen(msg) + 1); | |
| 32 | + | sscanf(msg, "%s", command); | |
| 33 | + | ||
| 34 | + | Vector* arguments = new_vector(); | |
| 35 | + | ||
| 36 | + | char* tmp_msg = malloc(strlen(msg)+1); | |
| 37 | + | strcpy(tmp_msg, msg); | |
| 38 | + | ||
| 39 | + | ||
| 40 | + | char* current = strtok(tmp_msg, " "); | |
| 41 | + | char* tmp_arg; | |
| 42 | + | ||
| 43 | + | while(current) | |
| 44 | + | { | |
| 45 | + | tmp_arg = malloc(strlen(current)+1); | |
| 46 | + | strcpy(tmp_arg, current); | |
| 47 | + | vector_push(arguments, tmp_arg); | |
| 48 | + | current = strtok(NULL, " "); | |
| 49 | + | } | |
| 50 | + | ||
| 51 | + | char* (*func_ptr)(const char*) = cmd_error; | |
| 52 | + | const char* func_args = "unknown command"; | |
| 53 | + | ||
| 54 | + | if(strcmp(command, "protocol_version") == 0) | |
| 55 | + | { | |
| 56 | + | func_ptr = cmd_success; | |
| 57 | + | func_args = "2"; | |
| 58 | + | } else if(strcmp(command, "name") == 0) { | |
| 59 | + | func_ptr = cmd_success; | |
| 60 | + | func_args = "simple-go"; | |
| 61 | + | } else if(strcmp(command, "version") == 0) { | |
| 62 | + | func_ptr = cmd_success; | |
| 63 | + | func_args = "0.1"; | |
| 64 | + | } else if(strcmp(command, "known_command") == 0) { | |
| 65 | + | func_ptr = cmd_success; | |
| 66 | + | func_args = "false"; | |
| 67 | + | for(int i = 0; i < cmd_count; i++) | |
| 68 | + | { | |
| 69 | + | if(arguments->length > 0 && strcmp(vector_at(arguments, 0), known_commands_array[i]) == 0) | |
| 70 | + | { | |
| 71 | + | func_args = "true"; | |
| 72 | + | break; | |
| 73 | + | } | |
| 74 | + | } | |
| 75 | + | } else if(strcmp(command, "list_commands") == 0) { | |
| 76 | + | func_ptr = cmd_success; | |
| 77 | + | func_args = known_commands_string; | |
| 78 | + | } else if(strcmp(command, "boardsize") == 0) { | |
| 79 | + | unsigned int size; | |
| 80 | + | if(arguments->length == 1 && sscanf(vector_at(arguments,0), "%u", &size) > 0 && 0 < size && size < 26) | |
| 81 | + | { | |
| 82 | + | func_ptr = cmd_success; | |
| 83 | + | func_args = ""; | |
| 84 | + | delete_board(game->board); | |
| 85 | + | game->board = create_board(size); | |
| 86 | + | } else { | |
| 87 | + | func_ptr = cmd_error; | |
| 88 | + | func_args = "unacceptable size"; | |
| 89 | + | } | |
| 90 | + | } else if(strcmp(command, "komi") == 0) { | |
| 91 | + | float komi; | |
| 92 | + | if(arguments->length == 1 && sscanf(vector_at(arguments,0), "%f", &komi)) | |
| 93 | + | { | |
| 94 | + | func_ptr = cmd_success; | |
| 95 | + | func_args = ""; | |
| 96 | + | game->komi = komi; | |
| 97 | + | } else { | |
| 98 | + | func_ptr = cmd_error; | |
| 99 | + | func_args = "komi not a float"; | |
| 100 | + | } | |
| 101 | + | } else if(strcmp(command, "clear_board") == 0) { | |
| 102 | + | unsigned int size = game->board->size; | |
| 103 | + | delete_board(game->board); | |
| 104 | + | game->board = create_board(size); | |
| 105 | + | } else if(strcmp(command, "play") == 0) { | |
| 106 | + | char* color = malloc(6); | |
| 107 | + | char y; | |
| 108 | + | int x; | |
| 109 | + | if((arguments->length == 2 || arguments->length == 3) && | |
| 110 | + | (snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) && | |
| 111 | + | (strcmp(color, "white") == 0 || strcmp(color, "black") == 0) && | |
| 112 | + | (sscanf(vector_at(arguments,1), "%c", &y) > 0) && | |
| 113 | + | ((unsigned char)(tolower(y) - 'a') < game->board->size) && | |
| 114 | + | (sscanf((char*)vector_at(arguments,1)+1, "%d", &x) > 0) && | |
| 115 | + | ((unsigned int)x <= game->board->size) && (unsigned int)x > 0) | |
| 116 | + | { | |
| 117 | + | if(play_at(game, (unsigned char)(y-'a'), (unsigned int)x-1)) | |
| 118 | + | { | |
| 119 | + | func_ptr = cmd_success; | |
| 120 | + | func_args = ""; | |
| 121 | + | } else { | |
| 122 | + | func_ptr = cmd_error; | |
| 123 | + | func_args = "illegal move"; | |
| 124 | + | } | |
| 125 | + | } else { | |
| 126 | + | func_ptr = cmd_error; | |
| 127 | + | func_args = "invalid color or coordinate"; | |
| 128 | + | } | |
| 129 | + | free(color); | |
| 130 | + | } else if(strcmp(command, "genmove") == 0) { | |
| 131 | + | unsigned int y; | |
| 132 | + | unsigned int x; | |
| 133 | + | do | |
| 134 | + | { | |
| 135 | + | y = (unsigned int)rand() % game->board->size; | |
| 136 | + | x = (unsigned int)rand() % game->board->size; | |
| 137 | + | } while(!play_at(game, y, x)); | |
| 138 | + | ||
| 139 | + | } | |
| 140 | + | ||
| 141 | + | free(command); | |
| 142 | + | delete_vector(arguments, NULL); | |
| 143 | + | free(arguments); | |
| 144 | + | free(tmp_msg); | |
| 145 | + | ||
| 146 | + | return func_ptr(func_args); | |
| 147 | + | } | |
Asimple-gtp.h
| @@ -0,0 +1,13 @@ | |||
|---|---|---|---|
| 1 | + | #ifndef SIMPLE_GTP_H | |
| 2 | + | #define SIMPLE_GTP_H | |
| 3 | + | #include <string.h> | |
| 4 | + | #include <stdlib.h> | |
| 5 | + | #include <stdio.h> | |
| 6 | + | #include <string.h> | |
| 7 | + | #include <ctype.h> | |
| 8 | + | #include "simple-go.h" | |
| 9 | + | #include "cutils.h" | |
| 10 | + | ||
| 11 | + | char* handle_gtp_cmd(const char* msg, game_state* game); | |
| 12 | + | ||
| 13 | + | #endif //SIMPLE_GTP_H | |
Mtest.c
| @@ -1,4 +1,5 @@ | |||
|---|---|---|---|
| 1 | 1 | #include "simple-go.h" | |
| 2 | + | #include "simple-gtp.h" | |
| 2 | 3 | ||
| 3 | 4 | void test1(void) | |
| 4 | 5 | { | |
| @@ -35,12 +36,13 @@ void test1(void) | |||
|---|---|---|---|
| 35 | 36 | void test2(void) | |
| 36 | 37 | { | |
| 37 | 38 | puts("test2 running"); | |
| 38 | - | game_state* test_game = create_game(5); | |
| 39 | + | game_state* test_game = create_game(5, 0); | |
| 39 | 40 | go_board* test_board = test_game->board; | |
| 40 | 41 | set_board_at(test_board, 2, 3, WHITE); | |
| 41 | 42 | set_board_at(test_board, 3, 2, WHITE); | |
| 42 | 43 | set_board_at(test_board, 1, 2, WHITE); | |
| 43 | 44 | set_board_at(test_board, 2, 1, WHITE); | |
| 45 | + | set_board_at(test_board, 1, 1, BLACK); | |
| 44 | 46 | ||
| 45 | 47 | play_at(test_game, 2, 2); | |
| 46 | 48 | print_board(test_game->board); | |
| @@ -58,10 +60,27 @@ void test2(void) | |||
|---|---|---|---|
| 58 | 60 | puts("test2 finished"); | |
| 59 | 61 | } | |
| 60 | 62 | ||
| 63 | + | void test3(void) | |
| 64 | + | { | |
| 65 | + | puts("test2 running"); | |
| 66 | + | ||
| 67 | + | game_state* test_game = create_game(11, 0); | |
| 68 | + | ||
| 69 | + | char* ret =handle_gtp_cmd("play white a9", test_game); | |
| 70 | + | printf("%s\n", ret); | |
| 71 | + | print_board(test_game->board); | |
| 72 | + | ||
| 73 | + | free(ret); | |
| 74 | + | delete_game(test_game); | |
| 75 | + | ||
| 76 | + | puts("test2 finished"); | |
| 77 | + | } | |
| 78 | + | ||
| 61 | 79 | ||
| 62 | 80 | int main(int argc, char** argv) | |
| 63 | 81 | { | |
| 64 | 82 | test1(); | |
| 65 | 83 | test2(); | |
| 84 | + | test3(); | |
| 66 | 85 | ||
| 67 | 86 | } | |