-#include "common.h"
+
#include "stratego.h"
/**
* 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()
{
}
return *(Array<Texture*>::operator[](at));
}
-#endif //GRAPHICS
+
/**
* Gets the type of a piece, based off a character token
* @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)
/**
* 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)
{
}
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");
}
}
-#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();
//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));
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));
Graphics::UpdateScreen();
}
-#endif //GRAPHICS
/**
* Adds a piece to the board
Piece * piece = new Piece(newType, newColour);
board[x][y] = piece;
+
+ pieces.push_back(piece);
return true;
}
}
else if (defender->colour != target->colour)
{
+ defender->beenRevealed = true;
+ target->beenRevealed = true;
+
Piece::Type defenderType = defender->type;
Piece::Type attackerType = target->type;
{
if (target->type == Piece::MINER)
{
-
+ RemovePiece(defender);
delete defender;
board[x][y] = NULL;
board[x2][y2] = target;
}
else
{
+ RemovePiece(defender);
+ RemovePiece(target);
delete defender;
delete target;
board[x][y] = NULL;
}
else if (defender->type == Piece::MARSHAL && target->type == Piece::SPY)
{
+ RemovePiece(defender);
delete defender;
board[x][y] = NULL;
board[x2][y2] = target;
}
else if (target->operator > (*defender))
{
+ RemovePiece(defender);
delete defender;
board[x][y] = NULL;
board[x2][y2] = target;
}
else if (target->operator==(*defender) && rand() % 2 == 0)
{
+ RemovePiece(defender);
delete defender;
board[x][y] = NULL;
board[x2][y2] = target;
}
else
{
+ RemovePiece(target);
delete target;
board[x][y] = NULL;
return MovementResult(MovementResult::DIES, attackerType, defenderType);
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<Piece*>::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<Piece*>::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<Piece*>::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;
+}