Improved -> Broke -> Fixed basic_python AI
[progcomp2012.git] / progcomp / judge / manager / controller.cpp
1 #include "controller.h"
2
3 #include <sstream>
4 #include "game.h"
5
6 using namespace std;
7
8 /**
9  * Queries the player to setup their pieces
10  *
11  */
12
13 MovementResult Controller::Setup(const char * opponentName)
14 {
15         string setup[4] = {"","","",""};
16         MovementResult query = this->QuerySetup(opponentName, setup);
17         if (query != MovementResult::OK)
18                 return query;
19
20         
21
22         int usedUnits[(int)(Piece::BOMB)];
23         for (int ii = 0; ii <= (int)(Piece::BOMB); ++ii)
24                 usedUnits[ii] = 0;
25
26         int yStart = 0;
27         switch (colour)
28         {
29                 case Piece::RED:
30                         yStart = 0;
31                         break;
32                 case Piece::BLUE:
33                         yStart = Game::theGame->theBoard.Height()-4;
34                         break;
35                 default:
36                         return MovementResult::COLOUR_ERROR; 
37                         break;
38         }
39
40
41         for (int y = 0; y < 4; ++y)
42         {
43                 if ((int)setup[y].length() != Game::theGame->theBoard.Width())
44                         return MovementResult::BAD_RESPONSE;
45
46                 for (int x = 0; x < Game::theGame->theBoard.Width(); ++x)
47                 {
48                         Piece::Type type = Piece::GetType(setup[y][x]);
49                         if (type != Piece::NOTHING)
50                         {
51                                 usedUnits[(int)(type)]++;
52                                 if (usedUnits[type] > Piece::maxUnits[(int)type])
53                                 {
54                                         //fprintf(stderr, "Too many units of type %c\n", Piece::tokens[(int)(type)]);
55                                         return MovementResult::BAD_RESPONSE;
56                                 }
57                                 Game::theGame->theBoard.AddPiece(x, yStart+y, type, colour);
58                         }
59                 }
60         }
61         if (usedUnits[(int)Piece::FLAG] <= 0)
62         {
63                 return MovementResult::BAD_RESPONSE; //You need to include a flag!
64         }
65
66         return MovementResult::OK;
67
68 }
69
70
71 /**
72  * Queries the player to respond to a state of Game::theGame->theBoard
73  * @param buffer String which is used to store the player's responses
74  * @returns The result of the response and/or move if made
75  */
76 MovementResult Controller::MakeMove(string & buffer)
77 {
78         buffer.clear();
79         MovementResult query = this->QueryMove(buffer);
80         if (query != MovementResult::OK)
81                 return query;
82
83         if (buffer == "NO_MOVE")
84         {
85                 buffer += " OK";
86                 return MovementResult::OK;
87         }
88         if (buffer == "SURRENDER")
89         {
90                 buffer += " OK";
91                 return MovementResult::SURRENDER;
92         }
93         
94         int x; int y; string direction="";
95         stringstream s(buffer);
96         s >> x;
97         s >> y;
98         
99
100         s >> direction;
101         Board::Direction dir;
102         if (direction == "UP")
103         {
104                 dir = Board::UP;
105         }
106         else if (direction == "DOWN")
107         {
108                 dir = Board::DOWN;
109         }
110         else if (direction == "LEFT")
111         {
112                 dir = Board::LEFT;
113         }
114         else if (direction == "RIGHT")
115         {
116                 dir = Board::RIGHT;
117         }       
118         else
119         {
120                 if (Game::theGame->allowIllegalMoves)
121                         return MovementResult::OK;
122                 else
123                         return MovementResult::BAD_RESPONSE; //Player gave bogus direction - it will lose by default.   
124         }
125
126         int multiplier = 1;
127         if (s.peek() != EOF)
128                 s >> multiplier;
129         MovementResult moveResult = Game::theGame->theBoard.MovePiece(x, y, dir, multiplier, colour);
130
131         s.clear();      s.str("");
132
133         //I stored the ranks in the wrong order; rank 1 is the marshal, 2 is the general etc...
134         //So I am reversing them in the output... great work
135         s << Piece::tokens[(int)(moveResult.attackerRank)] << " " << Piece::tokens[(int)(moveResult.defenderRank)];     
136         switch (moveResult.type)
137         {
138                 case MovementResult::OK:
139                         buffer += " OK";
140                         break;
141                 case MovementResult::VICTORY:
142                         buffer += " FLAG";
143                         break;
144                 case MovementResult::KILLS:
145                         buffer += " KILLS ";
146                         buffer += s.str();
147
148                         break;
149                 case MovementResult::DIES:
150                         buffer += " DIES ";
151                         buffer += s.str();
152                         break;
153                 case MovementResult::BOTH_DIE:
154                         buffer += " BOTHDIE ";
155                         buffer += s.str();
156                         break;  
157                 default:
158                         buffer += " ILLEGAL";
159                         break;                  
160                 
161         }
162
163         
164         if (!Board::LegalResult(moveResult))
165         {
166                 
167                 if (Game::theGame->allowIllegalMoves)
168                 {
169                         
170                         return MovementResult::OK; //HACK - Illegal results returned as legal! (Move not made)
171                 }
172                 else if (this->HumanController()) //Cut human controllers some slack and let them try again...
173                 {
174                         //Yes, checking type of object is "not the C++ way"
175                         //      But sometimes its bloody useful to know!!!
176                         Message("Bad move: \'" + buffer + "\' <- Please try again!");
177                         buffer = "";
178                         return this->MakeMove(buffer);
179                 }
180         }
181
182         return moveResult;      
183
184 }

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