[FINAL RESULTS]
[progcomp2012.git] / agents / ramen / src / main.c
1 /*
2  * UCC 2012 Programming Competition Entry
3  * - "Ramen"
4  *
5  * By John Hodge [TPG]
6  */
7 #define ENABLE_DEBUG    0
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <regex.h>
12 #include "interface.h"
13
14 // === CONSTANTS ===
15 static const char *DIR_NAMES[] = {"INVL", "LEFT", "RIGHT", "UP", "DOWN"};
16
17 // === PROTOTYPES ===
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);
23
24 // === GLOBALS ===
25 regex_t gRegex_move;
26 regex_t gRegex_res;
27  int    giBoardWidth;
28  int    giBoardHeight;
29 char    *gaBoardState;
30
31 // === CODE ===
32 int main(int argc, char *argv[])
33 {
34         setbuf(stdin, NULL);
35         setbuf(stdout, NULL);
36
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);
41
42         {
43                  int    colour_id;
44                 char    colour[6];
45                 char    opponent[128];
46                 fscanf(stdin, "%s %s %i %i", colour, opponent, &giBoardWidth, &giBoardHeight);
47
48                 if( strcmp(colour, "RED") == 0 )
49                         colour_id = COLOUR_RED;
50                 else if( strcmp(colour, "BLUE") == 0 )
51                         colour_id = COLOUR_BLUE;
52                 else {
53                         fprintf(stderr, "Oops... nutty manager, colour = %s\n", colour);
54                         colour_id = COLOUR_RED;
55                 }
56
57                 DEBUG("colour=%i, opponent='%s', dims = %ix%i", colour_id, opponent, giBoardWidth, giBoardHeight);
58
59                 AI_Initialise(colour_id, opponent);
60         }
61         
62         gaBoardState = malloc(giBoardWidth*giBoardHeight);
63
64         for( ;; )
65         {
66                 tMove   mymove, opponent_move;
67                 char    line[32];
68
69 //              DEBUG("Waiting for move");
70                 ASSERT( fgets(line, sizeof(line), stdin) != NULL );
71 //              DEBUG("pm line = '%s'", line);
72
73                 if( strcmp(line, "\n") == 0 )
74                         continue ;
75
76                 if( strcmp(line, "START\n") == 0 )
77                 {
78 //                      DEBUG("New game");
79                         ReadBoardState(stdin, gaBoardState);
80                         // TODO: Check if this hasn't happened before
81                         opponent_move.x = 0;
82                         opponent_move.y = 0;
83                         opponent_move.dist = 0;
84                         opponent_move.dir = 0;
85                 }
86                 else if( strncmp(line, "QUIT", 4) == 0 )
87                 {
88                         // TODO: Result?
89                         break ;
90                 }
91                 else if( strcmp(line, "VICTORY_FLAG\n") == 0 )
92                 {
93                         // I win!
94                         break;
95                 }
96                 else
97                 {
98 //                      DEBUG("GetMove");
99                         GetMove(line, &opponent_move);
100 //                      DEBUG("Read board state");
101                         ReadBoardState(stdin, gaBoardState);
102                 }
103                 DEBUG("Opposing move %i,%i dir %i dist %i",
104                         opponent_move.x, opponent_move.y, opponent_move.dir, opponent_move.dist);
105
106                 // Silly opponent, you lost
107                 if( opponent_move.result == RESULT_VICTORY )
108                         break;
109
110                 // Determine move
111                 AI_HandleMove(0, &opponent_move);
112                 AI_DoMove(&mymove);
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);
115
116                 // Get result of the move
117                 ASSERT( fgets(line, sizeof(line), stdin) != NULL );
118 //              DEBUG("res line = '%s'", line);
119 //
120                 GetMove(line, &mymove);
121                 AI_HandleMove(1, &mymove);
122
123                 // I WON!
124                 if( mymove.result == RESULT_VICTORY )
125                         break;
126
127 //              DEBUG("Move over");
128         }
129
130         return 0;
131 }
132
133 void GetMove(char *line, tMove *Move)
134 {
135         regmatch_t      matches[1+5];
136
137         // regex (\d+) (\d+) ([A-Z]*)(?: (\d+))?
138         RunRegex(&gRegex_move, line, 1+5, matches, "Move line");
139
140         char *xstr = line + matches[1].rm_so;
141         char *ystr = line + matches[2].rm_so;
142         char *dirstr = line + matches[3].rm_so;
143
144         Move->x = atoi(xstr);
145         Move->y = atoi(ystr);
146 //      DEBUG("(%i,%i)", Move->x, Move->y);
147         // Direction
148              if( strncmp(dirstr, "UP",    2) == 0 )
149                 Move->dir = DIR_UP;
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;
156         else {
157                 fprintf(stderr, "Is the manager nuts? Dir = %.*s unk\n",
158                         matches[3].rm_eo + matches[3].rm_so, dirstr
159                         );
160                 fprintf(stderr, "line = '%s'\n", line);
161                 Move->dir = DIR_INVAL;
162         }
163         if( matches[4].rm_so >= 0 )
164                 Move->dist = atoi(line + matches[4].rm_so + 1);
165         else
166                 Move->dist = 1;
167         
168         // Outcome
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;
178         else
179         {
180                 regmatch_t res_matches[3+1];
181                 RunRegex(&gRegex_res, outcome, 3+1, res_matches, "Result portion");
182
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;
190                 else {
191                         fprintf(stderr, "Is the manager nuts? Result = %.*s\n",
192                                 res_matches[1].rm_eo + res_matches[1].rm_so, res_str
193                                );
194                         Move->result = RESULT_INVAL;
195                 }
196
197                 Move->attacker = *(outcome + res_matches[2].rm_so);
198                 Move->defender = *(outcome + res_matches[3].rm_so);
199         }
200 }
201
202 void ReadBoardState(FILE *stream, char *dest)
203 {
204         for( int i = 0; i < giBoardHeight; i ++ )
205         {
206                 char    tmp[giBoardWidth+2];
207                 fgets(tmp, sizeof(tmp), stream);
208                 DEBUG("BS %.*s", giBoardWidth, tmp);
209                 memcpy(dest+i*giBoardWidth, tmp, giBoardWidth);
210         }
211 }
212
213 int RunRegex(regex_t *regex, const char *string, int nMatches, regmatch_t *matches, const char *errorMessage)
214 {
215          int    ret;
216         
217         ret = regexec(regex, string, nMatches, matches, 0);
218         if( ret ) {
219                 size_t  len = regerror(ret, regex, NULL, 0);
220                 char    errorStr[len];
221                 regerror(ret, regex, errorStr, len);
222                 fprintf(stderr, "string = '%s'\n", string);
223                 fprintf(stderr, "%s\n%s", errorMessage, errorStr);
224                 exit(-1);
225         }
226         
227         return ret;
228 }
229
230 void CompileRegex(regex_t *regex, const char *pattern, int flags)
231 {
232          int    ret = regcomp(regex, pattern, flags);
233         if( ret ) {
234                 size_t  len = regerror(ret, regex, NULL, 0);
235                 char    errorStr[len];
236                 regerror(ret, regex, errorStr, len);
237                 fprintf(stderr, "Regex compilation failed - %s\n", errorStr);
238                 exit(-1);
239         }
240 }

UCC git Repository :: git.ucc.asn.au