X-Git-Url: https://git.ucc.asn.au/?p=progcomp2012.git;a=blobdiff_plain;f=manager%2Fmain.cpp;h=44f8fd3de574e939aee6c8b77fd25d045e4a9a18;hp=96569eb58c0ecf27a023308f7a3f6acabbc9c379;hb=2120cc40abf9e3fd763c84a1e09b61064bb40be6;hpb=f91a915d6f64f9d35e867d26e8ddb9c1b1ab0c1e diff --git a/manager/main.cpp b/manager/main.cpp index 96569eb..44f8fd3 100644 --- a/manager/main.cpp +++ b/manager/main.cpp @@ -1,224 +1,272 @@ #include #include -#include "common.h" -#include "controller.h" -#include "stratego.h" -using namespace std; -#define theBoard Board::theBoard +#include "game.h" -#ifdef GRAPHICS - bool CheckForQuitWhilstWaiting(int wait); -#endif //GRAPHICS +using namespace std; -Controller * red; -Controller * blue; +Piece::Colour SetupGame(int argc, char ** argv); +void DestroyGame(); +void PrintResults(const MovementResult & result, string & buffer); -void cleanup(); int main(int argc, char ** argv) { - assert(argc == 3); - for (int y = 5; y < 9; ++y) - { - for (int x = 3; x < 5; ++x) - { - theBoard.AddPiece(x,y,Piece::BOULDER, Piece::NONE); - } - for (int x = 9; x < 11; ++x) - { - theBoard.AddPiece(x,y,Piece::BOULDER, Piece::NONE); - } - } - red = new Controller(Piece::RED, argv[1]); - blue = new Controller(Piece::BLUE, argv[2]); - atexit(cleanup); - Board::MovementResult redSetup = red->Setup(argv[2]); - Board::MovementResult blueSetup = blue->Setup(argv[1]); - if (redSetup != Board::OK) + if (argc == 1) { - fprintf(stderr, "Blue wins by DEFAULT!\n"); - red->SendMessage("ILLEGAL"); - blue->SendMessage("DEFAULT"); + fprintf(stderr, "Usage: stratego [options] red blue\n"); + fprintf(stderr, " stratego --help\n"); exit(EXIT_SUCCESS); + } - if (blueSetup != Board::OK) + + + Piece::Colour setupError = SetupGame(argc, argv); + MovementResult result = MovementResult::OK; + if (setupError == Piece::NONE) { - fprintf(stderr, "Red wins by DEFAULT!\n"); - red->SendMessage("DEFAULT"); - blue->SendMessage("ILLEGAL"); - exit(EXIT_SUCCESS); + result = Game::theGame->Play(); } + else + { + result = MovementResult::BAD_SETUP; + Game::theGame->ForceTurn(setupError); + } + + Game::theGame->PrintEndMessage(result); - Board::MovementResult result = Board::OK; - system("clear"); - int count = 1; + string buffer = ""; + PrintResults(result, buffer); - #ifdef GRAPHICS - if (!Graphics::Initialised()) - Graphics::Initialise("Stratego", theBoard.Width()*32, theBoard.Height()*32); - - #endif //GRAPHICS + //Message the AI's the quit message + Game::theGame->red->Message("QUIT " + buffer); + Game::theGame->blue->Message("QUIT " + buffer); - string buffer; + //Log the message + if (Game::theGame->GetLogFile() != stdout) + Game::theGame->logMessage("%s\n", buffer.c_str()); - red->SendMessage("START"); - Colour turn = Piece::RED; - while (Board::LegalResult(result)) - { + fprintf(stdout, "%s\n", buffer.c_str()); - fprintf(stderr, "This is move %d...\n", count); - fprintf(stderr,"---RED's turn---\n"); - turn = Piece::RED; - result = red->MakeMove(buffer); - red->SendMessage(buffer); - blue->SendMessage(buffer); + exit(EXIT_SUCCESS); + return 0; +} - if (!Board::LegalResult(result)) - break; - #ifdef GRAPHICS - Board::theBoard.Draw(); - if (CheckForQuitWhilstWaiting(0.2)) +Piece::Colour SetupGame(int argc, char ** argv) +{ + char * red = NULL; char * blue = NULL; double timeout = 0.00001; bool graphics = false; bool allowIllegal = false; FILE * log = NULL; + Piece::Colour reveal = Piece::BOTH; char * inputFile = NULL; int maxTurns = 5000; bool printBoard = false; + for (int ii=1; ii < argc; ++ii) + { + if (argv[ii][0] == '-') + { + switch (argv[ii][1]) { - red->SendMessage("QUIT"); - blue->SendMessage("QUIT"); - exit(EXIT_SUCCESS); - } - #endif //GRAPHICS - fprintf(stderr,"---BLUE's turn---\n"); - turn = Piece::BLUE; - result = blue->MakeMove(buffer); - blue->SendMessage(buffer); - red->SendMessage(buffer); - - if (!Board::LegalResult(result)) - break; - - + case 't': + if (argc - ii <= 1) + { + fprintf(stderr, "ARGUMENT_ERROR - Expected timeout value after -t switch!\n"); + exit(EXIT_FAILURE); + } + timeout = atof(argv[ii+1]); + ++ii; + break; + case 'g': + graphics = !graphics; + break; + case 'p': + printBoard = !printBoard; + break; + case 'i': + allowIllegal = !allowIllegal; + break; - #ifdef GRAPHICS - Board::theBoard.Draw(); - if (CheckForQuitWhilstWaiting(0.2)) + case 'o': + if (argc - ii <= 1) + { + fprintf(stderr, "ARGUMENT_ERROR - Expected filename or \"stdout\" after -o switch!\n"); + exit(EXIT_FAILURE); + } + if (log != NULL) + { + fprintf(stderr, "ARGUMENT_ERROR - Expected at most ONE -o switch!\n"); + exit(EXIT_FAILURE); + } + if (strcmp(argv[ii+1], "stdout") == 0) + log = stdout; + else + log = fopen(argv[ii+1], "w"); + setbuf(log, NULL); + + ++ii; + break; + + case 'r': + if (reveal == Piece::BOTH) + reveal = Piece::BLUE; + else + reveal = Piece::NONE; + break; + case 'b': + if (reveal == Piece::BOTH) + reveal = Piece::RED; + else + reveal = Piece::NONE; + break; + case 'm': + if (argc - ii <= 1) + { + fprintf(stderr, "ARGUMENT_ERROR - Expected max_turns value after -m switch!\n"); + exit(EXIT_FAILURE); + } + if (strcmp(argv[ii+1], "inf") == 0) + maxTurns = -1; + else + maxTurns = atoi(argv[ii+1]); + ++ii; + break; + case 'f': + if (argc - ii <= 1) + { + fprintf(stderr, "ARGUMENT_ERROR - Expected filename after -f switch!\n"); + exit(EXIT_FAILURE); + } + if (log != NULL) + { + fprintf(stderr, "ARGUMENT_ERROR - Expected at most ONE -f switch!\n"); + exit(EXIT_FAILURE); + } + red = (char*)("file"); + blue = (char*)("file"); + inputFile = argv[ii+1]; + ++ii; + break; + case 'h': + system("clear"); + system("less manual.txt"); + exit(EXIT_SUCCESS); + break; + case '-': + if (strcmp(argv[ii]+2, "help") == 0) + { + system("clear"); + system("less manual.txt"); + exit(EXIT_SUCCESS); + } + else + { + fprintf(stderr, "ARGUMENT_ERROR - Unrecognised switch \"%s\"...\n", argv[ii]); + exit(EXIT_FAILURE); + } + } + + } + else + { + if (red == NULL) + red = argv[ii]; + else if (blue == NULL) + blue = argv[ii]; + else { - red->SendMessage("QUIT"); - blue->SendMessage("QUIT"); - exit(EXIT_SUCCESS); + fprintf(stderr, "ARGUMENT_ERROR - Unexpected argument \"%s\"...\n", argv[ii]); + exit(EXIT_FAILURE); } - #else - Board::theBoard.Print(stderr); - sleep(1); - system("clear"); - #endif //GRAPHICS - - ++count; + } } - printf("Final board state\n"); - #ifdef GRAPHICS - Board::theBoard.Draw(); - if (CheckForQuitWhilstWaiting(4)) - { - red->SendMessage("QUIT"); - blue->SendMessage("QUIT"); - exit(EXIT_SUCCESS); - } - #else - Board::theBoard.Print(stderr); - #endif //GRAPHICS - sleep(2); - if (turn == Piece::RED) + if (inputFile == NULL) { - fprintf(stderr,"Game ends on RED's turn - REASON: "); + if (red == NULL || blue == NULL) //Not enough arguments + { + fprintf(stderr, "ARGUMENT_ERROR - Did not recieve enough players (did you mean to use the -f switch?)\n"); + exit(EXIT_FAILURE); + } + Game::theGame = new Game(red,blue, graphics, timeout, allowIllegal,log, reveal,maxTurns, printBoard); } - else if (turn == Piece::BLUE) + else { - fprintf(stderr,"Game ends on BLUE's turn - REASON: "); + Game::theGame = new Game(inputFile, graphics, timeout, allowIllegal,log, reveal,maxTurns, printBoard); } - else + + if (Game::theGame == NULL) { - fprintf(stderr,"Game ends on ERROR's turn - REASON: "); - + fprintf(stderr,"INTERNAL_ERROR - Error creating Game!\n"); + exit(EXIT_FAILURE); } - switch (result) + atexit(DestroyGame); + + return Game::theGame->Setup(red, blue); + + +} + +void PrintResults(const MovementResult & result, string & buffer) +{ + stringstream s(""); + switch (Game::theGame->Turn()) { - case Board::NO_BOARD: - fprintf(stderr,"Board does not exit?!\n"); - break; - case Board::INVALID_POSITION: - fprintf(stderr,"Coords outside board\n"); - break; - case Board::NO_SELECTION: - fprintf(stderr,"Move does not select a piece\n"); - break; - case Board::NOT_YOUR_UNIT: - fprintf(stderr,"Selected piece belongs to other player\n"); - break; - case Board::IMMOBILE_UNIT: - fprintf(stderr,"Selected piece is not mobile (FLAG or BOMB)\n"); - break; - case Board::INVALID_DIRECTION: - fprintf(stderr,"Selected unit cannot move that way\n"); - break; - case Board::POSITION_FULL: - fprintf(stderr,"Attempted move into square occupied by allied piece\n"); + case Piece::RED: + s << Game::theGame->red->name << " RED "; break; - case Board::VICTORY: - fprintf(stderr,"Captured the flag\n"); + case Piece::BLUE: + s << Game::theGame->blue->name << " BLUE "; break; - case Board::BAD_RESPONSE: - fprintf(stderr,"Unintelligable response\n"); + case Piece::BOTH: + s << "neither BOTH "; break; - case Board::NO_MOVE: - fprintf(stderr,"Did not make a move (may have exited)\n"); + case Piece::NONE: + s << "neither NONE "; break; } - - - exit(EXIT_SUCCESS); - - return 0; -} - -#ifdef GRAPHICS - -bool CheckForQuitWhilstWaiting(int wait) -{ - - - TimerThread timer(wait*1000000); //Wait in seconds - timer.Start(); - while (!timer.Finished()) + if (!Board::LegalResult(result) && result != MovementResult::BAD_SETUP) + s << "ILLEGAL "; + else if (!Board::HaltResult(result)) + s << "INTERNAL_ERROR "; + else { - SDL_Event event; - while (SDL_PollEvent(&event)) + switch (result.type) { - switch (event.type) - { - case SDL_QUIT: - timer.Stop(); - return true; - break; - } + case MovementResult::VICTORY: + s << "VICTORY "; + break; + case MovementResult::SURRENDER: + s << "SURRENDER "; + break; + case MovementResult::DRAW: + s << "DRAW "; + break; + case MovementResult::DRAW_DEFAULT: + s << "DRAW_DEFAULT "; + break; + case MovementResult::BAD_SETUP: + s << "BOTH_ILLEGAL "; + break; + default: + s << "INTERNAL_ERROR "; + break; } } - timer.Stop(); - return false; + + s << Game::theGame->TurnCount() << " " << Game::theGame->theBoard.TotalPieceValue(Piece::RED) << " " << Game::theGame->theBoard.TotalPieceValue(Piece::BLUE); + + buffer = s.str(); + + } -void cleanup() +void DestroyGame() { - delete red; - delete blue; + delete Game::theGame; + Game::theGame = NULL; } - -#endif //GRAPHICS