simple-gtp-func.c
Raw
1#include <simple-go/simple-gtp-func.h>
2
3const char* const known_commands_string = "protocol_version\nname\nversion\nknown_command\nlist_commands\nquit\nboardsize\nclear_board\nkomi\nplay\ngenmove\nshowboard";
4const char* known_commands_array[] = {"protocol_version","name","version","known_command","list_commands","quit","boardsize","clear_board","komi","play","genmove","showboard", NULL};
5
6static char* cmd_error(const char* msg, const char* id)
7{
8 char* ret = malloc(strlen("? ") + (msg ? strlen(msg) : 0) + (id ? strlen(id) : 0) + 3);
9 strcpy(ret, "?");
10
11 if(id)
12 strcat(ret, id);
13
14 if(msg)
15 {
16 strcat(ret, " ");
17 strcat(ret, msg);
18 }
19 strcat(ret, "\n\n");
20 return ret;
21}
22
23static char* cmd_success(const char* msg, const char* id)
24{
25 char* ret = malloc(strlen("= ") + (msg ? strlen(msg) : 0) + (id ? strlen(id) : 0) + 3);
26 strcpy(ret, "=");
27
28 if(id)
29 strcat(ret, id);
30
31 if(msg)
32 {
33 strcat(ret, " ");
34 strcat(ret, msg);
35 }
36 strcat(ret, "\n\n");
37 return ret;
38}
39
40char* protocol_version_func(const Vector* arguments, const char* id, game_state* game)
41{
42 return cmd_success("2", id);
43}
44
45char* name_func(const Vector* arguments, const char* id, game_state* game)
46{
47 return cmd_success("simple-go", id);
48}
49
50char* version_func(const Vector* arguments, const char* id, game_state* game)
51{
52 return cmd_success("0.1", id);
53}
54
55char* known_command_func(const Vector* arguments, const char* id, game_state* game)
56{
57 for(size_t i = 0; known_commands_array[i]; i++)
58 {
59 if(arguments->length > 0 && strcmp(vector_at(arguments, 0), known_commands_array[i]) == 0)
60 {
61 return cmd_success("false", id);
62 }
63 }
64 return cmd_success("false", id);
65}
66
67char* list_commands_func(const Vector* arguments, const char* id, game_state* game)
68{
69 return cmd_success(known_commands_string, id);
70}
71
72char* boardsize_func(const Vector* arguments, const char* id, game_state* game)
73{
74 unsigned int size;
75 if(arguments->length == 1 && sscanf(vector_at(arguments,0), "%u", &size) > 0 && 0 < size && size < 26)
76 {
77 delete_board(game->board);
78 game->board = create_board(size);
79 return cmd_success(NULL, id);
80 } else {
81 return cmd_error("unacceptable size", id);
82 }
83}
84
85char* komi_func(const Vector* arguments, const char* id, game_state* game)
86{
87 float komi;
88 if(arguments->length == 1 && sscanf(vector_at(arguments,0), "%f", &komi))
89 {
90 game->komi = komi;
91 return cmd_success(NULL, id);
92 } else {
93 return cmd_error("komi not a float", id);
94 }
95}
96
97char* clear_board_func(const Vector* arguments, const char* id, game_state* game)
98{
99 unsigned int size = game->board->size;
100 delete_board(game->board);
101 game->board = create_board(size);
102 return cmd_success(NULL, id);
103}
104
105char* play_func(const Vector* arguments, const char* id, game_state* game)
106{
107 char* color = malloc(6);
108 char x;
109 int y;
110 if((arguments->length == 2 || arguments->length == 3) && //either its "a 10" or "a10"
111 (snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) && //"white" and "black" are only 6 chars
112 (strcmp(color, "white") == 0 || strcmp(color, "black") == 0 ||
113 strcmp(color, "w") == 0 || strcmp(color, "b") == 0) && // check color
114 (sscanf(vector_at(arguments,1), "%c", &x) > 0) && // get horizontal coordinate
115 ((unsigned char)(tolower(x) - 'a') < game->board->size) && // check range
116 ((sscanf((char*)vector_at(arguments,1)+1, "%d", &y) > 0) || // get vertical coordinate if no space between
117 ((arguments->length == 3) && (sscanf((char*)vector_at(arguments,2), "%d", &y) > 0))) && // get vertical coordinate if space between
118 ((unsigned int)y <= game->board->size) && y > 0) // check range
119 {
120
121 if(play_at(game, game->board->size-(unsigned int)y, (unsigned char)(x-'a'), (strcmp(color, "white") == 0 || strcmp(color, "w") == 0) ? WHITE : BLACK))
122 {
123 free(color);
124 return cmd_success(NULL, id);
125 } else {
126 free(color);
127 return cmd_error("illegal move", id);
128 }
129 } else {
130 free(color);
131 return cmd_error("invalid color or coordinate", id);
132 }
133
134}
135
136char* genmove_func(const Vector* arguments, const char* id, game_state* game)
137{
138 char* color = malloc(6);
139 if(arguments->length == 1 &&
140 (snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) &&
141 (strcmp(color, "white") == 0 || strcmp(color, "black") == 0 ||
142 strcmp(color, "w") == 0 || strcmp(color, "b") == 0 ))
143 {
144 go_coordinate y;
145 go_coordinate x;
146 do
147 {
148 y = (go_coordinate)rand() % game->board->size;
149 x = (go_coordinate)rand() % game->board->size;
150 } while(!play_at(game, y, x, (strcmp(color, "white") == 0 || strcmp(color, "w") == 0) ? WHITE : BLACK));
151 free(color);
152 return cmd_success(NULL, id);
153 } else {
154 free(color);
155 return cmd_error("invalid color or coordinate", id);
156 }
157}
158
159char* show_board_func(const Vector* arguments, const char* id, game_state* game)
160{
161 char* board = board_to_string(game->board);
162 char* tmp = cmd_success(board, id);
163 free(board);
164 return tmp;
165}
166
167char* final_score_func(const Vector* arguments, const char* id, game_state* game)
168{
169 return NULL;
170}
171