Sign in to follow this  
simon10k

Source for my TicTacToe game

Recommended Posts

simon10k    220
tictactoe.cpp
#include <iostream>
#include <windows.h>
using namespace std;

void init();
void draw();
bool set(char, int, int);
bool line();
bool gameover(char*);
bool player();
bool computer();
bool proceed();
void TicTacToe();
void clrscr();

char board[3][3];
int moves;
int player_score = 0;
int comp_score = 0;

void init()
{
	for(int x=0; x<3; ++x)
		for(int y=0; y<3; ++y)
			board[x][y] = ' ';

	moves = 0;
	draw();
}

void draw()
{
	clrscr();
	cout << "Player: " << player_score << ", Computer: " << comp_score << "\n\n";	

	cout << board[0][0] << '|' << board[1][0] << '|' << board[2][0] << '\n';
	cout << "- - -\n";
	cout << board[0][1] << '|' << board[1][1] << '|' << board[2][1] << '\n';
	cout << "- - -\n";
	cout << board[0][2] << '|' << board[1][2] << '|' << board[2][2] << "\n\n";		
}

bool set(char i, int x, int y)
{
	if(x < 0 || x > 2 || y < 0 || y > 2 || board[x][y] != ' ')
		return false;

	board[x][y] = i;
	++moves;

	return true;
}

bool line()
{
	if(board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2]) 		
		return true;

	if(board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0])
		return true;  

	for(int x=0; x<3; ++x)
		if(board[x][0] != ' ' && board[x][0] == board[x][1] && board[x][1] == board[x][2])			
			return true;

	for(int y=0; y<3; ++y)
		if(board[0][y] != ' ' && board[0][y] == board[1][y] && board[1][y] == board[2][y])
			return true;

	return false;
}

bool gameover(char* winner)
{    
	if(line())
	{
		draw();
		cout << winner << '\n';
		return true;
	}
	else if(moves == 9)
	{	
		draw();
		cout << "No winner.\n";
		return true;
	}

	return false;
}

bool player()
{
	while(true)
	{
		cout << "Enter position: ";

		int x, y;		
		cin >> x >> y;	

		if(cin.bad())
			exit(1);

		if(cin.fail())
		{
			cin.clear();
			while(cin.get() != '\n');
			draw();
			continue;
		}

		while(cin.get() != '\n');		

		if(set('O', x, y))
			break;

		draw();
	}

	if(gameover("You have won the game."))
	{
		if(moves != 9)
			++player_score;

		return false;
	}

	return true;	
}

bool computer()
{
	while(true)
	{
		int x = rand()%3;
		int y = rand()%3;

		if(set('X', x, y))
			break;
	}

	if(gameover("Computer has won the game."))
	{
		if(moves != 9)
			++comp_score;
		return false;
	}
	return true;
}

bool proceed()
{
	int tries = 0;
	while(tries++ < 3)
	{
		cout << "Continue (y/n)? ";

		char answer;
        cin >> answer;	
		
		if(cin.bad())
			exit(1);
		
		if(cin.fail())
		{
			cin.clear();
			while(cin.get() != '\n');	
			draw();
			continue;
		}

		while(cin.get() != '\n');	

		switch(answer)
		{
			case 'y':
			case 'Y':
				return true;

			case 'n':
			case 'N':
				return false;

			default:
				draw();
				cout << "Enter y or n.\n";				
		}		
	}

	draw();
    cout << "I'll take that for a no.\n";
	return false;
}

void TicTacToe()
{
	while(true)
	{
		init();

		while(player() && computer())
			draw();

		if(!proceed())
			break;
	}

	cout << endl;
}

void clrscr( )
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD coordScreen = { 0, 0 };    

    DWORD cCharsWritten;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD dwConSize;

    GetConsoleScreenBufferInfo( hConsole, &csbi );   
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;

    FillConsoleOutputCharacter( hConsole, (TCHAR) ' ',
				dwConSize, coordScreen, &cCharsWritten );   

    GetConsoleScreenBufferInfo( hConsole, &csbi );   

    FillConsoleOutputAttribute( hConsole, csbi.wAttributes,
				dwConSize, coordScreen, &cCharsWritten );  

    SetConsoleCursorPosition( hConsole, coordScreen );   
 }

main.cpp
void TicTacToe();

int main()
{
	TicTacToe();	
}

Thought it might help some peeps, you can comment if you want.

Share this post


Link to post
Share on other sites
jonahrowley    300
The computer player is completely random? Anything would be better than that, at the very least something that tries to block my moves and tries to win itself. It would be easy to fool, but you could probably do that in just a few lines of code. There are other algorithms that are unbeatable, and they're not even very difficult.

Other than that, looks good!

Share this post


Link to post
Share on other sites
jonahrowley    300
Yes, I win every time. I hadn't actually played it before my last post, so a few suggestions. The player moves first, he should be X! I moved and expected my move to be X (since I went first) and was very confused to see the X went somewhere else. Also, the coordinates might be handy for an array index, but not for the human player. Use the number pad layout (5 is center square, 7 is top left, etc) and use a lookup table.

Use something like this:

int keypad_lookup_table[2][] = {
{ 0,2 },
{ 1,2 },
{ 2,2 },
{ 0,1 },
{ 1,1 },
{ 2,1 },
{ 0,0 },
{ 1,0 },
{ 2,0 }
};

int* keypad_lookup( int k ) {
return keypad_lookup_table[ (k-1) % 9 ];
}

Share this post


Link to post
Share on other sites
simon10k    220
I know the game as "Noughts and Crosses" so it is natural for me to think O goes first. As for the numpad, I agree but laptops don't have numpads (or atleast mine doesn't). Thanks for the suggestions though.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this