X-Git-Url: https://git.ucc.asn.au/?p=progcomp2012.git;a=blobdiff_plain;f=manager%2Fmain.cpp;h=01a7fab0a2a82a5a4d00ca431dcb843fb760e56e;hp=96569eb58c0ecf27a023308f7a3f6acabbc9c379;hb=fe470c015d73d07c44f0e951a2bb205d95763f22;hpb=f91a915d6f64f9d35e867d26e8ddb9c1b1ab0c1e diff --git a/manager/main.cpp b/manager/main.cpp index 96569eb..01a7fab 100644 --- a/manager/main.cpp +++ b/manager/main.cpp @@ -1,224 +1,228 @@ #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; +void CreateGame(int argc, char ** argv); +void DestroyGame(); +void PrintResults(const MovementResult & result); -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) + CreateGame(argc, argv); + if (Game::theGame == NULL) { - fprintf(stderr, "Red wins by DEFAULT!\n"); - red->SendMessage("DEFAULT"); - blue->SendMessage("ILLEGAL"); - exit(EXIT_SUCCESS); + fprintf(stderr, "ERROR: Couldn't create a game!\n"); + exit(EXIT_FAILURE); } - Board::MovementResult result = Board::OK; - system("clear"); - int count = 1; + MovementResult result = Game::theGame->Play(); + Game::theGame->PrintEndMessage(result); + PrintResults(result); - #ifdef GRAPHICS - if (!Graphics::Initialised()) - Graphics::Initialise("Stratego", theBoard.Width()*32, theBoard.Height()*32); - - #endif //GRAPHICS - - string buffer; + exit(EXIT_SUCCESS); + return 0; +} - red->SendMessage("START"); - Colour turn = Piece::RED; - while (Board::LegalResult(result)) +void CreateGame(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) { - - 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); - - if (!Board::LegalResult(result)) - break; - #ifdef GRAPHICS - Board::theBoard.Draw(); - if (CheckForQuitWhilstWaiting(0.2)) + 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, "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)) - { - red->SendMessage("QUIT"); - blue->SendMessage("QUIT"); - exit(EXIT_SUCCESS); + case 'o': + if (argc - ii <= 1) + { + fprintf(stderr, "Expected filename or \"stdout\" after -o switch!\n"); + exit(EXIT_FAILURE); + } + if (log != NULL) + { + fprintf(stderr, "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, "Expected max_turns value after -m switch!\n"); + exit(EXIT_FAILURE); + } + if (strcmp(argv[ii+1], "inf")) + maxTurns = -1; + else + maxTurns = atoi(argv[ii+1]); + ++ii; + break; + case 'f': + if (argc - ii <= 1) + { + fprintf(stderr, "Expected filename after -f switch!\n"); + exit(EXIT_FAILURE); + } + if (log != NULL) + { + fprintf(stderr, "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, "Unrecognised switch \"%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)) + + } + 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, "Unexpected argument \"%s\"...\n", argv[ii]); + exit(EXIT_FAILURE); } - #else - Board::theBoard.Print(stderr); - #endif //GRAPHICS - sleep(2); - - - if (turn == Piece::RED) - { - fprintf(stderr,"Game ends on RED's turn - REASON: "); + } } - else if (turn == Piece::BLUE) + + if (inputFile == NULL) { - fprintf(stderr,"Game ends on BLUE's turn - REASON: "); + Game::theGame = new Game(red,blue, graphics, timeout, allowIllegal,log, reveal,maxTurns, printBoard); } else { - fprintf(stderr,"Game ends on ERROR's turn - REASON: "); - + Game::theGame = new Game(inputFile, graphics, timeout, allowIllegal,log, reveal,maxTurns, printBoard); } - switch (result) + if (!Game::theGame->Setup(red, blue)) { - 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"); - break; - case Board::VICTORY: - fprintf(stderr,"Captured the flag\n"); - break; - case Board::BAD_RESPONSE: - fprintf(stderr,"Unintelligable response\n"); - break; - case Board::NO_MOVE: - fprintf(stderr,"Did not make a move (may have exited)\n"); - break; + fprintf(stdout, "NONE %d\n",Game::theGame->TurnCount()); + exit(EXIT_SUCCESS); } - - - - exit(EXIT_SUCCESS); - return 0; -} + atexit(DestroyGame); -#ifdef GRAPHICS +} -bool CheckForQuitWhilstWaiting(int wait) +void PrintResults(const MovementResult & result) { - - - TimerThread timer(wait*1000000); //Wait in seconds - timer.Start(); - while (!timer.Finished()) + Piece::Colour winner = Game::theGame->Turn(); + if (Board::LegalResult(result)) { - SDL_Event event; - while (SDL_PollEvent(&event)) + if (winner == Piece::BOTH) + winner = Piece::NONE; + else { - switch (event.type) - { - case SDL_QUIT: - timer.Stop(); - return true; - break; - } + if (winner == Piece::RED) + winner = Piece::BLUE; + else + winner = Piece::RED; } } - timer.Stop(); - return false; + + + switch (winner) + { + case Piece::RED: + fprintf(stdout, "%s RED %d\n", Game::theGame->red->name.c_str(),Game::theGame->TurnCount()); + Game::theGame->logMessage("%s RED %d\n", Game::theGame->red->name.c_str(),Game::theGame->TurnCount()); + break; + case Piece::BLUE: + fprintf(stdout, "%s BLUE %d\n", Game::theGame->blue->name.c_str(),Game::theGame->TurnCount()); + Game::theGame->logMessage("%s BLUE %d\n", Game::theGame->blue->name.c_str(),Game::theGame->TurnCount()); + break; + case Piece::BOTH: + fprintf(stdout, "DRAW %d\n",Game::theGame->TurnCount()); + Game::theGame->logMessage("DRAW %d\n",Game::theGame->TurnCount()); + break; + case Piece::NONE: + fprintf(stdout, "NONE %d\n",Game::theGame->TurnCount()); + Game::theGame->logMessage("NONE %d\n",Game::theGame->TurnCount()); + break; + + } } -void cleanup() +void DestroyGame() { - delete red; - delete blue; + delete Game::theGame; + Game::theGame = NULL; } - -#endif //GRAPHICS