simple-gtp.c
Raw
1#include "simple-gtp.h"
2
3char* 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
11char* 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
19const char* const known_commands_string = "protocol_version\nname\nversion\nknown_command\nlist_commands\nquit\nboardsize\nclear_board\nkomi\nplay\ngenmove\nshowboard";
20const char* known_commands_array[] = {"protocol_version","name","version","known_command","list_commands","quit","boardsize","clear_board","komi","play","genmove","showboard"};
21int cmd_count = sizeof(known_commands_array)/sizeof(known_commands_array[0]);
22
23char* 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 if(arguments->length > 1)
52 vector_remove(arguments,0,free);
53
54 char* (*func_ptr)(const char*) = cmd_error;
55 const char* func_args = "unknown command";
56
57 if(strcmp(command, "protocol_version") == 0)
58 {
59 func_ptr = cmd_success;
60 func_args = "2";
61 } else if(strcmp(command, "name") == 0) {
62 func_ptr = cmd_success;
63 func_args = "simple-go";
64 } else if(strcmp(command, "version") == 0) {
65 func_ptr = cmd_success;
66 func_args = "0.1";
67 } else if(strcmp(command, "known_command") == 0) {
68 func_ptr = cmd_success;
69 func_args = "false";
70 for(int i = 0; i < cmd_count; i++)
71 {
72 if(arguments->length > 0 && strcmp(vector_at(arguments, 0), known_commands_array[i]) == 0)
73 {
74 func_args = "true";
75 break;
76 }
77 }
78 } else if(strcmp(command, "list_commands") == 0) {
79 func_ptr = cmd_success;
80 func_args = known_commands_string;
81 } else if(strcmp(command, "boardsize") == 0) {
82 unsigned int size;
83 if(arguments->length == 1 && sscanf(vector_at(arguments,0), "%u", &size) > 0 && 0 < size && size < 26)
84 {
85 func_ptr = cmd_success;
86 func_args = "";
87 delete_board(game->board);
88 game->board = create_board(size);
89 } else {
90 func_ptr = cmd_error;
91 func_args = "unacceptable size";
92 }
93 } else if(strcmp(command, "komi") == 0) {
94 float komi;
95 if(arguments->length == 1 && sscanf(vector_at(arguments,0), "%f", &komi))
96 {
97 func_ptr = cmd_success;
98 func_args = "";
99 game->komi = komi;
100 } else {
101 func_ptr = cmd_error;
102 func_args = "komi not a float";
103 }
104 } else if(strcmp(command, "clear_board") == 0) {
105 unsigned int size = game->board->size;
106 delete_board(game->board);
107 game->board = create_board(size);
108 } else if(strcmp(command, "play") == 0) {
109 char* color = malloc(6);
110 char y;
111 int x;
112 if((arguments->length == 2 || arguments->length == 3) &&
113 (snprintf(color, 6, "%s", (char*)vector_at(arguments,0)) > 0) &&
114 (strcmp(color, "white") == 0 || strcmp(color, "black") == 0) &&
115 (sscanf(vector_at(arguments,1), "%c", &y) > 0) &&
116 ((unsigned char)(tolower(y) - 'a') < game->board->size) &&
117 (sscanf((char*)vector_at(arguments,1)+1, "%d", &x) > 0) &&
118 ((unsigned int)x <= game->board->size) && (unsigned int)x > 0)
119 {
120 if(play_at(game, (unsigned char)(y-'a'), (unsigned int)x-1))
121 {
122 func_ptr = cmd_success;
123 func_args = "";
124 } else {
125 func_ptr = cmd_error;
126 func_args = "illegal move";
127 }
128 } else {
129 func_ptr = cmd_error;
130 func_args = "invalid color or coordinate";
131 }
132 free(color);
133 } else if(strcmp(command, "genmove") == 0) {
134 unsigned int y;
135 unsigned int x;
136 do
137 {
138 y = (unsigned int)rand() % game->board->size;
139 x = (unsigned int)rand() % game->board->size;
140 } while(!play_at(game, y, x));
141
142 }
143
144 free(command);
145 delete_vector(arguments, free);
146 free(tmp_msg);
147
148 return func_ptr(func_args);
149}
150