2 * UCC 2012 Programming Competition Entry
12 #include "interface.h"
15 static const char *DIR_NAMES[] = {"INVL", "LEFT", "RIGHT", "UP", "DOWN"};
18 int main(int argc, char *argv[]);
19 void GetMove(char *line, tMove *Move);
20 void ReadBoardState(FILE *stream, char *dest);
21 int RunRegex(regex_t *regex, const char *string, int nMatches, regmatch_t *matches, const char *errorMessage);
22 void CompileRegex(regex_t *regex, const char *pattern, int flags);
32 int main(int argc, char *argv[])
37 // $X $Y $DIRECTION [$MULTIPLIER=1] $OUTCOME
38 CompileRegex(&gRegex_move, "([0-9]+) ([0-9]+) ([A-Z]+)( [0-9]+)? (.*)", REG_EXTENDED);
39 // (KILLS|DIES|BOTHDIE) $ATTACKER_RANK $DEFENDER_RANK
40 CompileRegex(&gRegex_res, "([A-Z_]+) (.) (.)", REG_EXTENDED);
46 fscanf(stdin, "%s %s %i %i", colour, opponent, &giBoardWidth, &giBoardHeight);
48 if( strcmp(colour, "RED") == 0 )
49 colour_id = COLOUR_RED;
50 else if( strcmp(colour, "BLUE") == 0 )
51 colour_id = COLOUR_BLUE;
53 fprintf(stderr, "Oops... nutty manager, colour = %s\n", colour);
54 colour_id = COLOUR_RED;
57 DEBUG("colour=%i, opponent='%s', dims = %ix%i", colour_id, opponent, giBoardWidth, giBoardHeight);
59 AI_Initialise(colour_id, opponent);
62 gaBoardState = malloc(giBoardWidth*giBoardHeight);
66 tMove mymove, opponent_move;
69 // DEBUG("Waiting for move");
70 ASSERT( fgets(line, sizeof(line), stdin) != NULL );
71 // DEBUG("pm line = '%s'", line);
73 if( strcmp(line, "\n") == 0 )
76 if( strcmp(line, "START\n") == 0 )
79 ReadBoardState(stdin, gaBoardState);
80 // TODO: Check if this hasn't happened before
83 opponent_move.dist = 0;
84 opponent_move.dir = 0;
86 else if( strncmp(line, "QUIT", 4) == 0 )
91 else if( strcmp(line, "VICTORY_FLAG\n") == 0 )
99 GetMove(line, &opponent_move);
100 // DEBUG("Read board state");
101 ReadBoardState(stdin, gaBoardState);
103 DEBUG("Opposing move %i,%i dir %i dist %i",
104 opponent_move.x, opponent_move.y, opponent_move.dir, opponent_move.dist);
106 // Silly opponent, you lost
107 if( opponent_move.result == RESULT_VICTORY )
111 AI_HandleMove(0, &opponent_move);
113 DEBUG("Chose move %i,%i %i %i", mymove.x, mymove.y, mymove.dir, mymove.dist);
114 printf("%i %i %s %i\n", mymove.x, mymove.y, DIR_NAMES[mymove.dir], mymove.dist);
116 // Get result of the move
117 ASSERT( fgets(line, sizeof(line), stdin) != NULL );
118 // DEBUG("res line = '%s'", line);
120 GetMove(line, &mymove);
121 AI_HandleMove(1, &mymove);
124 if( mymove.result == RESULT_VICTORY )
127 // DEBUG("Move over");
133 void GetMove(char *line, tMove *Move)
135 regmatch_t matches[1+5];
137 // regex (\d+) (\d+) ([A-Z]*)(?: (\d+))?
138 RunRegex(&gRegex_move, line, 1+5, matches, "Move line");
140 char *xstr = line + matches[1].rm_so;
141 char *ystr = line + matches[2].rm_so;
142 char *dirstr = line + matches[3].rm_so;
144 Move->x = atoi(xstr);
145 Move->y = atoi(ystr);
146 // DEBUG("(%i,%i)", Move->x, Move->y);
148 if( strncmp(dirstr, "UP", 2) == 0 )
150 else if( strncmp(dirstr, "DOWN", 4) == 0 )
151 Move->dir = DIR_DOWN;
152 else if( strncmp(dirstr, "LEFT", 4) == 0 )
153 Move->dir = DIR_LEFT;
154 else if( strncmp(dirstr, "RIGHT", 5) == 0 )
155 Move->dir = DIR_RIGHT;
157 fprintf(stderr, "Is the manager nuts? Dir = %.*s unk\n",
158 matches[3].rm_eo + matches[3].rm_so, dirstr
160 fprintf(stderr, "line = '%s'\n", line);
161 Move->dir = DIR_INVAL;
163 if( matches[4].rm_so >= 0 )
164 Move->dist = atoi(line + matches[4].rm_so + 1);
169 char *outcome = line + matches[5].rm_so;
170 if( strncmp(outcome, "OK", 2) == 0 )
171 Move->result = RESULT_OK;
172 else if( strncmp(outcome, "ILLEGAL", 7) == 0 )
173 Move->result = RESULT_ILLEGAL;
174 else if( strncmp(outcome, "VICTORY_FLAG", 12) == 0 )
175 Move->result = RESULT_VICTORY;
176 else if( strncmp(outcome, "VICTORY_ATTRITION", 17) == 0 )
177 Move->result = RESULT_VICTORY;
180 regmatch_t res_matches[3+1];
181 RunRegex(&gRegex_res, outcome, 3+1, res_matches, "Result portion");
183 char *res_str = outcome + res_matches[1].rm_so;
184 if( strncmp(res_str, "KILLS ", 6) == 0 )
185 Move->result = RESULT_KILL;
186 else if( strncmp(res_str, "DIES ", 5) == 0 )
187 Move->result = RESULT_DIES;
188 else if( strncmp(res_str, "BOTHDIE ", 8) == 0 )
189 Move->result = RESULT_BOTHDIE;
191 fprintf(stderr, "Is the manager nuts? Result = %.*s\n",
192 res_matches[1].rm_eo + res_matches[1].rm_so, res_str
194 Move->result = RESULT_INVAL;
197 Move->attacker = *(outcome + res_matches[2].rm_so);
198 Move->defender = *(outcome + res_matches[3].rm_so);
202 void ReadBoardState(FILE *stream, char *dest)
204 for( int i = 0; i < giBoardHeight; i ++ )
206 char tmp[giBoardWidth+2];
207 fgets(tmp, sizeof(tmp), stream);
208 DEBUG("BS %.*s", giBoardWidth, tmp);
209 memcpy(dest+i*giBoardWidth, tmp, giBoardWidth);
213 int RunRegex(regex_t *regex, const char *string, int nMatches, regmatch_t *matches, const char *errorMessage)
217 ret = regexec(regex, string, nMatches, matches, 0);
219 size_t len = regerror(ret, regex, NULL, 0);
221 regerror(ret, regex, errorStr, len);
222 fprintf(stderr, "string = '%s'\n", string);
223 fprintf(stderr, "%s\n%s", errorMessage, errorStr);
230 void CompileRegex(regex_t *regex, const char *pattern, int flags)
232 int ret = regcomp(regex, pattern, flags);
234 size_t len = regerror(ret, regex, NULL, 0);
236 regerror(ret, regex, errorStr, len);
237 fprintf(stderr, "Regex compilation failed - %s\n", errorStr);