Recently, I ventured into the realm of C++ programming. I have extensive knowledge in C and C#, but very basic knowledge of C++. I decided to build a brief TicTacToe example to test my knowledge.
It works by typing any comma-separated value (i.e. 2,1) and decides whose turn it is by odds and evens. X always goes first.
Problems: Does not claim a winner. There is no fail-safe for picking the same spot twice. I realize this, but I wanted the semantics over the algorithm. And I don't know of a sure-fire way to find a winner with a vector since I imagine a sea of nested if
-statements.
I would love to know what looks legal, and what I should never do again.
Board.h
#include <iostream>
#include <array>
#include <vector>
#include <string>
#include <iterator>
class Board
{
/*
** Protected boolean for checking for winner
*/
bool gameWon = false;
/*
** Use odd or even to tell whos turn it is
*/
int turnCount = 0;
public:
/*
** Pair vector for locations of X's and O's
*/
std::vector<std::pair<int, int>> locations;
bool GameWon(void){ return gameWon; }
void DrawBoard(void);
void NextTurn(void);
private:
int FindLocation(std::pair<int, int>);
};
Board.cpp
#include "Board.h"
const std::string line = " ------------- ";
const std::string wall = " | ";
/*
** Brute Force Drawing
**
** Iterate over the 9 squares and
** decide whether or not an X belongs
** there or if it's an O. Upon each
** square, check if the pair-location
** (x,y) matches an item in our vector
*/
void Board::DrawBoard()
{
// Clear screen on windows systems, throws an error
// on Unix and OS X
system("CLS");
std::cout << "Tic-Tac-Toe Console" << std::endl;
std::cout << line << std::endl;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
bool tileOpen = true;
std::cout << wall;
if (locations.size() > 0)
{
for (std::pair<int, int> p : locations)
{
if (p.first == i && p.second == j)
{
tileOpen = false;
if (FindLocation(p) % 2 == 0)
{
std::cout << "X";
}
else
{
std::cout << "O";
}
}
}
}
else
{
std::cout << "";
}
if (tileOpen == true)
std::cout << " ";
}
std::cout << wall << std::endl;
std::cout << line << std::endl;
}
}
/*
** Handles Board Turns
**
** Assume every even turn is X,
** and every odd is O.
*/
void Board::NextTurn()
{
std::string input;
if (turnCount % 2 == 0)
std::cout << " X's turn:" << std::endl;
else
std::cout << " O's turn:" << std::endl;
std::cin >> input;
locations.push_back(std::pair<int, int>(input[0] - '0' - 1, input[2] - '0' - 1));
turnCount++;
}
/*
** Vector Find Function
**
** Returns the index of a found object
** in the vector; 0 if otherwise
*/
int Board::FindLocation(std::pair<int, int> p)
{
std::vector<std::pair<int, int>>::iterator it;
it = std::find(locations.begin(), locations.end(), p);
return std::distance(locations.begin(), it);
}
Main.cpp
#include <iostream>
#include "Board.h"
int main()
{
Board mainBoard;
/*
** Check if there is a winner each cycle
*/
while (!mainBoard.GameWon())
{
/*
** Update Board
*/
mainBoard.DrawBoard();
/*
** Handle Players Turn
*/
mainBoard.NextTurn();
}
/*
** Grab a random char so the
** game doesn't immediately exit
*/
getchar();
}