Tic Tac Toe Game Help / Advice

Help with classes & passing variables

Page 1 of 1

12 Replies - 2951 Views - Last Post: 20 January 2010 - 01:08 PM Rate Topic: -----

#1 4D1  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 225
  • Joined: 22-October 09

Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 09:55 AM

Hello Guys,

I am studying C++ on a foundation computing degree, I am tasked with creating a Tic Tac Toe game. My course only covers basic C++ so we are only required to produce a game with procedural code or using functions if we like. I have been learning C++ in my own time and quickly surpassed what the course is teaching, I want to move to a software engineering course which covers C++ amongst others in much greater depth, in order to do this I need to get a distinction, also I wanted to produce a more complex program than is required as I want to learn how to use classes and other more advanced techniques and practice makes perfect

#include <fstream> //File stream functions, for file I/O
#include <vector> //Vector template functions
#include <windows.h> //Sleep function
#include <iostream> //Standard I/O header file
using namespace std;
/*Functions we require are part of the standard namespace,
including this means we dont need the :: access specifier
to use cout or cin */

//Class to keep program modular
class game
{
	public:

	string name;  //Used to create a vector for scores
	string score; //Used to create a vector for scores
	char* board; //Pointer used to create a dynamic array
	string player1, player2; //Variables to hold player names
	vector <game> scores; //Vector of base class, used to store scores from text file, member functions do not take up memory in a vector
	void main_menu();
	int init_board(int&, int&, char&);
	int take_turn(int&, int&);
	int check_winner(int&, int&, char&);
	int file_out(char&);
	int file_in();
};

void game::main_menu()
{
	int size; //Variable to store baord size
	int selection=0; //Variable to store user selection from menu

do
{
	int turn=1; //Variable to keep track of turn, initialised to 1 to start
	char winner='\0'; //Variable to store winner, set to NULL initially

	system("CLS"); //Clear the screen before displaying menu each time

	system("color 70"); //Used to change screen color

		//Just A Game Logo
		  cout << "\n\n	   *****   ***	****	 *****   *****	****	 *****   ****	****";
		  cout << "\n		**	  *	 *		 **	 ** * *   *		 **	 *  *	**  ";
		  cout << "\n		**	 ***	****	  **	 **   *   ****	  **	 ****	****";

		//Main Menu
		  cout << "\n\n\t\t\t Welcome To Tic Tac Toe Deluxe\n";
		  cout << "\n\n\t\t\t		Type 0 to Exit";
		  cout << "\n\n\t\t\t	  Choose a board size";
		  cout << "\n\t\t\t		  (1) 3 x 3";
		  cout << "\n\t\t\t		 (2) 10 x 10";
		  cout << "\n\t\t\t	  (3)View high scores";
		  cout << "\n\n\t\t\t		 Selection: ";
		  cin >> selection;

		switch (selection) //Switch case for menu
		{
			case 0: size=0; break;

			case 1: size=3; init_board(size, turn, winner); break;

			case 2: size=10; init_board(size, turn, winner); break;

			case 3: file_in(); system("PAUSE"); main_menu(); break;

			default:
				cout << "\n\t\t\tSorry Input Not Recognised!\n\t\t\t";
				system("PAUSE");
				main_menu();
			break;
		}

}while(size != 0);

}

int game::init_board(int& size, int& turn, char& winner)
{
	system("CLS");

	cout << "\n\n\n\t\tPlayer 1 You will be X, What is your name?: ";
	cin >> player1;
	cout << "\n\n\n\t\tPlayer 2 You will be O, What is your name?: ";
	cin >> player2;

	board = new (nothrow) char [(size*size)]; //Allocate memory for array

	if(board[0]==0)
	{
		cout<< "\n\t\t\tError initialising board\n\n\t\t"; //Simple check to see if memory was allocated successfully

		system("PAUSE"); //Pause so player can see error message

		main_menu(); //Take player back to main menu if memory is not allocated correctly
	}

	for(int a=0; a<((size*size)-1); a++)
	{
		board[a]='\0'; //Initialize board array to NULL
	}

	winner='\0'; //Initialise winner to NULL each game


while(winner!='X' && winner!='O' && winner!='D')
{
	system("CLS"); //Clear screen each time board refreshes, or each iteration

		for(int b=0; b<(size*size); b++) //Creates correct spacing dependent on which size board is being played
		{
			if(size==3 && (b%size)==0)
			{
				cout << "\n\n\t\t\t\t";

				if(board[b]!='X' && board[b]!='O')
				{
					cout << b << " | ";
				}
				else
				{
					cout << board[b] << " | ";
				}
			}
			else if(size==10 && (b%size)==0)
			{
				cout << "\n\n\t\t";

				if(b<=9)
				{
					cout << " "; //Correct spacing for 1st 9 elements
				}

				if(board[b]!='X' && board[b]!='O')
				{
					cout << b << " | ";
				}
				else
				{
					cout << board[b] << " | ";
				}
			}
			else
			{
				if(b<=9)
				{
					cout << " "; //Correct spacing for 1st 9 elements
				}

				if(board[b]!='X' && board[b]!='O')
				{
						cout << b << " | ";
				}
				else
				{
					if(b>9)
					{
						cout << " " << board[b] << " | ";
					}
					else
					{
						cout << board[b] << " | ";
					}
				}
			}
		}

	if(turn>5) //Check for a winner at the earliest point it could occur
	{
		check_winner(size, turn, winner); //Check winner before turn, otherwise winners are not announced correctly
	}

	if(winner!='X' && winner!='O' && winner!='D')
	{
		take_turn(size, turn); //Load function to take a turn if no winner
	}
}
}

int game::take_turn(int& size, int& turn)
{
	int space; //Variable for user to choose a space on the board

	cout << "\n\n\t\t\t\t";

		if(turn%2==1) //If number is odd player1's turn, if even player2's turn
		{
			cout << player1;
		}
		else
		{
			cout << player2;
		}

	cout << " Choose a space\n\n";
	cout << "\n\t\t\t\tSelection: ";
	cin >> space;


		if(space>((size*size)-1)) //Simple check to see if space is valid
		{
			cout << "\n\t\t\tSorry That Space Does Not Exist\n\n\t\t";
			system("PAUSE");
		}
		else if(board[space] == 'X' || board[space] == 'O') //Simple check to see if space is already taken
		{
			cout << "\n\t\t\tSorry That Space is taken\n\n\t\t";
			system("PAUSE");
		}
		else
		{
			if(turn%2==1)
			{
				board[space]='X';
			}
			else
			{
				board[space]='O';
			}

			turn++;
		}

}

int game::check_winner(int& size, int& turn, char& winner)
{
	for(int a=0; a<(size*size); a++)
	{
		if(a%size <= size-3 && board[a]==board[(a+1)] && board[a]==board[(a+2)]
								  ||
		   board[a]==board[(a+size)] && board[a]==board[(a+(size*2))]
								  ||
		   a%size <= size-3 && board[a]==board[((a+size)+1)] && board[a]==board[(a+((size*2)+2))]
								  ||
		   a%size <= size-3 && board[a]==board[((a-size)+1)] && board[a]==board[((a-(size*2))+2)]) //Compare Horizontal, Diagonal & Vertical with this algorithm
		{
			winner=board[a];

			if(winner=='X')
			{
				cout << "\n\n\t\t\t\t" << player1 << " " << winner << " is the winner!!!\n\n\t\t\t";
				//Creates a little flashy effect
				system("COLOR 45");
				Sleep (200);
				system("COLOR 50");
				Sleep (200);
				system("COLOR 45");
				Sleep (200);
				system("COLOR 50");
				Sleep (200);
				system("COLOR 45");
				Sleep (200);
				system("COLOR 70");
				system("PAUSE");
				file_out(winner);
				main_menu();
			}
			else if(winner=='O')
			{
				cout << "\n\n\t\t\t\t" << player2 << " " << winner << " is the winner!!!\n\n\t\t\t";
				//Creates a little flashy effect
				system("COLOR 45");
				Sleep (200);
				system("COLOR 50");
				Sleep (200);
				system("COLOR 45");
				Sleep (200);
				system("COLOR 50");
				Sleep (200);
				system("COLOR 45");
				Sleep (200);
				system("COLOR 70");
				system("PAUSE");
				file_out(winner);
				main_menu();
			}
		}
	}

	if(size==3 && turn==10 || size==10 && turn==101)
	{
		cout << "\n\n\t\t\t\tIts a Draw!!!\n\n\t\t\t";

		system("PAUSE");

		winner='D';
	}
}

int game::file_out(char& winner)
{
	ofstream output; //Create an instance of ofstream
	output.open("scores.txt", ios::app); //Open file scores.txt if exists or create, set mode to append, new scores are added to the end of the file

	if(winner=='X')
	{
		output << player1 << "\n";
	}
	else if(winner=='O')
	{
		output << player2 << "\n";
	}
	else if(winner=='D')
	{
		output << player1 << "\n" << player2 << "\n";
	}
	output.close();
}

int game::file_in()
{
	system("CLS");  //Clear screen before outputting scores

	ifstream input; //Create an object of ifstream

	input.open("scores.txt");  //Open Text File

	if(input.is_open())  //Simple check to see if file is open
	{

		while(!input.eof())  //Loop until end of file
		{
			game temp;  //Create an object of player

			getline(input, temp.name);  //Read in a line from the text file and assign it to object member

			getline(input, temp.score);  //Read in a line from the text file and assign it to object member

			scores.push_back(temp);
		}

		for(int a=0; a<(scores.size()-1); a++)
		{
			cout << "\n\t\t\t" << scores[a].name << " " << scores[a].score << "\n";
		}

		scores.clear();


	}
	else
	{
		cout << "\n\n\t\t\tSorry there was an error getting scores";
	}

	cout << "\n\t\t\t";
	input.close();
}

int main()
{
	game tic; //Create an instance of class game
	tic.main_menu(); //Load game member function

	return 0;
}



Would it be a good idea to strip my functions back to their main purpose and create a new header file for my class, then write the program from the main using the functions from the header file, as if it was a header file for making a tic tac toe game (if that makes sense).

Also how should I pass the variables? Is passing everything by reference acceptable? should I change this? I only did this as I was told passing by reference uses less memory.

And finally, I am always confused about class, Public: Private: etc, I know that:

Public: When everything should have access

Private: When only the class should have access

Protected: When only the class and things that inherit from the class should have access

But for me everything can be public? How should I decide what to make private or otherwise and how would that affect passing variables to them?

This post has been edited by 4D1: 19 January 2010 - 09:55 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Tic Tac Toe Game Help / Advice

#2 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 10:22 AM

You pass an argument by a reference, when you want that argument to keep it's value gotten from the function. I will give you an example:

// don't pass i as a reference.
void change_i(int i) // i is created here
{
   i += 3; // change the value of i
} // i is DESTROYED here

int main()
{
   int n = 13;
   change_i(n); 
   cout << "n = " << n; // outputs 13, not 16!

   return 0;
}


However, using this method:

// pass i as a reference:
void change_i(int &i) // i is created here
{
   i += 3; // change the value of i
} // i is NOT DESTROYED here, it keeps the value gotten from the function

int main()
{
   int n = 13;
   change_i(n); 
   cout << "n = " << n; // outputs 16!

   return 0;
}



Now about public, private and protected keywords:
Consider the following class:

class Car
{
private:
   int color;
public:
   void set_color(int newc) { color = newc; }
   int get_color() { return color; }
};

int main()
{
	// instantiate the class
	Car car;
	car.set_color(4); // can access the function, because it is public
	cout << car.get_color() << endl; // can access the function, because it is public
	// However, this will be an error:
	cout << car.color << endl; // ERROR: can't access private member directly

		return 0;
}



As you can see, you can't access private members directly, but only using member functions defined in 'public' zone.
As for 'protected' zone, the variables/member functions defined here can be accessed by the classes that derives from the base class. They can't be directly accessed by the class object (just like private member functions/vars), so you need public member functions to access them. Vars/member functions defined in 'protected' zone, can be accessed by the base class too!

Hope you understood. My english is not the best one here ....

This post has been edited by sarmanu: 19 January 2010 - 10:25 AM

Was This Post Helpful? 0
  • +
  • -

#3 4D1  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 225
  • Joined: 22-October 09

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 10:35 AM

Hello Sarmanu,

Thanks for the response, with regards to passing by reference I understand your example already, what I meant was is it better to pass by reference simply to save memory? Or should I always stick to using copies unless I want to change the original variable itself?

Also with your example on classes, I understand it but what I meant was from my new to c++ point of view, it would make everything very simple to make everything Global or Public, what motivation should I have to make things private and write more code? Why do we use Public etc not so much how.
Was This Post Helpful? 0
  • +
  • -

#4 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 10:48 AM

You should pass the arguments by references, only where you need to. Maybe it is faster to pass them by reference, but unexpected results may occur when you pass the arguments as references, and not only by a copy!
And that speeding amount that you are talking about, it is NOT affecting your runtime, because we are talking about micro-micro ... seconds.

As for the classes, even if you are a beginner, you have the motivation to make things 'perfect', making everything public will lack of efficiency (won't affect things though, but splitting the class with private and public zones makes the code more readable too) ... Based on my example, make sure that you use both private and public areas, so you can master the OOP :P

This post has been edited by sarmanu: 19 January 2010 - 10:54 AM

Was This Post Helpful? 1
  • +
  • -

#5 4D1  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 225
  • Joined: 22-October 09

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 10:57 AM

Hello Sarmanu, That gives me a solid rule to work on with passing variables, thanks, as for the classes even as a beginner I do have the motivation to do things perfectly which is why I am asking the question, but as I get deeper into programming I would prefer to know why I am making things private as opposed to just doing it for the sake of it, thats all.

What about my class, is the program good as it is, or should I make my own header file and use it like any other header file? is there anything I could improve? aside from the obvious, setting things to private and passing reference that I will change.
Was This Post Helpful? 0
  • +
  • -

#6 sonicpp  Icon User is offline

  • D.I.C Head

Reputation: 18
  • View blog
  • Posts: 58
  • Joined: 08-January 10

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 10:58 AM

View Postsarmanu, on 19 Jan, 2010 - 09:48 AM, said:

You should pass the arguments by references, only where you need to. Maybe it is faster to pass them by reference, but unexpected results may occur when you pass the arguments as references, and not only by a copy!
And that speeding amount that you are talking about, it is NOT affecting your runtime, because we are talking about micro-micro ... seconds.

As for the classes, even if you are a beginner, you have the motivation to make things 'perfect', making everything public will lack of efficiency ... Based on my example, make sure that you use both private and public areas, so you can master the OOP :P

Sorry to butt in but here is another way to look at it. If you do want to gain the speed that pass by ref gives you and are worried about accidently changing the data inside the function call you can always use the const keyword.
Example...
void myClass::someMemberFunction(const int &i)
{
i=10; // error can't set i in here
}


Was This Post Helpful? 1
  • +
  • -

#7 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 11:10 AM

Most of the programmers defines the class in a header file, then they implement it in a source file. Then, the main source file containing the main function is added. In the main source file, you should include the class header file, so you can access everything related to that class.

@sonicpp, yes, I know about that, but in my opinion is just a waste of time. I have seen a lot of BIG projects, and took a good look at the code. Where reference and pointer is needed, it is used. Where it's not, it is simply not used.
Was This Post Helpful? 0
  • +
  • -

#8 4D1  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 225
  • Joined: 22-October 09

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 12:17 PM

Hi Sonicpp,

Thanks for that, I have seen a number of examples of other programs where this is used with a reference and never understood what it was doing, so it is simply to prevent any unwanted modifications.
Was This Post Helpful? 0
  • +
  • -

#9 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 855
  • View blog
  • Posts: 2,338
  • Joined: 20-August 07

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 01:26 PM

the const keyword is an important tool for writing safer code - use it as much as possible wherever something in your program doesn't need to change; have a read through this page for some more detail - http://www.parashift...orrectness.html
Was This Post Helpful? 1
  • +
  • -

#10 4D1  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 225
  • Joined: 22-October 09

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 01:53 PM

Thanks for the replies, with reference to my class, I am trying to create a custom header file with it, some of the functions no matter how much I strip them back will need to use cout from within them, is this possible? I have never seen a function from any library that outputs anything on its own, is this even possible?
Was This Post Helpful? 0
  • +
  • -

#11 sonicpp  Icon User is offline

  • D.I.C Head

Reputation: 18
  • View blog
  • Posts: 58
  • Joined: 08-January 10

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 07:58 PM

View Post4D1, on 19 Jan, 2010 - 12:53 PM, said:

Thanks for the replies, with reference to my class, I am trying to create a custom header file with it, some of the functions no matter how much I strip them back will need to use cout from within them, is this possible? I have never seen a function from any library that outputs anything on its own, is this even possible?

I know of nothing to prevent you from using cout in a header file... what if the class is used in a non command line program... most people compile and run... pop goes the window and your message goes to stdout with no one to see it. The only messages I pass from header files are errors using the #error precompiler macro. That way if they try to use my stuff wrong they get an error message during compilation.
Was This Post Helpful? 0
  • +
  • -

#12 smeezekitty  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 18-December 08

Re: Tic Tac Toe Game Help / Advice

Posted 19 January 2010 - 11:53 PM

I dont know if it is my place to say this but you are really overusing system( ).
Was This Post Helpful? 0
  • +
  • -

#13 4D1  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 225
  • Joined: 22-October 09

Re: Tic Tac Toe Game Help / Advice

Posted 20 January 2010 - 01:08 PM

LOL @ smeezekitty, yeah I was gonna put a loop there instead, I only added that recently because I find console apps really bland
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1