sorry it's alot to ask but...

Started by
16 comments, last by SirLuthor 18 years, 10 months ago
i know this is alot to ask. but does anyone mind telling me where i went wrong? in this code? i'm not online anymore so i have to come to my brother's house to check up on my email and forum posts and it's also probably why i havent debugged this code yet. this is for a tic tac toe game. i think my problem is in the enum syntax. wich was barely even explained to me in the book iu'm reading. but found several explanations(short ones) inother books i use for refference. please don't stone mefor asking for such a request. i dunno if people help others debug code yet. this is the first time i've asked for help debbugin. this is always the reason for the longest delays in my c++ learning process.... #include <iostream> #include <string> #include <stdlib.h> using namespace std; //introduces namespace std; enum SquareState { blank = ' ', x = 'X', O= 'O'}; class gameBoard { private: const int WIDTH; const int HEIGHT; int* GameBoard; public: gameBoard() : WIDTH(3), HEIGHT(3) ( GameBoard = new int[9]; for (int i = 0; i < 9; i++) *(GameBoard + i) = blank; } ~gameBoard() {delete[] GameBoard;} void setX(int h, int w); void setO(int h, int w); bool isTaken(int h, int w); SquareState isLine(); void draw(); }; void gameBoard::setX(int h, int w) { *(GameBoard + h*HEIGHT + w) = X; } void gameBoard::set0(int h, int w); { *(GameBoard + h*HEIGHT + w) = O; } bool gameBoard::isTaken (int h, int w) { return *(GameBoard + h*HEIGHT + w) != ' '; } SquareState gameBoard::isLine() { if(*GameBoard==X && *(GameBoard +1)==X && *(GameBoard +2)==X) return X; if(*GameBoard==O && *(GameBoard +1)==O && *(GameBoard +2)==O) return O; if(*(GameBoard +3)==X && *(GameBoard +4)==X && *(GameBoard +5)==X) return X; if(*(GameBoard +3)==O && *(GameBoard +4)==O && *(GameBoard +5)==O) return O; if(*(GameBoard +6)==X && *(GameBoard +7)==X && *(GameBoard +8)==X) return X; if(*(GameBoard +6)==O && *(GameBoard +7)==O && *(GameBoard +8)==O) return O; if(*GameBoard==X && *(GameBoard +3)==X && *(GameBoard +6)==X) return X; if(*GameBoard==O && *(GameBoard +3)==O && *(GameBoard +6)==O) return O; if(*(GameBoard +1)==X && *(GameBoard +4)==X && *(GameBoard +7)==X) return X; if(*(GameBoard +1)==O && *(GameBoard +4)==O && *(GameBoard +7)==O) return O; if(*(GameBoard +2)==X && *(GameBoard +5)==X && *(GameBoard +8)==X) return X; if(*(GameBoard +2)==O && *(GameBoard +5)==O && *(GameBoard +8)==O) return O; if(*GameBoard==X && *(GameBoard +4)==X && *(GameBoard +8)==X) return X; if(*GameBoard==O && *(GameBoard +4)==O && *(GameBoard +8)==O) return O; if(*(GameBoard +2)==X && *(GameBoard +4)==X && *(GameBoard +6)==X) return X; if(*(GameBoard +2)==O && *(GameBoard +4)==O && *(GameBoard +6)==O) return O; return blank; } void gameBoard::draw()// proofread here { cout << endl; for(int i=0; i < HEIGHT; i++) { cout << (char)*(GameBoard + i*HEIGHT); for(int c=1; c < WIDTH; c++) cout << " | " << (char)*(GameBoard + i*WIDTH + c); cout << endl << "-------"<< endl; } } class Game { public: gameBoard* doInput(string player, gameBoard* gb); bool inRange(int test); }; gameBoard* Game::doInput(string player, gameBoard* gb) { gb->draw(); string letter; if(player.compare("one") == 0) letter = "X"; else if (player.compare("two") == 0) letter = "O"; else return gb; int input1, input2; do{ do{ cout << "\nPlayer " << player.c_str() << ", please enter a row number to put an " << letter.c_str() << ": "; cin >> input1; }while(!inRange(input1)); do { cout << "\nPlease enter a column number to put an " << letter.c_str() << ": "; cin << input2; }while(!inRange(input2)); }while(gb->isTaken(input1, input2)); if (player.compare("one") == 0) gb->setX(input1, input2); else gb->set0(input1, input2); return gb; } bool Game::inRange(int test) { return test > -1 && test < 3; } int main( void ) { gameBoard* gb = new gameBoard; Game g; string player1, player2; cout << "Welcome to Tic Tac Toe!" << "\nPlayer one, please enter your name: "; cin >> player1; cout << "\nPlayer two, please enter your name: "; cin >> player2; while (gb->isLine() == ' ') { gb = g.doInput("one",gb); gb = g.doInput("two",gb); } gb->draw(); if(gb->isLine()==X) cout << "\nPlayer one, you win!" << "\nGame Over."; else cout << "\nPlayer two, you win!" << "\nGame Over."; system("pause"); return 0; }
__________________________________________________________Maybe one day i can not be affraid of venturing out of the beginners section.
Advertisement
It would help if you told us what kind of error you are getting. Does the program not compile? Does it crash when you run it? If so, when does it crash? Does it not print the correct output?

I just noticed one thing that might be a reason why it won't compile. The '(' must be a '{' on the line after: "gameBoard() : WIDTH(3), HEIGHT(3"
Two things:

  1. Use the [source lang="cpp"] and [/source]

  2. Post the error(s) you're getting

sorry using my brother's compiler i'm getting lots of new errors. and i have to go now too cause they're going to sleep. i can let you know what happens tomorrow and check for replies. i've also cleaned the code up a bit.(i think)


 #include <iostream>#include <string>#include <stdlib.h>using namespace std;        //introduces namespace std;enum SquareState { blank = ' ', x = 'X', O= 'O'};class gameBoard{    private:		const int WIDTH;		const int HEIGHT;		int* GameBoard;	public:		gameBoard() : WIDTH(3), HEIGHT(3)		{			GameBoard = new int[9];			for (int i = 0; i < 9; i++)			*(GameBoard + i) = blank;        		}		~gameBoard() {delete[] GameBoard;}		void setX(int h, int w);		void setO(int h, int w);		bool isTaken(int h, int w);		SquareState isLine();		void draw();	};	void gameBoard::setX(int h, int w)	{		*(GameBoard + h*HEIGHT + w) = X;			}	void gameBoard::setO(int h, int w);	{		*(GameBoard + h*HEIGHT + w) = O;	}	bool gameBoard::isTaken (int h, int w)	{		return *(GameBoard + h*HEIGHT + w) != ' ';	}	SquareState gameBoard::isLine()	{		if(*GameBoard==X && *(GameBoard +1)==X && *(GameBoard +2)==X)			return X;		if(*GameBoard==O && *(GameBoard +1)==O && *(GameBoard +2)==O)			return O;		if(*(GameBoard +3)==X && *(GameBoard +4)==X && *(GameBoard +5)==X)			return X;		if(*(GameBoard +3)==O && *(GameBoard +4)==O && *(GameBoard +5)==O)			return O;		if(*(GameBoard +6)==X && *(GameBoard +7)==X && *(GameBoard +8)==X)			return X;		if(*(GameBoard +6)==O && *(GameBoard +7)==O && *(GameBoard +8)==O)			return O;		if(*GameBoard==X && *(GameBoard +3)==X && *(GameBoard +6)==X)			return X;		if(*GameBoard==O && *(GameBoard +3)==O && *(GameBoard +6)==O)			return O;		if(*(GameBoard +1)==X && *(GameBoard +4)==X && *(GameBoard +7)==X)			return X;		if(*(GameBoard +1)==O && *(GameBoard +4)==O && *(GameBoard +7)==O)			return O;		if(*(GameBoard +2)==X && *(GameBoard +5)==X && *(GameBoard +8)==X)			return X;		if(*(GameBoard +2)==O && *(GameBoard +5)==O && *(GameBoard +8)==O)			return O;		if(*GameBoard==X && *(GameBoard +4)==X && *(GameBoard +8)==X)			return X;		if(*GameBoard==O && *(GameBoard +4)==O && *(GameBoard +8)==O)			return O;		if(*(GameBoard +2)==X && *(GameBoard +4)==X && *(GameBoard +6)==X)			return X;		if(*(GameBoard +2)==O && *(GameBoard +4)==O && *(GameBoard +6)==O)			return O;		return blank;	}	void gameBoard::draw()// proofread here	{		cout << endl;		for(int i=0; i < HEIGHT; i++)		{			cout << (char)*(GameBoard + i*HEIGHT);			for(int c=1; c < WIDTH; c++)			cout << " | " << (char)*(GameBoard + i*WIDTH + c);		cout << endl << "-------"<< endl;		}	}	class Game	{	public:		gameBoard* doInput(string player, gameBoard* gb);		bool inRange(int test);	};	gameBoard* Game::doInput(string player, gameBoard* gb)	{		gb->draw();		string letter;		if(player.compare("one") == 0)			letter = "X";		else if (player.compare("two") == 0)			letter = "O";		else return gb;		int input1, input2;		do{			do{				cout << "\nPlayer " << player.c_str()					<< ", please enter a row number to put an "					<< letter.c_str() << ": ";				cin >> input1;			}while(!inRange(input1));			do {				cout << "\nPlease enter a column number to put an "					<< letter.c_str() << ": ";				cin << input2;			}while(!inRange(input2));		}while(gb->isTaken(input1, input2));		if (player.compare("one") == 0)			gb->setX(input1, input2);		else gb->setO(input1, input2);		return gb;	}	bool Game::inRange(int test)	{		return test > -1 && test < 3;	}int main( void ){	gameBoard* gb = new gameBoard;	Game g;	string player1, player2;	cout << "Welcome to Tic Tac Toe!"		<< "\nPlayer one, please enter your name: ";	cin >> player1;	cout << "\nPlayer two, please enter your name: ";	cin >> player2;	while (gb->isLine() == ' ')	{		gb = g.doInput("one",gb);		gb = g.doInput("two",gb);	}		gb->draw();	if(gb->isLine()==X)		cout << "\nPlayer one, you win!"			<< "\nGame Over.";	else cout << "\nPlayer two, you win!"			<< "\nGame Over.";	system("pause");	return 0;}
__________________________________________________________Maybe one day i can not be affraid of venturing out of the beginners section.
I didn't look over all your code, but in your enum declaration you have 'x', as opposed to the rest of the code in which you have 'X'.

HTH,
nilkn
Not that bad! You are actually really close to being done. Take a look at a few things I have marked, there is a lot more that should be fixed in terms of handling proper input and stuff, but for now it's good.

#include <iostream>#include <string>//#include <stdlib.h>//// We can use the modern version as well#include <cstdlib>//introduces namespace std;//using namespace std;//// For now, I did not//// Good idea, but needs revision//enum SquareState { blank = ' ', x = 'X', O= 'O'};enum SquareState { Blank = ' ', X = 'X', O = 'O' };class gameBoard{private:	const int WIDTH;	const int HEIGHT;	int* GameBoard;public:	gameBoard() : WIDTH(3), HEIGHT(3)	{		//// Oh no, what happened here!?!		/*GameBoard = new int[9];		for (int i = 0; i < 9; i++)		*(GameBoard + i) = blank;*/		//// Since we have a width and height, use it! 		//// I also changes the blank to Blank for consistancy		GameBoard = new int[ WIDTH * HEIGHT ];		for (int i = 0; i <  WIDTH * HEIGHT; i++)			*(GameBoard + i) = Blank;	}		//// Good! But you always want to change the memory first!	//// Yes I know this will only fail if the ctor fails, but	//// always be prepeared	~gameBoard()	{		if( GameBoard )			delete[] GameBoard;	}	void setX(int h, int w);	void setO(int h, int w);	bool isTaken(int h, int w);	SquareState isLine();	void draw();};void gameBoard::setX(int h, int w){	*(GameBoard + h*HEIGHT + w) = X;	//// More friendly, but to each his own [smile]	//// GameBoard[h*HEIGHT + w] = X;}void gameBoard::setO(int h, int w){	*(GameBoard + h*HEIGHT + w) = O;	//// More friendly, but to each his own [smile]	//// GameBoard[h*HEIGHT + w] = 0;}bool gameBoard::isTaken (int h, int w){	return *(GameBoard + h*HEIGHT + w) != ' ';}//// Looks like it should work...SquareState gameBoard::isLine(){	if(*GameBoard==X && *(GameBoard +1)==X && *(GameBoard +2)==X)		return X;	if(*GameBoard==O && *(GameBoard +1)==O && *(GameBoard +2)==O)		return O;	if(*(GameBoard +3)==X && *(GameBoard +4)==X && *(GameBoard +5)==X)		return X;	if(*(GameBoard +3)==O && *(GameBoard +4)==O && *(GameBoard +5)==O)		return O;	if(*(GameBoard +6)==X && *(GameBoard +7)==X && *(GameBoard +8)==X)		return X;	if(*(GameBoard +6)==O && *(GameBoard +7)==O && *(GameBoard +8)==O)		return O;	if(*GameBoard==X && *(GameBoard +3)==X && *(GameBoard +6)==X)		return X;	if(*GameBoard==O && *(GameBoard +3)==O && *(GameBoard +6)==O)		return O;	if(*(GameBoard +1)==X && *(GameBoard +4)==X && *(GameBoard +7)==X)		return X;	if(*(GameBoard +1)==O && *(GameBoard +4)==O && *(GameBoard +7)==O)		return O;	if(*(GameBoard +2)==X && *(GameBoard +5)==X && *(GameBoard +8)==X)		return X;	if(*(GameBoard +2)==O && *(GameBoard +5)==O && *(GameBoard +8)==O)		return O;	if(*GameBoard==X && *(GameBoard +4)==X && *(GameBoard +8)==X)		return X;	if(*GameBoard==O && *(GameBoard +4)==O && *(GameBoard +8)==O)		return O;	if(*(GameBoard +2)==X && *(GameBoard +4)==X && *(GameBoard +6)==X)		return X;	if(*(GameBoard +2)==O && *(GameBoard +4)==O && *(GameBoard +6)==O)		return O;	return Blank;}void gameBoard::draw()// proofread here{	std::cout << std::endl;	for(int i=0; i < HEIGHT; i++)	{		std::cout << (char)*(GameBoard + i*HEIGHT);		for(int c=1; c < WIDTH; c++)			std::cout << " | " << (char)*(GameBoard + i*WIDTH + c);		//std::cout << std::endl << "-------"<< std::endl;		//// You just needed two more here ;)		std::cout << std::endl << "---------"<< std::endl;	}}class Game{public:	gameBoard* doInput(std::string player, gameBoard* gb);	bool inRange(int test);};gameBoard* Game::doInput(std::string player, gameBoard* gb){	gb->draw();	std::string letter;	if(player.compare("one") == 0)		letter = "X";	else if (player.compare("two") == 0)		letter = "O";	else return gb;	int input1, input2;	do{		do{			std::cout << "\nPlayer " << player.c_str()				<< ", please enter a row number to put an "				<< letter.c_str() << ": ";			std::cin >> input1;		}while(!inRange(input1));		do {			std::cout << "\nPlease enter a column number to put an "				<< letter.c_str() << ": ";			//// Eeeek!! Wrong way!			//std::cin << input2;			std::cin >> input2;		}while(!inRange(input2));	}while(gb->isTaken(input1, input2));	if (player.compare("one") == 0)		gb->setX(input1, input2);	else gb->setO(input1, input2);	return gb;}bool Game::inRange(int test){	return test > -1 && test < 3;}int main( void ){	gameBoard* gb = new gameBoard;	Game g;	std::string player1, player2;	std::cout << "Welcome to Tic Tac Toe!" << "\nPlayer one, please enter your name: ";	std::cin >> player1;	std::cout << "\nPlayer two, please enter your name: ";	std::cin >> player2;	while (gb->isLine() == ' ')	{		gb = g.doInput("one",gb);		gb = g.doInput("two",gb);	}	gb->draw();	if(gb->isLine()==X)		std::cout << "\nPlayer one, you win!" << "\nGame Over.";	else std::cout << "\nPlayer two, you win!" << "\nGame Over.";		system("pause");	return 0;}


That runs for me just fine, the main thing that you do need to fix is to check for a win after each player move, not after both players have gone their turn.

With that program, there's a mixture of C and Standard C++, I would reccomend using all standard C++ stuff to take care of it (such as use a vector rather than int*).

Once you look over that, you can get more ideas of what to do to improve from the community. So good job almost getting it all done, keep at it!
Quote:Original post by Drew_Benton
//// Good! But you always want to change the memory first!
//// Yes I know this will only fail if the ctor fails, but
//// always be prepeared
~gameBoard()
{
if( GameBoard )
delete[] GameBoard;
}


I don't think the check is EVER necessary. Consider the three possible cases:

If you don't initialize your pointer, it will have garbage data and the if statement will evaluate to true anyway ( since it's not equal to zero ), causing your program to crash and having the same effect as not including the if statement at all

If you DO initialize it with new memory then it will of course delete it correctly.

Finally, if you initialize it to zero then the delete[] will have no effect whatsoever since deleting a null pointer is a NO-OP

I used to do this too, until I realized that it is completely useless.
Why do people always do this? Was delete[] not always a NO-OP with a NULL pointer? Anyone know?
Quote:Original post by Drew_Benton
Not that bad! You are actually really close to being done. Take a look at a few things I have marked, there is a lot more that should be fixed in terms of handling proper input and stuff, but for now it's good.

*** Source Snippet Removed ***

That runs for me just fine, the main thing that you do need to fix is to check for a win after each player move, not after both players have gone their turn.

With that program, there's a mixture of C and Standard C++, I would reccomend using all standard C++ stuff to take care of it (such as use a vector rather than int*).

Once you look over that, you can get more ideas of what to do to improve from the community. So good job almost getting it all done, keep at it!



read over the code and it looks interesting. sorry to disapoint you but i only copied that out of a book as part of an assignmet and couldnt even retype what i've read right!!! unless theyve intentionaly put errors in the code so i can fix it. funny thing wass that there were a whole buncha errors in visualstudio but i also edited it in codeblocks as well and fixed some errors and it xecuted. but still wouldnt execute in visual studio. very weird.

i think i will be looking over this code and figuring out why it works for a while. i read somewhere on this forum that it's not that important to know thw syntax of the code as long as you know what it does. i kinda know what things do but i dont always recognise them when i'm doing assignments. c++ is kinda hard. i have lots of studying to do. maybe the book i'm reading is so straight foreward to the point that i'm taking in too much at one time and not really learning how to use the stuff??
__________________________________________________________Maybe one day i can not be affraid of venturing out of the beginners section.
Quote:Original post by averisk
Quote:Original post by Drew_Benton
//// Good! But you always want to change the memory first!
//// Yes I know this will only fail if the ctor fails, but
//// always be prepeared
~gameBoard()
{
if( GameBoard )
delete[] GameBoard;
}


I don't think the check is EVER necessary. Consider the three possible cases:

If you don't initialize your pointer, it will have garbage data and the if statement will evaluate to true anyway ( since it's not equal to zero ), causing your program to crash and having the same effect as not including the if statement at all

If you DO initialize it with new memory then it will of course delete it correctly.

Finally, if you initialize it to zero then the delete[] will have no effect whatsoever since deleting a null pointer is a NO-OP

I used to do this too, until I realized that it is completely useless.
Why do people always do this? Was delete[] not always a NO-OP with a NULL pointer? Anyone know?

You are right. The destructor won't be called if the constructor fails (throws an error). Checking if the pointer is not null before delete is pointless because delete/free does this for you.
Initializing it to null would be pointless in this case too. The destructor would only be called if the constructor succeeded, and if the constructor succeeded the pointer would be valid. Thus is it pointless.

I don't know why people keep on checking if the pointer is not null before they delete it. Probably just a bad habit learned by some online code/tutorial.
ok gonna go back and learnmore about pointers and arrays(?)...
__________________________________________________________Maybe one day i can not be affraid of venturing out of the beginners section.

This topic is closed to new replies.

Advertisement