PDA

View Full Version : My Third Game finished


Loregoreth
08-21-2006, 12:31 PM
I have completed my third game, Tic-Tac-Toe. I think the AI is unbeatable, well I haven't beat it yet. It took about a month to finish in C++. If you wish to download it.
http://www.madgamedesign.com/Tic-Tac-Toe.ace
http://www.madgamedesign.com/Tic-Tac-Toe.exe

The source is a total of 831 lines.
I tried to make it easy to read.

#include <iostream>
#include <math.h>
#include <string>
using namespace std;


int usermove;
int game (1);
int move1;
int move2;
int move3;
int move4;
int move5;
int move6;
int move7;
int move8;
int move9;
string player;

class Box
{
public:
char fill;
int value;

};
Box box[9];
void lose()
{
int quit;
cout << box[6].fill << "|" << box[7].fill << "|" << box[8].fill << "\n";
cout << "-----\n";
cout << box[3].fill << "|" << box[4].fill << "|" << box[5].fill << "\n";
cout << "-----\n";
cout << box[0].fill << "|" << box[1].fill << "|" << box[2].fill << "\n\n";
cout << "You have lost Muhahahaha!!!!!!!!!\n";
cout << "Press any key to quit.\n";
cin >> quit;
if(quit != '*')
{
game = 2;
}
}
void win()
{
int quit;
cout << box[6].fill << "|" << box[7].fill << "|" << box[8].fill << "\n";
cout << "-----\n";
cout << box[3].fill << "|" << box[4].fill << "|" << box[5].fill << "\n";
cout << "-----\n";
cout << box[0].fill << "|" << box[1].fill << "|" << box[2].fill << "\n\n";
cout << "Congratulations, ";
cout << player;
cout << ", You have won! \n \n";
cout << "Press any key to quit.\n";
cin >> quit;
if(quit != '*')
{
game = 2;
}
}
void checkwin()
{
//Checks to see if the player could win.
if (box[0].fill == 'X' && box[1].fill == 'X' && box[2].fill == ' ')
{
box[2].value += 100;
}
if (box[0].fill == 'X' && box[1].fill == ' ' && box[2].fill == 'X')
{
box[1].value += 100;
}
if (box[0].fill == ' ' && box[1].fill == 'X' && box[2].fill == 'X')
{
box[0].value += 100;
}
if (box[3].fill == ' ' && box[4].fill == 'X' && box[5].fill == 'X')
{
box[3].value += 100;
}
if (box[3].fill == 'X' && box[4].fill == ' ' && box[5].fill == 'X')
{
box[4].value += 100;
}
if (box[3].fill == 'X' && box[4].fill == 'X' && box[5].fill == ' ')
{
box[5].value += 100;
}
if (box[6].fill == 'X' && box[7].fill == ' ' && box[8].fill == 'X')
{
box[7].value += 100;
}
if (box[6].fill == ' ' && box[7].fill == 'X' && box[8].fill == 'X')
{
box[6].value += 100;
}
if (box[6].fill == 'X' && box[7].fill == 'X' && box[8].fill == ' ')
{
box[8].value += 100;
}
if (box[0].fill == 'X' && box[3].fill == 'X' && box[6].fill == ' ')
{
box[6].value += 100;
}
if (box[0].fill == 'X' && box[3].fill == ' ' && box[6].fill == 'X')
{
box[3].value += 100;
}
if (box[0].fill == ' ' && box[3].fill == 'X' && box[6].fill == 'X')
{
box[0].value += 100;
}
if (box[1].fill == ' ' && box[4].fill == 'X' && box[7].fill == 'X')
{
box[1].value += 100;
}
if (box[1].fill == 'X' && box[4].fill == ' ' && box[7].fill == 'X')
{
box[4].value += 100;
}
if (box[1].fill == 'X' && box[4].fill == 'X' && box[7].fill == ' ')
{
box[7].value += 100;
}
if (box[2].fill == 'X' && box[5].fill == ' ' && box[8].fill == 'X')
{
box[5].value += 100;
}
if (box[2].fill == ' ' && box[5].fill == 'X' && box[8].fill == 'X')
{
box[2].value += 100;
}
if (box[2].fill == 'X' && box[5].fill == 'X' && box[8].fill == ' ')
{
box[8].value += 100;
}
if (box[0].fill == ' ' && box[4].fill == 'X' && box[8].fill == 'X')
{
box[0].value += 100;
}
if (box[0].fill == 'X' && box[4].fill == ' ' && box[8].fill == 'X')
{
box[4].value += 100;
}
if (box[0].fill == 'X' && box[4].fill == 'X' && box[8].fill == ' ')
{
box[8].value += 100;
}
if (box[2].fill == ' ' && box[4].fill == 'X' && box[6].fill == 'X')
{
box[2].value += 100;
}
if (box[2].fill == 'X' && box[4].fill == ' ' && box[6].fill == 'X')
{
box[4].value += 100;
}
if (box[2].fill == 'X' && box[4].fill == 'X' && box[6].fill == ' ')
{
box[6].value += 100;
}
}

void checklose()
{
if (box[0].fill == '0' && box[1].fill == '0' && box[2].fill == '0')
{
lose();
}
if (box[0].fill == '0' && box[4].fill == '0' && box[8].fill == '0')
{
lose();
}
if (box[0].fill == '0' && box[3].fill == '0' && box[6].fill == '0')
{
lose();
}
if (box[1].fill == '0' && box[4].fill == '0' && box[7].fill == '0')
{
lose();
}
if (box[2].fill == '0' && box[5].fill == '0' && box[8].fill == '0')
{
lose();
}
if (box[2].fill == '0' && box[4].fill == '0' && box[6].fill == '0')
{
lose();
}
if (box[3].fill == '0' && box[4].fill == '0' && box[5].fill == '0')
{
lose();
}
if (box[6].fill == '0' && box[7].fill == '0' && box[8].fill == '0')
{
lose();
}
}
void play ()
{
if(game == 1)
{
cout << box[6].fill << "|" << box[7].fill << "|" << box[8].fill << "\n";
cout << "-----\n";
cout << box[3].fill << "|" << box[4].fill << "|" << box[5].fill << "\n";
cout << "-----\n";
cout << box[0].fill << "|" << box[1].fill << "|" << box[2].fill << "\n\n";
cout << player;
cout << " It is your turn where do you want to move?\n\n";
cin >> usermove;
cout << "\n\n\n\n";
switch(usermove)
{
case 1:
if (box[0].fill == ' ')
{
box[0].fill = 'X';
box[0].value = 0;
checkwin();
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
// Checks to see if the player has won.
if (box[0].fill == 'X' && box[1].fill == 'X' && box[2].fill == 'X')
{
win();
}
if (box[0].fill == 'X' && box[4].fill == 'X' && box[8].fill == 'X')
{
win();
}
if (box[0].fill == 'X' && box[3].fill == 'X' && box[6].fill == 'X')
{
win();
}
}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
case 2:
if (box[1].fill == ' ')
{
box[1].fill = 'X';
box[1].value = 0;
checkwin();
if (box[0].fill == ' ' && box[1].fill == 'X' && box[2].fill == ' ')
{
box[0].value += 1;
box[2].value += 1;
}
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
// Checks to see if the player has won.
if (box[0].fill == 'X' && box[1].fill == 'X' && box[2].fill == 'X')
{
win();
}
if (box[1].fill == 'X' && box[4].fill == 'X' && box[7].fill == 'X')
{
win();
}
}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
case 3:
if (box[2].fill == ' ')
{
box[2].fill = 'X';
box[2].value = 0;
checkwin();
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
// Checks to see if the player has won.
if (box[0].fill == 'X' && box[1].fill == 'X' && box[2].fill == 'X')
{
win();
}
if (box[2].fill == 'X' && box[4].fill == 'X' && box[6].fill == 'X')
{
win();
}
if (box[2].fill == 'X' && box[5].fill == 'X' && box[8].fill == 'X')
{
win();
}
}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
case 4:
if (box[3].fill == ' ')
{
box[3].fill = 'X';
box[3].value = 0;
checkwin();
if (box[0].fill == ' ' && box[3].fill == 'X' && box[6].fill == ' ')
{
box[0].value += 1;
box[6].value += 1;
}
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
// Checks to see if the player has won.
if (box[3].fill == 'X' && box[4].fill == 'X' && box[5].fill == 'X')
{
win();
}
if (box[0].fill == 'X' && box[3].fill == 'X' && box[6].fill == 'X')
{
win();
}
}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
case 5:
if (box[4].fill == ' ')
{
box[4].fill = 'X';
box[4].value = 0;
checkwin();
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
// Checks to see if the player has won.
if (box[0].fill == 'X' && box[4].fill == 'X' && box[8].fill == 'X')
{
win();
}
if (box[1].fill == 'X' && box[4].fill == 'X' && box[7].fill == 'X')
{
win();
}
if (box[2].fill == 'X' && box[4].fill == 'X' && box[6].fill == 'X')
{
win();
}
if (box[5].fill == 'X' && box[4].fill == 'X' && box[3].fill == 'X')
{
win();
}
}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
case 6:
if (box[5].fill == ' ')
{
box[5].fill = 'X';
box[5].value = 0;
checkwin();
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == ' ' && box[5].fill == 'X' && box[8].fill == ' ')
{
box[2].value += 1;
box[8].value += 1;
}
// Checks to see if the player has won.
if (box[5].fill == 'X' && box[4].fill == 'X' && box[3].fill == 'X')
{
win();
}
if (box[5].fill == 'X' && box[8].fill == 'X' && box[2].fill == 'X')
{
win();
}
}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
case 7:
if (box[6].fill == ' ')
{
box[6].fill = 'X';
box[6].value = 0;
checkwin();
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == ' ' && box[1].fill == ' ' && box[2].fill == ' ' && box[3].fill == ' ' && box[4].fill == ' ' && box[5].fill == ' ' && box[6].fill == 'X' && box[7].fill == ' ' && box[8].fill == ' ')
{
box[4].value += 3;
}
// Checks to see if the player has won.
if (box[6].fill == 'X' && box[7].fill == 'X' && box[8].fill == 'X')
{
win();
}
if (box[6].fill == 'X' && box[3].fill == 'X' && box[0].fill == 'X')
{
win();
}
if (box[6].fill == 'X' && box[4].fill == 'X' && box[2].fill == 'X')
{
win();
}
}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
case 8:
if (box[7].fill == ' ')
{
box[7].fill = 'X';
box[7].value = 0;
checkwin();
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == ' ' && box[7].fill == 'X' && box[8].fill == ' ')
{
box[6].value += 1;
box[8].value += 1;
}
// Checks to see if the player has won.
if (box[6].fill == 'X' && box[7].fill == 'X' && box[8].fill == 'X')
{
win();
}
if (box[7].fill == 'X' && box[4].fill == 'X' && box[1].fill == 'X')
{
win();
}

}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
case 9:
if (box[8].fill == ' ')
{
box[8].fill = 'X';
box[8].value = 0;
checkwin();
if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[6].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[2].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}
if (box[0].fill == ' ' && box[1].fill == ' ' && box[2].fill == ' ' && box[3].fill == ' ' && box[4].fill == ' ' && box[5].fill == ' ' && box[6].fill == ' ' && box[7].fill == ' ' && box[8].fill == 'X')
{
box[4].value += 3;
}
// Checks to see if the player has won.
if (box[6].fill == 'X' && box[7].fill == 'X' && box[8].fill == 'X')
{
win();
}
if (box[8].fill == 'X' && box[4].fill == 'X' && box[0].fill == 'X')
{
win();
}
if (box[8].fill == 'X' && box[5].fill == 'X' && box[2].fill == 'X')
{
win();
}
}
else
{
cout << player;
cout << " that tile is already filled. \n\n";
play();
}
break;
default:
cout << "Sorry, you must enter a number 1-9.\n\n\n\n";
play();
}
// Here the AI finds the highest value by process of emlination.
if(box[0].value - box[1].value >= 0)
{
move1 = box[0].value;
}
else
{
move1 = box[1].value;
}
//**************************************
if(box[2].value - box[3].value >= 0)
{
move2 = box[2].value;
}
else
{
move2 = box[3].value;
}
//**************************************
if(box[4].value - box[5].value >= 0)
{
move3 = box[4].value;
}
else
{
move3 = box[5].value;
}
//**************************************
if(box[6].value - box[7].value >= 0)
{
move4 = box[6].value;
}
else
{
move4 = box[7].value;
}
//**************************************
if(move1 - move2 >= 0)
{
move6 = move1;
}
else
{
move6 = move2;
}
//**************************************
if(move3 - move4 >= 0)
{
move7 = move3;
}
else
{
move7 = move4;
}
//**************************************
if(move6 - move7 >= 0)
{
move8 = move6;
}
else
{
move8 = move7;
}
//**************************************
if(box[8].value - move8 >= 0)
{
move9 = box[8].value;
}
else
{
move9 = move8;
}
//*****************
//Now the AI moves*
//*****************
if(move9 == box[0].value && box[0].fill == ' ')
{
box[0].fill = '0';
box[0].value = 0;
checklose();
play();
}
else if(move9 == box[1].value && box[1].fill == ' ')
{
box[1].fill = '0';
box[1].value = 0;
checklose();
play();
}
else if(move9 == box[2].value && box[2].fill == ' ')
{
box[2].fill = '0';
box[2].value = 0;
checklose();
play();
}
else if(move9 == box[3].value && box[3].fill == ' ')
{
box[3].fill = '0';
box[3].value = 0;
checklose();
play();
}
else if(move9 == box[4].value && box[4].fill == ' ')
{
box[4].fill = '0';
box[4].value = 0;
checklose();
play();
}
else if(move9 == box[5].value && box[5].fill == ' ')
{
box[5].fill = '0';
box[5].value = 0;
checklose();
play();
}
else if(move9 == box[6].value && box[6].fill == ' ')
{
box[6].fill = '0';
box[6].value = 0;
checklose();
play();
}
else if(move9 == box[7].value && box[7].fill == ' ')
{
box[7].fill = '0';
box[7].value = 0;
checklose();
play();
}
else if(move9 == box[8].value && box[8].fill == ' ')
{
box[8].fill = '0';
box[8].value = 0;
checklose();
play();
}
}
//*****************************************
}
void valuefill ()
{
box[0].fill = ' ';
box[1].fill = ' ';
box[2].fill = ' ';
box[3].fill = ' ';
box[4].fill = ' ';
box[5].fill = ' ';
box[6].fill = ' ';
box[7].fill = ' ';
box[8].fill = ' ';
box[0].value = 3;
box[1].value = 2;
box[2].value = 3;
box[3].value = 2;
box[4].value = 4;
box[5].value = 2;
box[6].value = 3;
box[7].value = 2;
box[8].value = 3;
play ();
}
int main ()
{
int start;
cout << "********************************\n";
cout << "********************************\n";
cout << "** Welcome to Tic Tac Toe 1.0 **\n";
cout << "********************************\n";
cout << "*********** 1. Play ************\n";
cout << "******** 2. How to Play ********\n";
cout << "*********** 3. Exit ************\n";
cout << "********************************\n";
cout << "********************************\n";
cin >> start;
if(start == 1)
{
cout << "What is your player name? \n";
cin >> player;
cout << "Thanks " << player <<".\n";
valuefill ();
}
else if(start == 2)
{
int play;
cout << "Here is what the game board looks like. The numbers\nyou see in each box are the numbers you will type\nin to place your letter in that box.\n\n";
cout << "7|8|9\n";
cout << "-----\n";
cout << "4|5|6\n";
cout << "-----\n";
cout << "1|2|3\n\n";
cout << "Press 1 to continue. \n";
cin >> play;
if(play == 1)
{
cout << "What is your player name? \n";
cin >> player;
cout << "Thanks " << player <<".\n";
valuefill ();
}
}
else if(start == 3)
{
cout << "Bye Bye!\n";
}
else
{
cout << "You need to enter a number 1, 2, or 3.\n";
}
}


Comments are welcomed! :) :D

Jufa
08-21-2006, 11:56 PM
I got error when trying to play that at school.

My OS is Finnish so I dont know how to say that Error-report in english but it says something like "initializing failed (0xc0000135)"

geon
08-22-2006, 06:49 AM
That's an awfull lot of code duplication. I'm pretty shure you could use a loop to avoid that.

Cleves
08-22-2006, 07:23 AM
No AI in the world is unbeatable. It took me 2 tries to win.

Pretty easy actually. Nice game.

http://img150.imageshack.us/img150/8602/1yj5.jpg

neptune3d
08-22-2006, 08:43 AM
That's an awfull lot of code duplication. I'm pretty shure you could use a loop to avoid that.

I think he was going for readability, but of course in practice this method would be a nightmare to maintain on a larger project. Nice work though, keep at it.

Nep.

neptune3d
08-22-2006, 08:45 AM
I got error when trying to play that at school.

My OS is Finnish so I dont know how to say that Error-report in english but it says something like "initializing failed (0xc0000135)"

Sounds like a memory error, generally a 0xc.... error has to do with mem. Kind of interesting that a term. based program would come up with that.

Razor
08-23-2006, 04:14 AM
No AI in the world is unbeatable.

It doesn't take a genius (far from it) to play Tic-Tac-Toe perfectly. If both players play perfectly, it is a draw. Always. So if his ai was perfect (which I guess it isn't, in which case I'm shocked he never beat it) it would be unbeatable. The best you could do is draw.

geon
08-23-2006, 06:02 AM
I think he was going for readability

In my opinion,it is more readable if a loop shows you wich variables are changing and in what order. Otherwise you need to extract that information from n nearly identical code blocks. Not readable.

Loregoreth
08-23-2006, 06:23 AM
When I said readable I meant neat not small. For instance i wrote it like this:

if (box[8].fill == 'X'&& box[4].fill == ' ')
{
box[4].value += 3;
}


instead of like


if (box[8].fill == 'X'&& box[4].fill == ' ') box[4].value += 3;


this or


if (box[8].fill == 'X'&& box[4].fill == ' ')
box[4].value += 3;


this.

Its seems i also forgot to make sure the AI checked for double win.

PS: I only played it three times so I didn't have time to continue looking for a way to win.