X-Git-Url: https://git.ucc.asn.au/?p=progcomp2012.git;a=blobdiff_plain;f=manager%2Fcontroller.cpp;h=e68c1dccc4ac7d5e26f49e6a06e59384a07db4c1;hp=dad6e44641df146c783c80065feb68d3f487abc7;hb=2120cc40abf9e3fd763c84a1e09b61064bb40be6;hpb=f91a915d6f64f9d35e867d26e8ddb9c1b1ab0c1e diff --git a/manager/controller.cpp b/manager/controller.cpp index dad6e44..e68c1dc 100644 --- a/manager/controller.cpp +++ b/manager/controller.cpp @@ -1,111 +1,96 @@ -#include - -#include "stratego.h" - #include "controller.h" +#include +#include "game.h" + using namespace std; /** - * Queries the AI program to setup its pieces - * @returns the result of the response + * Queries the player to setup their pieces + * */ -Board::MovementResult Controller::Setup(const char * opponentName) + +MovementResult Controller::Setup(const char * opponentName) { - int y; + string setup[4] = {"","","",""}; + MovementResult query = this->QuerySetup(opponentName, setup); + if (query != MovementResult::OK) + return query; + + + + int usedUnits[(int)(Piece::BOMB)]; + for (int ii = 0; ii <= (int)(Piece::BOMB); ++ii) + usedUnits[ii] = 0; + + int yStart = 0; switch (colour) { case Piece::RED: - assert(SendMessage("RED %s %d %d", opponentName, Board::theBoard.Width(), Board::theBoard.Height())); - y = 0; - + yStart = 0; break; case Piece::BLUE: - assert(SendMessage("BLUE %s %d %d", opponentName, Board::theBoard.Width(), Board::theBoard.Height())); - y = Board::theBoard.Height()-4; - + yStart = Game::theGame->theBoard.Height()-4; break; - case Piece::NONE: - case Piece::BOTH: - //Should never see this; - assert(false); + default: + return MovementResult::COLOUR_ERROR; break; } - int usedUnits[(int)(Piece::BOMB)]; - for (int ii = 0; ii <= (int)(Piece::BOMB); ++ii) - usedUnits[ii] = 0; - - //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. - - - - - for (int ii=0; ii < 4; ++ii) + for (int y = 0; y < 4; ++y) { - string line=""; - if (!GetMessage(line, 2.5)) - { - fprintf(stderr, "Timeout on setup\n"); - return Board::BAD_RESPONSE; - } - if ((int)(line.size()) != Board::theBoard.Width()) - { - fprintf(stderr, "Bad length of \"%s\" on setup\n", line.c_str()); - return Board::BAD_RESPONSE; - } - - for (int x = 0; x < (int)(line.size()); ++x) + if ((int)setup[y].length() != Game::theGame->theBoard.Width()) + return MovementResult::BAD_RESPONSE; + + for (int x = 0; x < Game::theGame->theBoard.Width(); ++x) { - Piece::Type type = Piece::GetType(line[x]); + Piece::Type type = Piece::GetType(setup[y][x]); if (type != Piece::NOTHING) { -//fprintf(stderr, "x y %d %d\n", x, y+ii); -// 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]); - /// 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)]); - - usedUnits[(int)(type)] += 1; + usedUnits[(int)(type)]++; if (usedUnits[type] > Piece::maxUnits[(int)type]) { - fprintf(stderr, "Too many units of type %c\n", Piece::tokens[(int)(type)]); - return Board::BAD_RESPONSE; + //fprintf(stderr, "Too many units of type %c\n", Piece::tokens[(int)(type)]); + return MovementResult::BAD_RESPONSE; } - - Board::theBoard.AddPiece(x, y+ii, type, colour); + Game::theGame->theBoard.AddPiece(x, yStart+y, type, colour); } - } + } } - if (usedUnits[(int)Piece::FLAG] <= 0) { - return Board::BAD_RESPONSE; //You need to include a flag! + return MovementResult::BAD_RESPONSE; //You need to include a flag! } - return Board::OK; + return MovementResult::OK; + } /** - * Queries the AI program to respond to a state of Board::theBoard + * Queries the player to respond to a state of Game::theGame->theBoard + * @param buffer String which is used to store the player's responses * @returns The result of the response and/or move if made */ -Board::MovementResult Controller::MakeMove(string & buffer) +MovementResult Controller::MakeMove(string & buffer) { - - if (!Running()) - return Board::NO_MOVE; //AI has quit - Board::theBoard.Print(output, colour); - - - - buffer.clear(); - if (!GetMessage(buffer,2)) + MovementResult query = this->QueryMove(buffer); + if (query != MovementResult::OK) + return query; + + if (buffer == "NO_MOVE") { - return Board::NO_MOVE; //AI did not respond. It will lose by default. + buffer += " OK"; + return MovementResult::OK; } - + if (buffer == "SURRENDER") + { + buffer += " OK"; + return MovementResult::SURRENDER; + } + int x; int y; string direction=""; stringstream s(buffer); s >> x; @@ -132,30 +117,40 @@ Board::MovementResult Controller::MakeMove(string & buffer) } else { - fprintf(stderr, "BAD_RESPONSE \"%s\"\n", buffer.c_str()); - return Board::BAD_RESPONSE; //AI gave bogus direction - it will lose by default. + //fprintf(stderr, "BAD_RESPONSE \"%s\"\n", buffer.c_str()); + return MovementResult::BAD_RESPONSE; //Player gave bogus direction - it will lose by default. } int multiplier = 1; if (s.peek() != EOF) s >> multiplier; - Board::MovementResult moveResult = Board::theBoard.MovePiece(x, y, dir, multiplier, colour); - switch (moveResult) + MovementResult moveResult = Game::theGame->theBoard.MovePiece(x, y, dir, multiplier, colour); + + s.clear(); s.str(""); + + //I stored the ranks in the wrong order; rank 1 is the marshal, 2 is the general etc... + //So I am reversing them in the output... great work + s << Piece::tokens[(int)(moveResult.attackerRank)] << " " << Piece::tokens[(int)(moveResult.defenderRank)]; + switch (moveResult.type) { - case Board::OK: + case MovementResult::OK: buffer += " OK"; break; - case Board::VICTORY: + case MovementResult::VICTORY: buffer += " FLAG"; break; - case Board::KILLS: - buffer += " KILLS"; + case MovementResult::KILLS: + buffer += " KILLS "; + buffer += s.str(); + break; - case Board::DIES: - buffer += " DIES"; + case MovementResult::DIES: + buffer += " DIES "; + buffer += s.str(); break; - case Board::BOTH_DIE: - buffer += " BOTHDIE"; + case MovementResult::BOTH_DIE: + buffer += " BOTHDIE "; + buffer += s.str(); break; default: buffer += " ILLEGAL"; @@ -163,10 +158,9 @@ Board::MovementResult Controller::MakeMove(string & buffer) } - if (!Board::LegalResult(moveResult)) - return Board::OK; //HACK - Legal results returned! + if (Game::theGame->allowIllegalMoves && !Board::LegalResult(moveResult)) + return MovementResult::OK; //HACK - Illegal results returned as legal! else return moveResult; } -