Looking for any feedback to improve practices on the following logic, and I have removed large chunks of documentation to reduce noise. I feel the areas that could expect heavy criticism are the win/tie condition checking.
Main.cpp
#include "Board.h"
int main() {
//initialize board
Board gameboard;
for (int i = 0; i < gameboard.GetBoardSize(); i++) {
gameboard.PlayTurn();
gameboard.SetTurn(gameboard.GetTurn() + 1);
if (gameboard.CheckWin()) {
std::cout << gameboard.GetWin() << " wins!" << std::endl;
break;
}
if (gameboard.CheckTie()) {
std::cout << "Cat's Game!" << std::endl;
break;
}
if (i == 8) {
std::cout << "Cat's Game!" << std::endl;
break;
}
}
return 0;
}
Board.h
#pragma once
#include <iostream>
#include <string>
#include <vector>
class Board
{
private:
std::vector<std::string> tiles;
int turn;
public:
//constructors
Board();
//getters
std::string GetTile(int);
int GetTurn();
int GetBoardSize();
//setters
void SetTile(std::string, int);
void SetTurn(int);
//other methods
void Display();
void PlayTurn();
bool CheckPlayedTile(int);
bool CheckWin();
bool CheckTie();
std::string GetWin();
};
Board.cpp
#include "Board.h"
//constructors
Board::Board() {
for (int i = 0; i < 9; i++)
tiles.push_back(std::to_string(i));
turn = 0;
Display();
}
//getters
std::string Board::GetTile(int pos) {
return tiles[pos];
}
int Board::GetTurn() {
return turn;
}
int Board::GetBoardSize() {
return tiles.size();
}
//setters
void Board::SetTile(std::string letter, int pos) {
tiles[pos] = letter;
}
void Board::SetTurn(int newTurn) {
turn = newTurn;
}
//other methods
void Board::Display() {
std::cout << std::endl;
if (turn == 0)
std::cout << "Turn " << turn << std::endl;
for (int i = 0; i < tiles.size(); i++) {
if (i % 3 == 0 && i > 0)
std::cout << std::endl << "---------" << std::endl;
else if (i % 3 != 0 && i > 0)
std::cout << " | ";
std::cout << tiles[i];
}
std::cout << std::endl << std::endl;
}
void Board::PlayTurn() {
int uiTile;
if (turn % 2 == 0) {
std::cout << "Turn " << turn << std::endl;
std::cout << "Player X, please select a square: ";
std::cin >> uiTile;
if (!CheckPlayedTile(uiTile))
tiles[uiTile] = "X";
else {
std::cout << uiTile << " has already been played, please select another" << std::endl;
PlayTurn();
}
}
else {
std::cout << "Turn " << turn << std::endl;
std::cout << "Player O, please select a square: ";
std::cin >> uiTile;
if (!CheckPlayedTile(uiTile))
tiles[uiTile] = "O";
else {
std::cout << uiTile << " has already been played, please select another" << std::endl;
PlayTurn();
}
}
Display();
}
bool Board::CheckPlayedTile(int pos) {
if (tiles[pos] == "X" || tiles[pos] == "O")
return true;
return false;
}
bool Board::CheckWin() {
if (tiles[0] == tiles[1] && tiles[0] == tiles[2])
return true;//tiles[0];
else if (tiles[0] == tiles[3] && tiles[0] == tiles[6])
return true;//tiles[0];
else if (tiles[0] == tiles[4] && tiles[0] == tiles[8])
return true;//tiles[0];
else if (tiles[1] == tiles[4] && tiles[1] == tiles[7])
return true;//tiles[1];
else if (tiles[2] == tiles[5] && tiles[2] == tiles[8])
return true;//tiles[2];
else if (tiles[2] == tiles[4] && tiles[2] == tiles[6])
return true;//tiles[2];
else if (tiles[3] == tiles[4] && tiles[3] == tiles[5])
return true;//tiles[3];
else if (tiles[6] == tiles[7] && tiles[6] == tiles[8])
return true;//tiles[6];
return false;
}
bool Board::CheckTie() {
for (int i = 0; i < tiles.size(); i++) {
if (tiles[i] == "X" || tiles[i] == "O")
return false;
}
return true;
}
std::string Board::GetWin() {
if (tiles[0] == tiles[1] && tiles[0] == tiles[2])
return tiles[0];
else if (tiles[0] == tiles[3] && tiles[0] == tiles[6])
return tiles[0];
else if (tiles[0] == tiles[4] && tiles[0] == tiles[8])
return tiles[0];
else if (tiles[1] == tiles[4] && tiles[1] == tiles[7])
return tiles[1];
else if (tiles[2] == tiles[5] && tiles[2] == tiles[8])
return tiles[2];
else if (tiles[2] == tiles[4] && tiles[2] == tiles[6])
return tiles[2];
else if (tiles[3] == tiles[4] && tiles[3] == tiles[5])
return tiles[3];
else if (tiles[6] == tiles[7] && tiles[6] == tiles[8])
return tiles[6];
return "";
}