diff --git a/.cproject b/.cproject
index e7c89fb..e0e395a 100644
--- a/.cproject
+++ b/.cproject
@@ -1,44 +1,42 @@
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -46,11 +44,11 @@
-
-
+
+
-
+
@@ -59,55 +57,77 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
index d22c8b7..0a0e2a6 100644
--- a/.settings/language.settings.xml
+++ b/.settings/language.settings.xml
@@ -1,22 +1,22 @@
-
+
-
+
-
+
-
+
diff --git a/Board.h b/Board.h
index c86c77e..3ba39f8 100644
--- a/Board.h
+++ b/Board.h
@@ -2,214 +2,346 @@
* BaseBoard.h
*
* Created on: 21/02/2021
- * Author: dongmo
+ * Author: Dongmo
*/
#ifndef BOARD_H_
#define BOARD_H_
+#include
+
class Board
{
-private:
- int boardSize;
- int turn;
- int **grid;
-public:
- Board(int bs)
- {
- boardSize = bs;
- grid = new int*[boardSize];
- for (int i = 0; i < boardSize; i++)
- grid[i] = new int[boardSize];
-
- for (int i = 0; i < boardSize; i++)
- for (int j = 0; j < boardSize; j++)
- {
- grid[i][j] = 0;
- }
- turn = 1;
- }
-
- virtual ~Board()
- {
-
- for (int i = 0; i < boardSize; i++)
- delete[] grid[i];
-
- delete[] grid;
- }
-
- Board(Board &cboard)
- {
- boardSize = cboard.getBoardSize();
-
- grid = new int*[boardSize];
- for (int i = 0; i < boardSize; i++)
- grid[i] = new int[boardSize];
-
- for (int i = 0; i < boardSize; i++)
- for (int j = 0; j < boardSize; j++)
- grid[i][j] = 0;
-
- for (int i = 0; i < boardSize; i++)
- for (int j = 0; j < boardSize; j++)
- {
- grid[i][j] = cboard.getGrid(i, j);
- }
-
- turn = cboard.getTurn();
- }
-
- int getBoardSize()
- {
- return boardSize;
- }
-
- int getGrid(int x, int y)
- {
- return grid[x][y];
- }
-
- int getTurn()
- {
- return turn;
- }
-
- bool validInput(int, int);
-
- bool addMove(int playerType, int x, int y);
-
- int checkWinningStatus(int playerType)
- {
- //To be implemented
- return 0;
- }
-
- void printBoard();
+ private:
+ int boardSize;
+ int turn;
+ int **grid;
+ vector spots;
+ public:
+ Board(int bs)
+ {
+ boardSize = bs;
+ grid = new int*[boardSize];
+ for (int i = 0; i < boardSize; i++)
+ grid[i] = new int[boardSize];
+
+ for (int i = 0; i < boardSize; i++)
+ for (int j = 0; j < boardSize; j++)
+ {
+ grid[i][j] = 0;
+ }
+ turn = 1;
+ }
+
+ virtual ~Board()
+ {
+
+ for (int i = 0; i < boardSize; i++)
+ delete[] grid[i];
+
+ delete[] grid;
+ }
+
+ Board(Board &cboard)
+ {
+ boardSize = cboard.getBoardSize();
+
+ grid = new int*[boardSize];
+ for (int i = 0; i < boardSize; i++)
+ grid[i] = new int[boardSize];
+
+ for (int i = 0; i < boardSize; i++)
+ for (int j = 0; j < boardSize; j++)
+ grid[i][j] = 0;
+
+ for (int i = 0; i < boardSize; i++)
+ for (int j = 0; j < boardSize; j++)
+ {
+ grid[i][j] = cboard.getGrid(i, j);
+ }
+
+ turn = cboard.getTurn();
+ }
+
+ int getBoardSize()
+ {
+ return boardSize;
+ }
+
+ int getGrid(int x, int y)
+ {
+ return grid[x][y];
+ }
+
+ int getTurn()
+ {
+ return turn;
+ }
+
+ bool validInput(int, int);
+
+ bool addMove(int playerIndex, int x, int y);
+
+ int checkWinningStatus(int playerIndex);
+
+ void printBoard();
+
+ bool isBoardFull();
+ bool isFullThisTurn();
+
+ void allSpots();
+ void printSpots();
+ void removeSpot(int x, int y);
+ vector getSpots()
+ {
+ return spots;
+ }
};
+void Board::allSpots()
+{
+ for(int x = 0; x < boardSize; x++)
+ for(int y = 0; y < boardSize; y++)
+ {
+ int value = x*boardSize+y;
+ //cout << x << " " << boardSize << " " << y << endl;
+
+ spots.push_back(value);
+
+ //int i = value/boardSize+1;
+ //int j = value%boardSize+1;
+ //cout << i << j << endl;
+ }
+}
+
+void Board::printSpots()
+{
+ for(int i = 0; i < spots.size(); i++)
+ cout << "(" << (spots[i]/boardSize)+1 << "," << (spots[i]%boardSize)+1 << ")" << endl;
+}
+
+void Board::removeSpot(int x, int y)
+{
+ int value = x*boardSize+y;
+
+ for(int i = 0; i < spots.size(); i++)
+ {
+ if(spots[i] == value)
+ {
+ spots.erase(spots.begin()+i);
+ break;
+ }
+ }
+}
+
bool Board::validInput(int x, int y)
{
- if (x < 0 || y < 0 || x >= boardSize || y >= boardSize)
- {
- cout << "Move (" << x + 1 << ", " << y + 1 << ") out of range!" << endl;
- return false;
- }
-
- if (grid[x][y] != 0)
- {
- cout << "Invalid move. The cell has been occupied." << endl;
- return false;
- }
-
- return true;
+ if (x < 0 || y < 0 || x >= boardSize || y >= boardSize)
+ {
+ cout << "Move (" << x + 1 << ", " << y + 1 << ") out of range!" << endl;
+ return false;
+ }
+
+ if (grid[x][y] != 0)
+ {
+ cout << "Invalid move. The cell has been occupied." << endl;
+ return false;
+ }
+
+ return true;
}
-bool Board::addMove(int playerType, int x, int y)
+bool Board::addMove(int playerIndex, int x, int y)
{
+ if (playerIndex != turn)
+ {
+ cout << "It is not the player's turn!" << endl;
+ return false;
+ }
+
+ if (grid[x][y] != 0)
+ {
+ cout << "Invalid move. The cell has been occupied." << endl;
+ return false;
+ }
+
+ grid[x][y] = playerIndex;
+ removeSpot(x,y);
+
+ turn = -1 * turn;
+ return true;
+}
- if (playerType != turn)
- {
- cout << "It is not the player's turn!" << endl;
- return false;
- }
+void Board::printBoard()
+{
+ //Top X numbers
+ cout << " ";
+ for (int j = 0; j < boardSize; j++)
+ {
+ if (j < 9) cout << "_" << j + 1 << "_.";
+ else cout << "_" << j + 1 << ".";
+ }
+ cout << endl;
+
+ //RHS Y numbers & grid
+ for (int i = 0; i < boardSize; i++)
+ {
+ for (int k = 0; k < i; k++)
+ cout << " ";
+
+ if (i < 9) cout << " " << i + 1 << " ";
+ else cout << i + 1 << " ";
+
+ for (int j = 0; j < boardSize; j++)
+ {
+ if (grid[i][j] == 0)
+ {
+ if (j == 0)
+ {
+ cout << "\\___\\";
+ }
+ else
+ {
+ cout << "___\\";
+ }
+ }
+ else if (grid[i][j] == 1)
+ {
+ if (j == 0)
+ {
+ cout << "\\_X_\\";
+ }
+ else
+ {
+ cout << "_X_\\";
+ }
+ }
+ else
+ {
+ if (j == 0)
+ {
+ cout << "\\_O_\\";
+ }
+ else
+ {
+ cout << "_O_\\";
+ }
+ }
+ }
+
+ cout << " " << i + 1;
+ if (i == boardSize / 2 || i == boardSize / 2 + 0.5) cout << " Y Goal";
+ cout << endl;
+ }
+
+ for (int s = 0; s < boardSize; s++)
+ cout << " ";
+
+ cout << " ";
+ for (int e = 0; e < boardSize; e++)
+ {
+ if (e < 9) cout << " " << e + 1 << " ";
+ else cout << " " << e + 1 << " ";
+ }
+ cout << endl;
+
+ for (int g = 0; g < boardSize * 3; g++)
+ cout << " ";
+ cout << " X Goal" << endl;
+}
- if (grid[x][y] != 0)
- {
- cout << "Invalid move. The cell has been occupied." << endl;
- return false;
- }
+bool Board::isBoardFull()
+{
+ if(spots.size() > 0)
+ return false;
- grid[x][y] = playerType;
+ cout << "Woops! The board is full and no one has won, looks like it's game over." << endl;
+ return true;
+}
- turn = -1 * turn;
- return true;
+bool Board::isFullThisTurn()
+{
+ int count = 0;
+ for(int i = 0; i < boardSize; i++)
+ {
+ for(int j = 0; j < boardSize; j++)
+ {
+ if(grid[i][j] == 0)
+ ++count;
+ }
+ }
+
+ if(count==1)
+ {
+ cout << "Yikes, looks like there's only one free spot. Better make this move count or its game over." << endl;
+ return true;
+ }
+ else
+ return false;
}
-void Board::printBoard()
+int Board::checkWinningStatus(int playerIndex)
{
- //Top X numbers
- cout << " ";
- for (int j = 0; j < boardSize; j++)
- {
- if (j < 9)
- cout << "_" << j + 1 << "_.";
- else
- cout << "_" << j + 1 << ".";
- }
- cout << endl;
-
- //RHS Y numbers & grid
- for (int i = 0; i < boardSize; i++)
- {
- for (int k = 0; k < i; k++)
- cout << " ";
-
- if (i < 9)
- cout << " " << i + 1 << " ";
- else
- cout << i + 1 << " ";
-
- for (int j = 0; j < boardSize; j++)
- {
- if (grid[i][j] == 0)
- {
- if (j == 0)
- {
- cout << "\\___\\";
- }
- else
- {
- cout << "___\\";
- }
- }
- else if (grid[i][j] == 1)
- {
- if (j == 0)
- {
- cout << "\\_X_\\";
- }
- else
- {
- cout << "_X_\\";
- }
- }
- else
- {
- if (j == 0)
- {
- cout << "\\_O_\\";
- }
- else
- {
- cout << "_O_\\";
- }
- }
- }
-
- cout << " " << i + 1;
- if(i == boardSize/2 || i == boardSize/2+0.5)
- cout << " Y Goal";
- cout << endl;
- }
-
-
- for(int s = 0; s < boardSize; s++)
- cout << " ";
-
- cout << " ";
- for(int e = 0; e < boardSize; e++)
- {
- if(e < 9)
- cout << " " << e + 1 << " ";
- else
- cout << " " << e + 1 << " ";
- }
- cout << endl;
-
- for(int g = 0; g < boardSize*3; g++)
- cout << " ";
- cout << " X Goal" << endl;
+ //Check if a whole row is complete
+ for (int r=0; r
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Hex.depend b/Hex.depend
new file mode 100644
index 0000000..dac7bdb
--- /dev/null
+++ b/Hex.depend
@@ -0,0 +1,24 @@
+# depslib dependency file v1.0
+1616572301 source:c:\users\ascle\desktop\uni\dsa\assignments\assignment 1 - hex game\dsa-hex-game\main.cpp
+
+
+ "Board.h"
+ "Player.h"
+ "HumanPlayer.h"
+ "HexGame.h"
+ "RandomPlayer.h"
+
+1616577291 c:\users\ascle\desktop\uni\dsa\assignments\assignment 1 - hex game\dsa-hex-game\board.h
+
+
+1613904637 c:\users\ascle\desktop\uni\dsa\assignments\assignment 1 - hex game\dsa-hex-game\player.h
+
+1616376427 c:\users\ascle\desktop\uni\dsa\assignments\assignment 1 - hex game\dsa-hex-game\humanplayer.h
+
+1616577125 c:\users\ascle\desktop\uni\dsa\assignments\assignment 1 - hex game\dsa-hex-game\hexgame.h
+
+1616392894 c:\users\ascle\desktop\uni\dsa\assignments\assignment 1 - hex game\dsa-hex-game\randomplayer.h
+
+
+
+
diff --git a/Hex.layout b/Hex.layout
new file mode 100644
index 0000000..7dc8f04
--- /dev/null
+++ b/Hex.layout
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/HexGame.h b/HexGame.h
index 59abb4d..db271fb 100644
--- a/HexGame.h
+++ b/HexGame.h
@@ -8,47 +8,56 @@
#ifndef HEXGAME_H_
#define HEXGAME_H_
-class HexGame {
-private:
- Board *board;
- Player *player[2];
-public:
- HexGame(Board *b, Player *p1, Player *p2) {
- board = b;
- player[0] = p1;
- player[1] = p2;
- }
+class HexGame
+{
+ private:
+ Board *board;
+ Player *player[2];
+ public:
+ bool canPlay = true;
+
+ HexGame(Board *b, Player *p1, Player *p2)
+ {
+ board = b;
+ player[0] = p1;
+ player[1] = p2;
+ }
- void play();
+ void play();
};
-void HexGame::play() {
+void HexGame::play()
+{
int won = 0;
- board->printBoard();
-
- while (!won) {
+ board->printBoard(); //Print the game board to the screen
+ board->allSpots(); //Add all of the free coordinates to the spots vector
+ //Loop until someone has won or the board has been filled
+ while (!won && !board->isBoardFull())
+ {
int playerType = board->getTurn();
int playerIndex = (playerType == player[0]->getType()) ? 0 : 1;
int x = -1;
int y = -1;
- if (!player[playerIndex]->getMove(board, x, y)) {
- cout << "No available move" << endl;
+ if (!player[playerIndex]->getMove(board, x, y))
+ {
+ cout << "ERROR: No available move" << endl;
return;
}
+ else
+ system("CLS");
cout << player[playerIndex]->getPlayerName() << " plays " << " ("
- << x + 1 << ", " << y + 1 << "):" << endl;
+ << x + 1 << ", " << y + 1 << "):" << endl;
if (!board->addMove(playerType, x, y))
return;
board->printBoard();
won = board->checkWinningStatus(playerType);
- if(won == playerType)
- cout << player[playerIndex]->getPlayerName() << " player wins!" << endl;
-
+ if(won == playerType)
+ cout << player[playerIndex]->getPlayerName() << " player wins!" << endl;
}
}
diff --git a/HumanPlayer.h b/HumanPlayer.h
index 24c1f14..526b95b 100644
--- a/HumanPlayer.h
+++ b/HumanPlayer.h
@@ -10,29 +10,41 @@
using namespace std;
-class HumanPlayer: public Player {
-public:
- HumanPlayer(int t, string name = "Human") :
- Player(t, name) {
- }
- bool getMove(Board*, int&, int&);
+class HumanPlayer: public Player
+{
+ public:
+ HumanPlayer(int t, string name = "Human") :
+ Player(t, name)
+ {
+ }
+ bool getMove(Board*, int&, int&);
};
-bool HumanPlayer::getMove(Board *board, int &x, int &y) {
+bool HumanPlayer::getMove(Board *board, int &x, int &y)
+{
bool flag = false;
+ bool lastTurn = false;
int bs = board->getBoardSize();
- while (!flag) {
+ lastTurn = board->isFullThisTurn();
+
+ do
+ {
cout << "Input row and column (x, y) between 1 to " << bs << " for "
- << name << " player:" << endl;
+ << name << ":" << endl;
+ board->printSpots();
int row, col;
- cin >> col >> row;
+ cin >> row >> col;
x = row - 1;
y = col - 1;
- flag = board->validInput(x, y);
- if (flag == false)
+ flag = board->validInput(x, y)?false:true; //Flag invalid inout if the board is full or if it isnt a valid input (ie. used spot)
+ if (flag == true)
cout << "Invalid input! Please input again." << endl;
}
+ while (flag);
+
+ //board->emptySpots -= 1;
+ //cout << board->emptySpots;
return true;
}
diff --git a/Main.cpp b/Main.cpp
index 3910216..9478f85 100644
--- a/Main.cpp
+++ b/Main.cpp
@@ -14,18 +14,45 @@ using namespace std;
#include "Player.h"
#include "HumanPlayer.h"
#include "HexGame.h"
+#include "RandomPlayer.h"
-int main() {
+int main()
+{
int boardSize = 5;
cout <<"Input the size of board: (Minimum is 3, but boards from 5-12 are best)" << endl;
- cin >> boardSize;
+ cin >> boardSize;
+ system("CLS");
if (boardSize < 3)
boardSize = 3;
Board *board = new Board(boardSize);
+ int p2Type = 1;
+ cout <<"Who do you want to verse? (0 = another player, 1 = Bad AI, 2 = Better AI)" << endl;
+ cin >> p2Type;
+ system("CLS");
+
Player *p1 = new HumanPlayer(1, "Crosses (X)");
- Player *p2 = new HumanPlayer(-1, "Naughts (O)");
+ Player *p2;
+
+ switch(p2Type)
+ {
+ case 0:
+ {
+ p2 = new HumanPlayer(-1, "Naughts (O)");
+ break;
+ }
+ case 1:
+ {
+ p2 = new RandomPlayer(-1, "Naughts (O)");
+ break;
+ }
+ default:
+ {
+ p2 = new RandomPlayer(-1, "Naughts (O)");
+ break;
+ }
+ }
HexGame game(board, p1, p2);
game.play();
diff --git a/RandomPlayer.h b/RandomPlayer.h
new file mode 100644
index 0000000..8d14d64
--- /dev/null
+++ b/RandomPlayer.h
@@ -0,0 +1,45 @@
+/*
+ * RandomPlayer.h
+ *
+ * Created on: 22/03/2021
+ * Author: Broderick Westrope
+ */
+
+#ifndef RANDOMPLAYER_H_
+#define RANDOMPLAYER_H_
+
+#include
+#include
+#include
+
+using namespace std;
+
+class RandomPlayer: public Player
+{
+ public:
+ RandomPlayer(int t, string name = "Random") :
+ Player(t, name)
+ {
+ }
+ bool getMove(Board*, int&, int&);
+};
+
+bool RandomPlayer::getMove(Board *board, int &x, int &y)
+{
+ if(board->isBoardFull())
+ {
+ cout << "ERROR: Random player can't move cause the board is full!" << endl;
+ return false;
+ }
+
+ srand(time(NULL));
+ vector spots = board->getSpots();
+ int index = rand() % (spots.size()-1) + 0;
+
+ x = spots[index]/board->getBoardSize();
+ y = spots[index]%board->getBoardSize();
+
+ return true;
+}
+
+#endif /* RANDOMPLAYER_H_ */