TicTacToe Game

The Partridge Family were neither partridges nor a family. Discuss.
User avatar
neptunemermaid
Posts: 17
Joined: January 25th, 2015, 7:10 pm
Location: BC, Canada

TicTacToe Game

Post by neptunemermaid » July 10th, 2018, 2:59 am

I asked this on Discord but no one responded...

Anyone around? I have a question about tic tac toe. I'm new to the language and following a tutorial on youtube from some guy. in my tictactoe.h file I have:

private:
char board;
// xy coord from user
int getXCoord();
int getYCoord();

and in my tictactoe.cpp file i have:

int TicTacToeGame::getXCoord()
{ blah blah blah}

and I'm getting an error saying local function definitions are illegal.

thoughts?

User avatar
neptunemermaid
Posts: 17
Joined: January 25th, 2015, 7:10 pm
Location: BC, Canada

Re: TicTacToe Game

Post by neptunemermaid » July 10th, 2018, 3:54 am

TicTacToe.h


---------------

Code: Select all

#pragma once
class TicTacToeGame
{
public:
	TicTacToeGame();
	void playGame();
private:
	char board;
	// xy coord from user
	int getXCoord();
	int getYCoord();

	// places a marker. If false, couldn't place
	bool placeMarker(int x, int y, char currentPlayer);

	// returns true if winner
	bool checkForVictory(char currentPlayer);

	// clear board
	void clearBoard();

	// prints the board
	void printBoard();



};

User avatar
neptunemermaid
Posts: 17
Joined: January 25th, 2015, 7:10 pm
Location: BC, Canada

Re: TicTacToe Game

Post by neptunemermaid » July 10th, 2018, 3:54 am

TicTacToeGame.cpp

----------------------

Code: Select all

#include "TicTacToeGame.h"
#include <iostream>

using namespace std;




// constructor
TicTacToeGame::TicTacToeGame()
{
}


void TicTacToeGame::playGame() {

	clearBoard();

	char player1 = 'X';
	char player2 = 'O';
	char currentPlayer = player1;

	bool isDone = false;
	int x;
	int y;
	int turn = 0;


	// inner game loop

	while (isDone == false) 
	{
		printBoard();


		// get coordinates
		x = getXCoord();
		y = getYCoord();

		// place a marker

		if (placeMarker(x, y, currentPlayer) == false) {
			cout << "There's already something there\n";

		}
		else {
			turn++;
			if (checkForVictory(currentPlayer) == true) {
				cout << "Game Over! Player " << currentPlayer << "has won!\n";
				isDone = true;
			}
			else if (turn == 9) {
				cout << "Tied game!\n";
				isDone = true;
			}
		}



		// switch players

		if (currentPlayer == player1) {
			currentPlayer = player2;
		}
		else {
			currentPlayer = player1;
		}
	}



	int TicTacToeGame::getXCoord()
	{
		bool isInputBad = true;

		int x;

		while (isInputBad == true) {
			cout << "Enter the X coordinate: ";
			cin >> x;

			if (x < 1 || x > 3) {
				cout << "Invalid Coordinate!\n";
			}
			else {
				isInputBad = false;
			}
		}
		return x - 1;
	}







	int TicTacToeGame::getYCoord() 
	{

		bool isInputBad = true;
		int y;
		while (isInputBad = true) {
			cout << "Enter the Y Coordinate\n";
			cin >> y;

			if (y < 1 || y > 3) {
				cout << "Invalid coordinate\n";

			}
			else {
				isInputBad = false;
			}
		}
		return y - 1;
	}


	bool TicTacToeGame::placeMarker(int x, int y, char currentPlayer) {
		if (board[y][x] != ' ') {
			return false;
		}
		board[y][x] = currentPlayer;
		return true;
	}


	bool TicTacToeGame::checkForVictory(char currentPlayer) {
		// check rows
		for (int i = 0; i < 3; i++) {
			if ((board[i][0] == currentPlayer) && (board[i][0] == board[i][1]) && (board[i][1] == board[i][2])) {
				return true; // won the game

			}
		}

		// check columns
		for (int i = 0; i < 3; i++) {
			if ((board[0][i] == currentPlayer) && (board[0][i] == board[1][i]) && (board[1][i] == board[2][i])) {
				return true; // won the game
			}
		}


		// check top left diagonal
		for (int i = 0; i < 3; i++) {

			if ((board[0][0] == currentPlayer) && (board[0][0] == board[1][1]) && (board[1][1] == board[2][2])) {
				return true; // won the game
			}
		}


		// check top right diagonal
		for (int i = 0; i < 3; i++) {
			if ((board[2][0] == currentPlayer) && (board[2][0] == board[1][1]) && (board[1][1] == board[0][2])) {
				return true; // won the game 

			}
			return false;
		}
	}

	void TicTacToeGame::clearBoard()
	{
		//Empties the board
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				board[i][j] = ' ';
			}
		}
	}

	void TicTacToeGame::printBoard()
	{
		//formatting
		cout << endl;
		cout << " |1 2 3|\n";
		for (int i = 0; i < 3; i++) {
			cout << " -------\n";
			cout << i + 1 << "|" << board[i][0] << "|" << board[i][1] << "|" << board[i][2] << "|\n";
		}
		cout << " -------\n";
	}
}

User avatar
neptunemermaid
Posts: 17
Joined: January 25th, 2015, 7:10 pm
Location: BC, Canada

Re: TicTacToe Game

Post by neptunemermaid » July 10th, 2018, 3:55 am

main.cpp
-------------

Code: Select all

#include <iostream>

#include "TicTacToeGame.h"
using namespace std;

int main() {



	char input;
	bool isDone = false;

	TicTacToeGame game;

	while (isDone = false) {
		game.playGame();

		cout << "Do you want to play again? Y/N";
		cin >> input;

		if (input == 'N' || input == 'n') {
			isDone = true;
		}
	}
	system("PAUSE");
	return 0;






}

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: TicTacToe Game

Post by albinopapa » July 10th, 2018, 7:20 am

First off, you should upload the entire project and not just copy and paste the files, it makes things way simpler debug and less error prone from us having to create a new project and copy/paste your code to a new project.

If you do need to upload a code snippet, be sure to use the

Code: Select all

[code]
[/code] tags so the code keeps it's formatting, looks nicer and is more readable.

Getting to your issue. You have in your TicTacToeGame::playGame function all the other functions of the class defined. You must have them outside of this function. This is what is meant by "local function definition illegal".

Also, you are going to run into an error with your ( char board ) variable. You are using it as a 2D array ( board[ y ][ x ] ), but you have not declared it as a 2D array: char board[3][3]; in your TicTacToeGame class.

TicTacToeGame.h

Code: Select all

#pragma once

class TicTacToeGame
{
public:
	TicTacToeGame() = default;
	void playGame();

private:
	// xy coord from user
	int getXCoord();
	int getYCoord();

	// places a marker. If false, couldn't place
	bool placeMarker( int x, int y, char currentPlayer );

	// returns true if winner
	bool checkForVictory( char currentPlayer );

	// clear board
	void clearBoard();

	// prints the board
	void printBoard();

private:
	char board[3][3];
};
TicTacToeGame.cpp

Code: Select all

#include "TicTacToeGame.h"
#include <iostream>

using namespace std;

void TicTacToeGame::playGame()
{
	clearBoard();

	const char player1 = 'X';
	const char player2 = 'O';
	char currentPlayer = player1;

	bool isDone = false;
	int turn = 0;

	// inner game loop
	while( isDone == false )
	{
		printBoard();

		// get coordinates
		int x = getXCoord();
		int y = getYCoord();

		// place a marker
		if( placeMarker( x, y, currentPlayer ) == false )
		{
			cout << "There's already something there\n";
		}
		else
		{
			turn++;
			if( checkForVictory( currentPlayer ) == true )
			{
				cout << "Game Over! Player " << currentPlayer << "has won!\n";
				isDone = true;
			}
			else if( turn == 9 )
			{
				cout << "Tied game!\n";
				isDone = true;
			}
		}

		// switch players
		currentPlayer = ( currentPlayer == player1 ) ? player2 : player1;
	}
}

int TicTacToeGame::getXCoord()
{
	bool isInputBad = true;

	int x;

	while( isInputBad == true )
	{
		cout << "Enter the X coordinate: ";
		cin >> x;

		if( x < 1 || x > 3 )
		{
			cout << "Invalid Coordinate!\n";
		}
		else
		{
			isInputBad = false;
		}
	}
	return x - 1;
}

int TicTacToeGame::getYCoord()
{

	bool isInputBad = true;
	int y;
	while( isInputBad = true )
	{
		cout << "Enter the Y Coordinate\n";
		cin >> y;

		if( y < 1 || y > 3 )
		{
			cout << "Invalid coordinate\n";

		}
		else
		{
			isInputBad = false;
		}
	}
	return y - 1;
}

bool TicTacToeGame::placeMarker( int x, int y, char currentPlayer )
{
	if( board[ y ][ x ] != ' ' )
	{
		return false;
	}
	board[ y ][ x ] = currentPlayer;
	return true;
}

bool TicTacToeGame::checkForVictory( char currentPlayer )
{
	// check rows
	for( int i = 0; i < 3; i++ )
	{
		if( ( board[ i ][ 0 ] == currentPlayer ) && ( board[ i ][ 0 ] == board[ i ][ 1 ] ) && ( board[ i ][ 1 ] == board[ i ][ 2 ] ) )
		{
			return true; // won the game

		}
	}

	// check columns
	for( int i = 0; i < 3; i++ )
	{
		if( ( board[ 0 ][ i ] == currentPlayer ) && ( board[ 0 ][ i ] == board[ 1 ][ i ] ) && ( board[ 1 ][ i ] == board[ 2 ][ i ] ) )
		{
			return true; // won the game
		}
	}


	// check top left diagonal
	for( int i = 0; i < 3; i++ )
	{

		if( ( board[ 0 ][ 0 ] == currentPlayer ) && ( board[ 0 ][ 0 ] == board[ 1 ][ 1 ] ) && ( board[ 1 ][ 1 ] == board[ 2 ][ 2 ] ) )
		{
			return true; // won the game
		}
	}


	// check top right diagonal
	for( int i = 0; i < 3; i++ )
	{
		if( ( board[ 2 ][ 0 ] == currentPlayer ) && ( board[ 2 ][ 0 ] == board[ 1 ][ 1 ] ) && ( board[ 1 ][ 1 ] == board[ 0 ][ 2 ] ) )
		{
			return true; // won the game 

		}
		return false;
	}
}

void TicTacToeGame::clearBoard()
{
	//Empties the board
	for( int i = 0; i < 3; i++ )
	{
		for( int j = 0; j < 3; j++ )
		{
			board[ i ][ j ] = ' ';
		}
	}
}

void TicTacToeGame::printBoard()
{
	//formatting
	cout << endl;
	cout << " |1 2 3|\n";
	for( int i = 0; i < 3; i++ )
	{
		cout << " -------\n";
		cout << i + 1 << "|" << board[ i ][ 0 ] << "|" << board[ i ][ 1 ] << "|" << board[ i ][ 2 ] << "|\n";
	}
	cout << " -------\n";
}
main.cpp

Code: Select all

#include <iostream>

#include "TicTacToeGame.h"
using namespace std;

int main()
{
	bool isDone = false;

	TicTacToeGame game;

	while( isDone = false )
	{
		game.playGame();

		cout << "Do you want to play again? Y/N";
		char input;
		cin >> input;

		if( input == 'N' || input == 'n' )
		{
			isDone = true;
		}
	}

	system( "PAUSE" );

	return 0;
}
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: TicTacToe Game

Post by albinopapa » July 10th, 2018, 7:24 am

I copied and pasted the corrected code. Sorry for the formatting being different,

Code: Select all

void IDetest{
    std::cout << "This style of formatting :)";
}
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: TicTacToe Game

Post by albinopapa » July 10th, 2018, 7:28 am

Ok, that's not entirely true. For functions, loops and if/else statements, I detest that style. For initialization of lists, I prefer it.

Code: Select all

void Func()
{
    if( a == b )
    {
        for( int i = 0; i < a; ++i )
        {
        }
    }
    else if( a < b )
    {
        while( true )
        {
            return b;
        }
    }
    else
    {
        c = {
            1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
            0, 9, 8, 7, 6, 5, 4, 3, 2, 1
        };
    }
}
It is personal preference though, so you can ignore this.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
neptunemermaid
Posts: 17
Joined: January 25th, 2015, 7:10 pm
Location: BC, Canada

Re: TicTacToe Game

Post by neptunemermaid » July 10th, 2018, 3:14 pm

Thanks, man! I have developed some bad habits from formatting, so I'll work on that. Ill also keep in mind the copy/paste code thing for next time.

So I'm looking over the code and I'm trying to see what you did differently to fix the problems. It might be too early in the morning but I don't see much difference...

User avatar
neptunemermaid
Posts: 17
Joined: January 25th, 2015, 7:10 pm
Location: BC, Canada

Re: TicTacToe Game

Post by neptunemermaid » July 11th, 2018, 4:26 am

I got the differences, tried to declare my array properly but when i run the program the only thing that happens is a black screen pops up and says "press any key to continue" which is from the pause I put in. Any idea why the game isn't running? Is it still a problem with my 2d array?

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: TicTacToe Game

Post by albinopapa » July 11th, 2018, 5:15 am

Make sure you're in Debug mode.
Set a break point at while( isDone = false ) in the main function in main.cpp
press F11 and see what happens.

F9 will set a break point at the current line the caret or keyboard cursor is on, generally.
F10 will step over a line of code. If the line of code is a function call, it will run the function and stop on the next line.
F11 will step into each line of code. If it's a function, it will enter the function.

These are useful debugging keys. Look at the Locals window to check out current values of variables. Use the Stack window to jump to previously called functions. These windows only show up when you are in Debug mode and have hit a break point.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Post Reply