X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=manager%2Fcontroller.cpp;fp=manager%2Fcontroller.cpp;h=dad6e44641df146c783c80065feb68d3f487abc7;hb=f91a915d6f64f9d35e867d26e8ddb9c1b1ab0c1e;hp=0000000000000000000000000000000000000000;hpb=b41b9981c516c746a075e96aeeb3d7914617c713;p=progcomp2012.git diff --git a/manager/controller.cpp b/manager/controller.cpp new file mode 100644 index 0000000..dad6e44 --- /dev/null +++ b/manager/controller.cpp @@ -0,0 +1,172 @@ +#include + +#include "stratego.h" + +#include "controller.h" + +using namespace std; + +/** + * Queries the AI program to setup its pieces + * @returns the result of the response + */ +Board::MovementResult Controller::Setup(const char * opponentName) +{ + int y; + switch (colour) + { + case Piece::RED: + assert(SendMessage("RED %s %d %d", opponentName, Board::theBoard.Width(), Board::theBoard.Height())); + y = 0; + + break; + case Piece::BLUE: + assert(SendMessage("BLUE %s %d %d", opponentName, Board::theBoard.Width(), Board::theBoard.Height())); + y = Board::theBoard.Height()-4; + + break; + case Piece::NONE: + case Piece::BOTH: + //Should never see this; + assert(false); + 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) + { + 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) + { + Piece::Type type = Piece::GetType(line[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; + if (usedUnits[type] > Piece::maxUnits[(int)type]) + { + fprintf(stderr, "Too many units of type %c\n", Piece::tokens[(int)(type)]); + return Board::BAD_RESPONSE; + } + + Board::theBoard.AddPiece(x, y+ii, type, colour); + } + } + } + + if (usedUnits[(int)Piece::FLAG] <= 0) + { + return Board::BAD_RESPONSE; //You need to include a flag! + } + + return Board::OK; +} + + +/** + * Queries the AI program to respond to a state of Board::theBoard + * @returns The result of the response and/or move if made + */ +Board::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)) + { + return Board::NO_MOVE; //AI did not respond. It will lose by default. + } + + int x; int y; string direction=""; + stringstream s(buffer); + s >> x; + s >> y; + + + s >> direction; + Board::Direction dir; + if (direction == "UP") + { + dir = Board::UP; + } + else if (direction == "DOWN") + { + dir = Board::DOWN; + } + else if (direction == "LEFT") + { + dir = Board::LEFT; + } + else if (direction == "RIGHT") + { + dir = Board::RIGHT; + } + else + { + fprintf(stderr, "BAD_RESPONSE \"%s\"\n", buffer.c_str()); + return Board::BAD_RESPONSE; //AI 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) + { + case Board::OK: + buffer += " OK"; + break; + case Board::VICTORY: + buffer += " FLAG"; + break; + case Board::KILLS: + buffer += " KILLS"; + break; + case Board::DIES: + buffer += " DIES"; + break; + case Board::BOTH_DIE: + buffer += " BOTHDIE"; + break; + default: + buffer += " ILLEGAL"; + break; + + } + + if (!Board::LegalResult(moveResult)) + return Board::OK; //HACK - Legal results returned! + else + return moveResult; + +} +