I am learning C++ and I need help to review my first code and see how I could improve it in any way. Any suggestions are welcome. It was tested and it is free of bug.
The code is a game called TicTacToe and do the following:
- Create a 4x4 game board
- Prompt the first user (the 'x' user) to enter their name
- Prompt the second user (the 'o' user) to enter their name
- Prompt the 'x' user to select a grid position where they would like to place an 'x'.
- Prompt the 'o' user to select a grid position where they would like to place an 'o'.
- After each user has a turn, check for any row, column, diagonal that has 4 'x's or 4 'o's.
- If 4 'x's are found in the same col, row, diagonal, declare the 'x' user the winner.
- If 4 'o's are found in the same col, row, diagonal, declare the 'o' user the winner.
- End the game and declare the winner.
- If the grid is filled (each player gets 8 turns) and there is not a row, column, diagonal with 4 of the same symbol, the game is tied. Declare a tie game.
main.cpp
#include "main.hpp"
#include "User.cpp"
#include "Gameboard.cpp"
int main() {
int count=1, out=1;
string str0 ="";
//Create a 4x4 game board
Gameboard game;
//Prompt users to enter their name
usrs players;
players = create_2user();
//Create list, list iterator
list<User> playerList = { players.usr0, players.usr1 };
//Play until there is a winner or the gird is filled
while((count < 16)&&(out != 0)) {
for( User& usr : playerList ) {
//Prompt users to select a grid position
cout<<"\n "<< usr.get_name() <<", select a grid position: \n";
cout<<"\n"; game.printInfo(); cout<<"\n > ";
cin>>str0;
//update the gameboard after converting str0 into coordinate ( i, j )
game.updateBoard(str0, usr.get_symbol());
//check if four symbols are aligned:
if ( game.findFour(usr.get_symbol())==1 ) {
cout<<"\n"<<usr.get_name() <<" WINS!\n";
out=0; break; }
else if( count >= 16 ) {
cout<<"\nThe game is tied\n";
game.printInfo();
out=0; break; }
++count;
}
}
return 0;
}
User.cpp
#include "main.hpp"
using namespace std;
/* ----------- class User ------------------------------------------- */
class User { //create a CLASS (type) called 'User'
string name; //data attribute - private
char chr;
public: //procedural attribute- public
User(); //constructors
void set_name (string in_name); //mutator method : SETTER
void set_symbol(char in_chr);
string get_name(); //accessor method: GETTER
char get_symbol();
void printInfo(); //helper functions
};
User::User() { name="Unkonw"; chr='.'; } //define the constructor
void User::set_name(string in_name) { name = in_name; } //mutator method
void User::set_symbol (char in_chr) { chr = in_chr; }
string User::get_name() { return name; } //accessor method
char User::get_symbol() { return chr; }
void User::printInfo() { cout<<name<<"\t"<<chr; }
/* ----------- use class User --------------------------------------- */
struct usrs { User usr0, usr1; };
usrs create_2user() {
User array_usr[2];
char array_chr[] = { 'x', 'o' };
string str0;
for(int i=0;i<2;i++) {
cout<<"Enter player "<<i<<"'s name: ";
cin>>str0;
array_usr[i].set_name(str0);
array_usr[i].set_symbol(array_chr[i]);
}
usrs result = { array_usr[0], array_usr[1] };
return result;
}
Gameboard.cpp
#include "main.hpp"
using namespace std;
/* ----------- class Gameboard -------------------------------------- */
class Gameboard {
string gameSpace[4][4];
char chr;
public:
Gameboard(); //initialize the board with '-' in all 16 spaces
void setGameSpace(int row,int column, char value); //x,y,or '-' in each game square
string getGameSpace(int row,int column);
int findFour(char chr); //four 'x's in any row 'wins'
void printInfo(); //print the game board in a 4x4 matrix
void updateBoard(string str0, char symbol);
};
Gameboard::Gameboard() { //define the constructor
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
gameSpace[i][j] = to_string( (i+1)*10 + (j+1) );
//test0: OK - diag0 - if(i==j) { gameSpace[i][j] = "x"; }
//test1: OK - diag1 - if(i==(3-j)) { gameSpace[i][j] = "x"; }
//test2: OK - row - gameSpace[1][j] = "x";
//test3: OK - col - gameSpace[i][1] = "x";
};
};
}
void Gameboard::setGameSpace(int row, int column, char value) { gameSpace[row][column] = value;} //mutator method
string Gameboard::getGameSpace(int row, int column) { return gameSpace[row][column];} //accessor method
void Gameboard::printInfo() { //print the game board in a 4x4 matrix
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
cout<<gameSpace[i][j]<<"\t";
};
cout<<"\n";
};
}
int Gameboard::findFour(char chr) { //four symbols in any row, col, diagonals 'wins'
int int_dg0=0, int_dg1=0;
for(int i=0;i<4;i++) {
int int_row=0, int_col=0;
for(int j=0;j<4;j++) {
if(gameSpace[i][j][0]==chr) { ++int_row;}
if(gameSpace[j][i][0]==chr) { ++int_col;}
if( (gameSpace[i][j][0]==chr)&&(i==j) ) { ++int_dg0;}
if( (gameSpace[i][j][0]==chr)&&(i==(3-j)) ) { ++int_dg1;}
};
if((int_row==4)||(int_col==4)||(int_dg0==4)||(int_dg1==4)) { return 1; }
};
return 0;
}
void Gameboard::updateBoard(string str0, char symbol) {
//Convert player's input in coordinates
int row=0, column=0, k=0;
stringstream(str0) >> k;
row=k/10-1;
column=k%10-1;
//Update gameboard setGameSpace(int row, int column, char value)
gameSpace[row][column] = symbol;
}
main.hpp
#ifndef MAIN_HPP_
#define MAIN_HPP_
#include <iomanip>
#include <iostream>
#include <list>
#include <string>
#include <sstream>
using namespace std;
#endif /* MAIN_HPP_ */