added check_bound(), changed tests, added protoype for play_at()

AuthorKonata <konata@posteo.jp>
Date
Commit930be82795216cef0c686cd72a2abb5d16a6487b
Parent578e149
4 files changed, 103 insertions(+), 10 deletions(-)
MMakefile
@@ -1,3 +1,4 @@
11 all:
22 gcc -O0 -g test.c simple-go.c -o test \
3- -Wall -Wpedantic -Wnull-dereference -Wshadow -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wstrict-overflow=5 -Wunreachable-code -Wno-unused-parameter
3+ -Wall -Wpedantic -Wnull-dereference -Wshadow -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wstrict-overflow=5 -Wunreachable-code -Wno-unused-parameter \
4+ -fsanitize=undefined
Msimple-go.c
@@ -13,6 +13,14 @@ go_board* create_board(size_t size)
1313 return board;
1414 }
1515
16+bool check_bounds(go_board* board, size_t y, size_t x)
17+{
18+ if(y >= 0 && x >= 0 && y < board->size && x < board->size)
19+ return true;
20+ else
21+ return false;
22+}
23+
1624 void delete_board(go_board* board)
1725 {
1826 free(board->field_array);
@@ -32,9 +40,83 @@ void print_board(go_board* board)
3240 }
3341 }
3442
43+bool play_at(game_state* game, size_t y, size_t x)
44+{
45+ //check out-of-bounds
46+ if(!check_bounds(game->board, y, x))
47+ return false;
48+
49+ //check if field is empty
50+ if(get_board_at(game->board, y, x) != EMPTY)
51+ return false;
52+
53+ //check if placement could lead to suicide
54+ if(get_board_at(game->board, y-1, x) != EMPTY &&
55+ get_board_at(game->board, y, x-1) != EMPTY &&
56+ get_board_at(game->board, y+1, x) != EMPTY &&
57+ get_board_at(game->board, y, x+1) != EMPTY)
58+ //if so, check if placement kills a surrounding group
59+ {
60+ if(get_board_at(game->board, y-1, x) == (game->black_turn ? WHITE : BLACK))
61+ {
62+
63+ go_board* enemy_group = create_board(game->board->size);
64+ find_group(game->board, enemy_group, y-1, x);
65+ if(count_liberties(game->board, enemy_group) > 1)
66+ {
67+ delete_board(enemy_group);
68+ return false;
69+ } else {
70+ //TODO: kill_group();
71+ }
72+ }
73+ if(get_board_at(game->board, y, x-1) == (game->black_turn ? WHITE : BLACK))
74+ {
75+ go_board* enemy_group = create_board(game->board->size);
76+ find_group(game->board, enemy_group, y, x-1);
77+ if(count_liberties(game->board, enemy_group) > 1)
78+ {
79+ delete_board(enemy_group);
80+ return false;
81+ } else {
82+ //kill_group();
83+ }
84+ }
85+ if(get_board_at(game->board, y+1, x) == (game->black_turn ? WHITE : BLACK))
86+ {
87+ go_board* enemy_group = create_board(game->board->size);
88+ find_group(game->board, enemy_group, y+1, x);
89+ if(count_liberties(game->board, enemy_group) > 1)
90+ {
91+ delete_board(enemy_group);
92+ return false;
93+ } else {
94+ //kill_group();
95+ }
96+ }
97+ if(get_board_at(game->board, y, x+1) == (game->black_turn ? WHITE : BLACK))
98+ {
99+ go_board* enemy_group = create_board(game->board->size);
100+ find_group(game->board, enemy_group, y, x+1);
101+ if(count_liberties(game->board, enemy_group) > 1)
102+ {
103+ delete_board(enemy_group);
104+ return false;
105+ } else {
106+ //kill_group();
107+ }
108+ }
109+ //TODO: ...or if it connects to own group that has liberties left
110+ }
111+
112+ set_board_at(game->board, y, x, game->black_turn ? BLACK : WHITE);
113+ game->black_turn = !game->black_turn;
114+ return true;
115+}
116+
35117 char get_board_at(go_board* board, size_t y, size_t x)
36118 {
37- if(y >= 0 && x >= 0 && y < board->size && x < board->size)
119+ if(check_bounds(board, y, x))
38120 return board->field_array[y*board->size+x];
39121 else
40122 return INVALID_FIELD;
@@ -42,13 +124,14 @@ char get_board_at(go_board* board, size_t y, size_t x)
42124
43125 void set_board_at(go_board* board, size_t y, size_t x, char item)
44126 {
45- if(y >= 0 && x >= 0 && y < board->size && x < board->size)
127+ if(check_bounds(board,y,x))
46128 board->field_array[y*board->size+x] = item;
47129 }
48-#include <unistd.h>
130+
49131 void find_group(go_board* board, go_board* overlay, size_t y, size_t x)
50132 {
51133 assert(board->size == overlay->size);
134+ assert(check_bounds(board, y, x));
52135
53136 set_board_at(overlay, y, x, GROUP);
54137 char field = get_board_at(board,y,x);
@@ -106,6 +189,8 @@ size_t count_liberties(go_board* board, go_board* overlay)
106189 }
107190 }
108191
192+ delete_board(tmpoverlay);
193+
109194 return liberties;
110195 }
111196
Msimple-go.h
@@ -22,12 +22,14 @@ typedef struct go_board
2222
2323 typedef struct game_state
2424 {
25- struct go_board* board;
25+ go_board* board;
2626 bool black_turn;
2727 } game_state;
2828
2929
3030 go_board* create_board(size_t size);
31+bool play_at(game_state* game, size_t y, size_t x);
32+bool check_bounds(go_board* board, size_t y, size_t x);
3133 void delete_board(go_board* board);
3234 char get_board_at(go_board* board, size_t y, size_t x);
3335 void set_board_at(go_board* board, size_t y, size_t x, char item);
Mtest.c
@@ -4,19 +4,24 @@ int main(int argc, char** argv)
44 {
55 go_board* test_board = create_board(5);
66
7- set_board_at(test_board,2,2,WHITE);
8- set_board_at(test_board,2,3,WHITE);
9- set_board_at(test_board,1,3,WHITE);
10- set_board_at(test_board,3,3,WHITE);
7+ set_board_at(test_board, 2, 2, WHITE);
8+ set_board_at(test_board, 2, 3, WHITE);
9+ set_board_at(test_board, 1, 3, WHITE);
10+ set_board_at(test_board, 3, 3, WHITE);
11+ set_board_at(test_board, 4, 4, WHITE);
12+ set_board_at(test_board, 3, 1, WHITE);
13+ set_board_at(test_board, 3, 2, BLACK);
1114
1215 print_board(test_board);
1316 putchar('\n');
1417
1518 go_board* overlay = create_board(5);
16- find_group(test_board, overlay,2,2);
19+ find_group(test_board, overlay, 2, 2);
1720
1821 print_board(overlay);
1922
2023 printf("liberties: %ld\n", count_liberties(test_board,overlay));
24+ delete_board(test_board);
25+ delete_board(overlay);
2126
2227 }