5 #include "controller.h"
10 * Queries the AI program to setup its pieces
11 * @param opponentName - string containing the name/id of the opponent AI program
12 * @returns the result of the response
14 MovementResult Controller::Setup(const char * opponentName)
20 assert(SendMessage("RED %s %d %d", opponentName, Board::theBoard.Width(), Board::theBoard.Height()));
25 assert(SendMessage("BLUE %s %d %d", opponentName, Board::theBoard.Width(), Board::theBoard.Height()));
26 y = Board::theBoard.Height()-4;
31 //Should never see this;
37 int usedUnits[(int)(Piece::BOMB)];
38 for (int ii = 0; ii <= (int)(Piece::BOMB); ++ii)
41 //The setup is spread across 4 lines of the board - blue at the top, red at the bottom. AI has 2.5s for each line.
46 for (int ii=0; ii < 4; ++ii)
49 if (!GetMessage(line, 2.5))
51 fprintf(stderr, "Timeout on setup\n");
52 return MovementResult::BAD_RESPONSE;
54 if ((int)(line.size()) != Board::theBoard.Width())
56 fprintf(stderr, "Bad length of \"%s\" on setup\n", line.c_str());
57 return MovementResult::BAD_RESPONSE;
60 for (int x = 0; x < (int)(line.size()); ++x)
62 Piece::Type type = Piece::GetType(line[x]);
63 if (type != Piece::NOTHING)
65 //fprintf(stderr, "x y %d %d\n", x, y+ii);
66 // fprintf(stderr, "Found unit of type '%c' (%d '%c') %d vs %d\n", line[x], (int)(type), Piece::tokens[(int)(type)], usedUnits[(int)(type)], Piece::maxUnits[(int)type]);
67 /// fprintf(stderr, "Marshal is %d '%c', flag is %d '%c'\n", (int)Piece::MARSHAL, Piece::tokens[(int)(Piece::MARSHAL)], (int)Piece::FLAG, Piece::tokens[(int)(Piece::FLAG)]);
69 usedUnits[(int)(type)] += 1;
70 if (usedUnits[type] > Piece::maxUnits[(int)type])
72 fprintf(stderr, "Too many units of type %c\n", Piece::tokens[(int)(type)]);
73 return MovementResult::BAD_RESPONSE;
76 Board::theBoard.AddPiece(x, y+ii, type, colour);
81 if (usedUnits[(int)Piece::FLAG] <= 0)
83 return MovementResult::BAD_RESPONSE; //You need to include a flag!
86 return MovementResult::OK;
91 * Queries the AI program to respond to a state of Board::theBoard
92 * @returns The result of the response and/or move if made
94 MovementResult Controller::MakeMove(string & buffer)
98 return MovementResult::NO_MOVE; //AI has quit
99 Board::theBoard.Print(output, colour);
105 if (!GetMessage(buffer,2))
107 return MovementResult::NO_MOVE; //AI did not respond. It will lose by default.
110 int x; int y; string direction="";
111 stringstream s(buffer);
117 Board::Direction dir;
118 if (direction == "UP")
122 else if (direction == "DOWN")
126 else if (direction == "LEFT")
130 else if (direction == "RIGHT")
136 fprintf(stderr, "BAD_RESPONSE \"%s\"\n", buffer.c_str());
137 return MovementResult::BAD_RESPONSE; //AI gave bogus direction - it will lose by default.
143 MovementResult moveResult = Board::theBoard.MovePiece(x, y, dir, multiplier, colour);
145 s.clear(); s.str("");
147 //I stored the ranks in the wrong order; rank 1 is the marshal, 2 is the general etc...
148 //So I am reversing them in the output... great work
149 s << (Piece::BOMB - moveResult.attackerRank) << " " << (Piece::BOMB - moveResult.defenderRank) << "\n";
150 switch (moveResult.type)
152 case MovementResult::OK:
155 case MovementResult::VICTORY:
158 case MovementResult::KILLS:
163 case MovementResult::DIES:
167 case MovementResult::BOTH_DIE:
168 buffer += " BOTHDIE ";
172 buffer += " ILLEGAL";
177 if (!Board::LegalResult(moveResult))
178 return MovementResult::OK; //HACK - Legal results returned!