Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
#include <iostream>
#include <exception>
#include <SFML/Graphics.hpp>
#include "Board.h"
#include "GlobalVariables.h"
#include "Shooter.h"
#define and &&
#define or ||
#define not !
using namespace std;
Board::Board()
{
}
Board::Board(int xx, int yy, int ww, int hh)
{
CreateNewBoard();
x = xx;
y = yy;
w = ww;
h = hh;
movesPerformed = 0;
winner = EMPTY;
}
Board::Board(Board* b)
{
CreateNewBoard();
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
this->board[i][j] = b->board[i][j];
}
}
this->x = b->x;
this->y = b->y;
this->w = b->w;
this->h = b->h;
this->movesPerformed = b->movesPerformed;
this->winner = b->winner;
}
Board::~Board()
{
}
void Board::ProcessMouseEvent()
{
//std::cout << "Board.ProcessMouseEvent() not yet implemented\n";
//no need to update this board if the mouse is not in bounds or the board is full
if (mouseX < x || mouseY < y || mouseX > x + w || mouseY > y + h || movesPerformed == 9)
{
return;
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
//only have to process less-than since it checks in increasing order
//also, only have to check one because the mouse can only click once per turn
if (mouseX < x + w * (i + 1) / 3 && mouseY < y + h * (j + 1) / 3)
{
if (board[i][j] == EMPTY)
{
board[i][j] = (playerOnesTurn ? PLAYER1 : PLAYER2);
playerOnesTurn = !playerOnesTurn;
movesPerformed++;
CheckForWin();
}
return;
}
}
}
}
void Board::Draw()
{
if (movesPerformed < 9)
{
DrawLines();
DrawPieces();
}
else
{
DrawWinner();
}
}
int Board::GetWinner()
{
return winner;
}
void Board::DrawLines()
{
//the rectangle defining the verticle lines
sf::Vector2f vertLinesSize(lineThickness, h - 2 * distanceFromEdges);
sf::RectangleShape vertLine(vertLinesSize);
vertLine.setFillColor(lineColor);
vertLine.setOutlineColor(lineColor);
//set the position of each and draw it
vertLine.setPosition(x + w / 3, y + distanceFromEdges);
window.draw(vertLine);
vertLine.setPosition(x + w * 2 / 3, y + distanceFromEdges);
window.draw(vertLine);
//draw the horozontal lines
sf::Vector2f horzLinesSize(w - 2 * distanceFromEdges, lineThickness);
sf::RectangleShape horzLine(horzLinesSize);
horzLine.setFillColor(lineColor);
horzLine.setOutlineColor(lineColor);
//set the position of each and draw it
horzLine.setPosition(x + distanceFromEdges, y + h / 3);
window.draw(horzLine);
horzLine.setPosition(x + distanceFromEdges, y + h * 2 / 3);
window.draw(horzLine);
}
void Board::DrawWinner()
{
if (winner == PLAYER1)
{
DrawX(x, y, w, h);
}
else if (winner == PLAYER2)
{
DrawO(x, y, w, h);
}
else
{
throw new std::exception("ERROR: winner declared as an invalid type. This is a bug.");
//cout << "ERROR: winner declared as an invalid type. This is a bug.\nThere is normally an exception thrown here." << endl;
}
}
void Board::DrawX(int px, int py, int dx, int dy)
{
sf::Vector2f size(dx, dy / 3);
sf::RectangleShape tl2br(size); //top left to bottom right bar
sf::RectangleShape tr2bl(size); //top right to bottom left bar
//set the origin to the middle of the shape
tl2br.setOrigin(size.x / 2, size.y / 2);
tr2bl.setOrigin(size.x / 2, size.y / 2);
//set the colors
tl2br.setFillColor(xColor);
tr2bl.setFillColor(xColor);
//set the rotations
tl2br.setRotation(45);
tr2bl.setRotation(-45);
//position
tl2br.setPosition(px + dx / 2, py + dy / 2);
tr2bl.setPosition(px + dx / 2, py + dy / 2);
//draw
window.draw(tl2br);
window.draw(tr2bl);
}
void Board::DrawO(int px, int py, int dx, int dy)
{
sf::CircleShape shape(dx / 2);
shape.setFillColor(oColor);
sf::Vector2f pos(px, py);
shape.setPosition(pos);
window.draw(shape);
}
void Board::CreateNewBoard()
{
//empty it out just to be sure
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = EMPTY;//(i + j) % 2 + 1;//PLAYER1;
}
}
}
void Board::CheckForWin()
{
//no need to check if there haven't been enough moves
if (movesPerformed < 3)
return;
bool foundWin = false;
for (int i = PLAYER1; i <= PLAYER2; i++)
{
//rows
if (board[0][0] == i and board[0][1] == i and board[0][2] == i)
{
foundWin = true;
goto Board_CheckForWin_SkipFurtherChecking;
}
if (board[1][0] == i and board[1][1] == i and board[1][2] == i)
{
foundWin = true;
goto Board_CheckForWin_SkipFurtherChecking;
}
if (board[2][0] == i and board[2][1] == i and board[2][2] == i)
{
foundWin = true;
goto Board_CheckForWin_SkipFurtherChecking;
}
//columns
if (board[0][0] == i and board[1][0] == i and board[2][0] == i)
{
foundWin = true;
goto Board_CheckForWin_SkipFurtherChecking;
}
if (board[0][1] == i and board[1][1] == i and board[2][1] == i)
{
foundWin = true;
goto Board_CheckForWin_SkipFurtherChecking;
}
if (board[0][2] == i and board[1][2] == i and board[2][2] == i)
{
foundWin = true;
goto Board_CheckForWin_SkipFurtherChecking;
}
//diagonals
if (board[0][0] == i and board[1][1] == i and board[2][2] == i)
{
foundWin = true;
goto Board_CheckForWin_SkipFurtherChecking;
}
if (board[2][0] == i and board[1][1] == i and board[0][2] == i)
{
foundWin = true;
//no need for the goto since it goes to the right line anyway
}
//resolve the checks
Board_CheckForWin_SkipFurtherChecking:
if (foundWin)
{
winner = i;
movesPerformed = 9; //setting this to 9 closes off the board to other moves
return;
}
}
//if it exits the loop but 9 moves were performed, it is a cats-game.
if (movesPerformed == 9)
{
/*
CreateNewBoard();
movesPerformed = 0;
*/
contestedBoard = this;
states->PushState(new Shooter());
return;
}
}
void Board::DrawPieces()
{
//Draw the x's and o's
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
int piece = board[i][j];
if (piece == EMPTY)
{
continue; //no need to draw anything for this, move on to the next one
}
else
{
//Determine the size and location of the token
int px = x + i * w / 3;
int py = y + j * h / 3;
int dx = w / 3;
int dy = h / 3;
//draw the correct shape
if (piece == PLAYER1)
{
DrawX(px, py, dx, dy);
}
else if (piece == PLAYER2)
{
DrawO(px, py, dx, dy);
}
else
{
throw new std::exception("ERROR: invalid piece in the game board");
}
}
}
}
}
void Board::SetWinner(int player)
{
movesPerformed = 9;
winner = player;
}