X-Git-Url: https://git.ucc.asn.au/?p=progcomp2012.git;a=blobdiff_plain;f=manager%2Fmain.cpp;h=01a7fab0a2a82a5a4d00ca431dcb843fb760e56e;hp=e3e435e6c5c764674617554d7e48e02c1e2d5b4a;hb=fe470c015d73d07c44f0e951a2bb205d95763f22;hpb=041c37d1dfc4a94024fe1d329d289e4c59667885;ds=sidebyside diff --git a/manager/main.cpp b/manager/main.cpp index e3e435e..01a7fab 100644 --- a/manager/main.cpp +++ b/manager/main.cpp @@ -1,265 +1,228 @@ #include #include -#include "common.h" -#include "controller.h" -#include "stratego.h" - -using namespace std; -#define theBoard Board::theBoard -#ifdef GRAPHICS - bool CheckForQuitWhilstWaiting(int wait); -#endif //GRAPHICS +#include "game.h" -Controller * red; -Controller * blue; -Colour turn; - -void cleanup(); +using namespace std; -void BrokenPipe(int sig); +void CreateGame(int argc, char ** argv); +void DestroyGame(); +void PrintResults(const MovementResult & result); int main(int argc, char ** argv) { - assert(argc == 3); - - - for (int y = 4; y < 6; ++y) - { - for (int x = 2; x < 4; ++x) - { - theBoard.AddPiece(x,y,Piece::BOULDER, Piece::NONE); - } - for (int x = 6; x < 8; ++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); - signal(SIGPIPE, BrokenPipe); - MovementResult redSetup = red->Setup(argv[2]); - MovementResult blueSetup = blue->Setup(argv[1]); - if (redSetup != MovementResult::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 != MovementResult::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); } - MovementResult result(MovementResult::OK); - system("clear"); - int count = 1; - - #ifdef GRAPHICS - if (!Graphics::Initialised()) - Graphics::Initialise("Stratego", theBoard.Width()*32, theBoard.Height()*32); - - #endif //GRAPHICS + MovementResult result = Game::theGame->Play(); + Game::theGame->PrintEndMessage(result); + PrintResults(result); - string buffer; + exit(EXIT_SUCCESS); + return 0; +} - red->SendMessage("START"); - 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) { - - - turn = Piece::RED; - fprintf(stderr, "%d RED: ", count); - result = red->MakeMove(buffer); - red->SendMessage(buffer); - blue->SendMessage(buffer); - fprintf(stderr, "%s\n", buffer.c_str()); - if (!Board::LegalResult(result)) - break; - #ifdef GRAPHICS - Board::theBoard.Draw(); - if (CheckForQuitWhilstWaiting(0.5)) + if (argv[ii][0] == '-') + { + switch (argv[ii][1]) { - red->SendMessage("QUIT"); - blue->SendMessage("QUIT"); - exit(EXIT_SUCCESS); - } - #endif //GRAPHICS - - turn = Piece::BLUE; - fprintf(stderr, "%d BLU: ", count); - result = blue->MakeMove(buffer); - blue->SendMessage(buffer); - red->SendMessage(buffer); - fprintf(stderr, "%s\n", buffer.c_str()); - - 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.5)) - { - 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.type) + if (!Game::theGame->Setup(red, blue)) { - case MovementResult::NO_BOARD: - fprintf(stderr,"Board does not exit?!\n"); - break; - case MovementResult::INVALID_POSITION: - fprintf(stderr,"Coords outside board\n"); - break; - case MovementResult::NO_SELECTION: - fprintf(stderr,"Move does not select a piece\n"); - break; - case MovementResult::NOT_YOUR_UNIT: - fprintf(stderr,"Selected piece belongs to other player\n"); - break; - case MovementResult::IMMOBILE_UNIT: - fprintf(stderr,"Selected piece is not mobile (FLAG or BOMB)\n"); - break; - case MovementResult::INVALID_DIRECTION: - fprintf(stderr,"Selected unit cannot move that way\n"); - break; - case MovementResult::POSITION_FULL: - fprintf(stderr,"Attempted move into square occupied by allied piece\n"); - break; - case MovementResult::VICTORY: - fprintf(stderr,"Captured the flag\n"); - break; - case MovementResult::BAD_RESPONSE: - fprintf(stderr,"Unintelligable response\n"); - break; - case MovementResult::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; -} + -void cleanup() -{ - delete red; - delete blue; + 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 BrokenPipe(int sig) +void DestroyGame() { - if (turn == Piece::RED) - { - fprintf(stderr,"Game ends on RED's turn - REASON: Broken pipe\n"); - blue->SendMessage("DEFAULT"); - } - else if (turn == Piece::BLUE) - { - fprintf(stderr,"Game ends on BLUE's turn - REASON: Broken pipe\n"); - red->SendMessage("DEFAULT"); - } - else - { - fprintf(stderr,"Game ends on ERROR's turn - REASON: Broken pipe\n"); - - } - Board::theBoard.Draw(); - while (true) - { - if (CheckForQuitWhilstWaiting(4000)) - { - red->SendMessage("QUIT"); - blue->SendMessage("QUIT"); - exit(EXIT_SUCCESS); - } - } - exit(EXIT_SUCCESS); + delete Game::theGame; + Game::theGame = NULL; } - -#endif //GRAPHICS