X-Git-Url: https://git.ucc.asn.au/?p=progcomp2012.git;a=blobdiff_plain;f=manager%2Fstratego.cpp;h=f2df0ffc29719cda5a4e91b4e129580e4b2b5237;hp=871d3822510486ed3600a3a15d1e2b1fa767d76a;hb=7f7bc05439b70b3139086086608996de3c9ae2ed;hpb=2ab27eb698cfd57977cc9cc25edcbfbeb3b1b1ee diff --git a/manager/stratego.cpp b/manager/stratego.cpp index 871d382..f2df0ff 100644 --- a/manager/stratego.cpp +++ b/manager/stratego.cpp @@ -1,4 +1,4 @@ -#include "common.h" + #include "stratego.h" @@ -7,19 +7,18 @@ using namespace std; /** * Static variables */ -Board Board::theBoard(14,14); + //nothing, boulder, flag, spy, scout, miner, sergeant, lietenant, captain, major, colonel, general, marshal, bomb, error -char Piece::tokens[] = {'.','+','F','y','s','n','S','L','c','m','C','G','M','B','?'}; +char Piece::tokens[] = {'.','*','F','s','9','8','7','6','5','4','3','2','1','B','?'}; int Piece::maxUnits[] = {0,0,1,1,8,5,4,4,4,3,2,1,1,6,0}; -#ifdef GRAPHICS - Piece::TextureManager Piece::textures; -#endif //GRAPHICS + +Piece::TextureManager Piece::textures; + -#ifdef GRAPHICS Piece::TextureManager::~TextureManager() { @@ -42,7 +41,7 @@ Texture & Piece::TextureManager::operator[](const LUint & at) } return *(Array::operator[](at)); } -#endif //GRAPHICS + /** * Gets the type of a piece, based off a character token @@ -66,7 +65,7 @@ Piece::Type Piece::GetType(char fromToken) * @param newWidth - the width of the board * @param newHeight - the height of the board */ -Board::Board(int newWidth, int newHeight) : winner(Piece::NONE), width(newWidth), height(newHeight), board(NULL) +Board::Board(int newWidth, int newHeight) : winner(Piece::NONE), width(newWidth), height(newHeight), board(NULL), pieces() { board = new Piece**[width]; for (int x=0; x < width; ++x) @@ -93,7 +92,7 @@ Board::~Board() /** * Print textual representation of the board to a stream * @param stream - the stream to print information to - * @param reveal - Pieces matching this colour will have their identify revealed, other pieces will be shown as '#' or '*' for RED or BLUE respectively. + * @param reveal - Pieces matching this colour will have their identify revealed, other pieces will be shown as '#' */ void Board::Print(FILE * stream, const Piece::Colour & reveal) { @@ -108,26 +107,89 @@ void Board::Print(FILE * stream, const Piece::Colour & reveal) } else if (piece->colour != Piece::NONE && (piece->colour == reveal || reveal == Piece::BOTH)) { + fprintf(stream, "%c", Piece::tokens[piece->type]); + + } else { switch (piece->colour) { case Piece::RED: + case Piece::BLUE: fprintf(stream, "#"); + break; + case Piece::NONE: + fprintf(stream, "+"); + break; + case Piece::BOTH: + fprintf(stream, "$"); + break; + } + } + } + fprintf(stream, "\n"); + } + +} + +/** + * Print textual representation of the board to a stream + * @param stream - the stream to print information to + * @param reveal - Pieces matching this colour will have their identify revealed, other pieces will be shown as '#' + */ +void Board::PrintPretty(FILE * stream, const Piece::Colour & reveal) +{ + for (int y=0; y < height; ++y) + { + for (int x=0; x < width; ++x) + { + Piece * piece = board[x][y]; + if (piece == NULL) + { + fprintf(stream, "."); + } + else if (piece->colour != Piece::NONE && (piece->colour == reveal || reveal == Piece::BOTH)) + { + switch (piece->colour) + { + case Piece::RED: + fprintf(stream, "%c[%d;%d;%dm",0x1B,1,31,40); + break; + case Piece::BLUE: + fprintf(stream, "%c[%d;%d;%dm",0x1B,1,34,40); + break; + default: + break; + } + fprintf(stream, "%c", Piece::tokens[piece->type]); + + } + else + { + switch (piece->colour) + { + case Piece::RED: + fprintf(stream, "%c[%d;%d;%dm",0x1B,1,31,41); + break; case Piece::BLUE: - fprintf(stream, "*"); + fprintf(stream, "%c[%d;%d;%dm",0x1B,1,34,44); break; case Piece::NONE: - fprintf(stream, "+"); + fprintf(stream, "%c[%d;%d;%dm",0x1B,1,37,47); break; case Piece::BOTH: - fprintf(stream, "$"); //Should never see these! + //Should never see this + fprintf(stream, "%c[%d;%d;%dm",0x1B,1,33,43); break; - } + + } + fprintf(stream, "#"); + } + fprintf(stream, "%c[%d;%d;%dm",0x1B,0,7,0); } fprintf(stream, "\n"); } @@ -135,16 +197,18 @@ void Board::Print(FILE * stream, const Piece::Colour & reveal) } -#ifdef GRAPHICS + /** * Draw the board state to graphics * @param reveal - Pieces matching this colour will be revealed. All others will be shown as blank coloured squares. */ -void Board::Draw(const Piece::Colour & reveal) +void Board::Draw(const Piece::Colour & reveal, bool showRevealed) { if (!Graphics::Initialised()) { - Graphics::Initialise("Stratego", width*32, height*32); + fprintf(stderr, "ERROR - Board::Draw called whilst graphics disabled!!!\n"); + exit(EXIT_FAILURE); + } Graphics::ClearScreen(); @@ -159,7 +223,8 @@ void Board::Draw(const Piece::Colour & reveal) //Don't display anything } - else if (piece->colour != Piece::NONE && (piece->colour == reveal || reveal == Piece::BOTH)) + else if ((piece->colour != Piece::NONE && (piece->colour == reveal || reveal == Piece::BOTH)) + || (piece->beenRevealed && showRevealed)) { //Display the piece Piece::textures[(int)(piece->type)].DrawColour(x*32,y*32,0,1, Piece::GetGraphicsColour(piece->colour)); @@ -170,10 +235,10 @@ void Board::Draw(const Piece::Colour & reveal) switch (piece->colour) { case Piece::RED: - Piece::textures[(int)(Piece::BOULDER)].DrawColour(x*32,y*32,0,1, Piece::GetGraphicsColour(piece->colour)); + Piece::textures[(int)(Piece::NOTHING)].DrawColour(x*32,y*32,0,1, Piece::GetGraphicsColour(piece->colour)); break; case Piece::BLUE: - Piece::textures[(int)(Piece::BOULDER)].DrawColour(x*32,y*32,0,1, Piece::GetGraphicsColour(piece->colour)); + Piece::textures[(int)(Piece::NOTHING)].DrawColour(x*32,y*32,0,1, Piece::GetGraphicsColour(piece->colour)); break; case Piece::NONE: Piece::textures[(int)(Piece::BOULDER)].DrawColour(x*32,y*32,0,1, Piece::GetGraphicsColour(piece->colour)); @@ -189,7 +254,6 @@ void Board::Draw(const Piece::Colour & reveal) Graphics::UpdateScreen(); } -#endif //GRAPHICS /** * Adds a piece to the board @@ -206,6 +270,8 @@ bool Board::AddPiece(int x, int y, const Piece::Type & newType, const Piece::Col Piece * piece = new Piece(newType, newColour); board[x][y] = piece; + + pieces.push_back(piece); return true; } @@ -295,6 +361,9 @@ MovementResult Board::MovePiece(int x, int y, const Direction & direction, int m } else if (defender->colour != target->colour) { + defender->beenRevealed = true; + target->beenRevealed = true; + Piece::Type defenderType = defender->type; Piece::Type attackerType = target->type; @@ -311,7 +380,7 @@ MovementResult Board::MovePiece(int x, int y, const Direction & direction, int m { if (target->type == Piece::MINER) { - + RemovePiece(defender); delete defender; board[x][y] = NULL; board[x2][y2] = target; @@ -319,6 +388,8 @@ MovementResult Board::MovePiece(int x, int y, const Direction & direction, int m } else { + RemovePiece(defender); + RemovePiece(target); delete defender; delete target; board[x][y] = NULL; @@ -328,6 +399,7 @@ MovementResult Board::MovePiece(int x, int y, const Direction & direction, int m } else if (defender->type == Piece::MARSHAL && target->type == Piece::SPY) { + RemovePiece(defender); delete defender; board[x][y] = NULL; board[x2][y2] = target; @@ -335,6 +407,7 @@ MovementResult Board::MovePiece(int x, int y, const Direction & direction, int m } else if (target->operator > (*defender)) { + RemovePiece(defender); delete defender; board[x][y] = NULL; board[x2][y2] = target; @@ -342,6 +415,7 @@ MovementResult Board::MovePiece(int x, int y, const Direction & direction, int m } else if (target->operator==(*defender) && rand() % 2 == 0) { + RemovePiece(defender); delete defender; board[x][y] = NULL; board[x2][y2] = target; @@ -349,6 +423,7 @@ MovementResult Board::MovePiece(int x, int y, const Direction & direction, int m } else { + RemovePiece(target); delete target; board[x][y] = NULL; return MovementResult(MovementResult::DIES, attackerType, defenderType); @@ -361,5 +436,77 @@ MovementResult Board::MovePiece(int x, int y, const Direction & direction, int m return MovementResult(MovementResult::OK); } +/** + * Removes a piece from the board + * @param piece The piece to remove + * @returns true iff the piece actually existed + */ +bool Board::RemovePiece(Piece * piece) +{ + bool result = false; + for (int x = 0; x < width; ++x) + { + for (int y = 0; y < height; ++y) + { + if (board[x][y] == piece) + { + result = true; + board[x][y] = NULL; + } + } + } + + vector::iterator i = pieces.begin(); + while (i != pieces.end()) + { + if ((*i) == piece) + { + i = pieces.erase(i); + result = true; + continue; + } + ++i; + } + return result; +} + +/** + * Returns the total value of pieces belonging to colour + * @param colour the colour + * @returns the total value of pieces belonging to colour. + * (Redundant repetition <3) + */ +int Board::TotalPieceValue(const Piece::Colour & colour) const +{ + int result = 0; + for (vector::const_iterator i = pieces.begin(); i != pieces.end(); ++i) + { + if ((*i)->colour == colour || colour == Piece::BOTH) + { + result += (*i)->PieceValue(); + } + } + return result; +} + +/** + * Returns the total number of mobile pieces belonging to colour + * @param colour the colour + * @returns the total value of mobile pieces belonging to colour. + * (Redundant repetition <3) + */ +int Board::MobilePieces(const Piece::Colour & colour) const +{ + int result = 0; + for (vector::const_iterator i = pieces.begin(); i != pieces.end(); ++i) + { + if ((*i)->colour == colour || colour == Piece::BOTH) + { + if ((*i)->type <= Piece::MARSHAL && (*i)->type >= Piece::SPY) + result++; + } + } + return result; +}