-
tic tac toe(again xD)
Have a tic tac toe program which works fine expect the computer decides to cheat every once in a while.
If after making a move it can then win by making another move, for some reason it makes that move, and then if it can win again it will make a third move etc.
As there is only once statement actually changing the value of the board i thought it must be an issue with loops or something, but i just can't find it.
Also, while you're checking the code, can anyone suggest ways of making it more efficient/less clunky?
Thanks,
Code:
Code:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <time.h>
using namespace std;
// Declare Variables
int loopcountrow;
int loopcountcol;
int loopcount;
int board[9];
int aiboard[3][3];
int movex;
int move;
int aimove;
int win=0;
int endc;
int player=1;
int playerc;
int i;
int itt;
int moo;
int numove=0;
int ai;
int randint;
//////////////////////////////////////////////
///////////////// //////////////
///////////////// -=0 X=1 O=2 ////////////////
///////////////// /////////////////
/////////////////////////////////////////////////////
void drawboard()
{
cout << endl;
for (loopcountrow = 0; loopcountrow < 3; loopcountrow = loopcountrow + 1)
{
for (loopcountcol = 0; loopcountcol < 3; loopcountcol = loopcountcol + 1)
{
loopcount = (loopcountrow*3)+loopcountcol;
switch(board[loopcount])
{
case 0:
cout << "-";
break;
case 1:
cout << "X";
break;
case 2:
cout << "O";
break;
default:
cout << "-";
}
}
cout << endl;
}
}
/////////////////////////////////////////////////////////////////////////
void aichoosemovetwo()
{
for (moo=2; moo>0; --moo)
{
/// blockandwin rows
for (i=0;i<3; ++i)
{
if (aiboard[i][0]==moo && aiboard[i][1]==moo && aiboard[i][2]==0)
{
aimove=((((i+1)*3)-3)+2);
return;
}
if (aiboard[i][0]==moo && aiboard[i][2]==moo && aiboard[i][1]==0)
{
aimove=((((i+1)*3)-3)+1);
return;
}
if (aiboard[i][1]==moo && aiboard[i][2]==moo && aiboard[i][0]==0)
{
aimove=(((i+1)*3)-3);
return;
}
///blockandwin columns
if (aiboard[0][i]==moo && aiboard[1][i]==moo && aiboard[2][i]==0)
{
aimove=6+i;
return;
}
if (aiboard[0][i]==moo && aiboard[2][i]==moo && aiboard[1][i]==0)
{
aimove=3+i;
return;
}
if (aiboard[1][i]==moo && aiboard[2][i]==moo && aiboard[0][i]==0)
{
aimove=0+i;
return;
}
}
///blockandwin! diagonals
//to be continued XD
}
}
////////////////////////////////////////////////////////////////////////
int aichoosemove()
{
randint = (rand()%9);
if (board[randint]==0)
{
aimove=randint;
}else{
aichoosemove();
}
aiboard[0][0]=board[0];
aiboard[0][1]=board[1];
aiboard[0][2]=board[2];
aiboard[1][0]=board[3];
aiboard[1][1]=board[4];
aiboard[1][2]=board[5];
aiboard[2][0]=board[6];
aiboard[2][1]=board[7];
aiboard[2][2]=board[8];
aichoosemovetwo();
board[aimove]=2;
numove++;
player=1;
}
///////////////////////////////////////////////////////////////////////////
void inputmove()
{
if(ai==2 && player==2){
aichoosemove();
}else{
cout << endl;
cout << "Player " << player << endl;
cout << "Where would you like to move? >> ";
cin >> movex;
if (movex>9)
{
cout << "Invalid Move" << endl;
inputmove();
}
move=movex-1;
switch(board[move])
{
case 0:
board[move]=player;
if(player==1)
{
player=2;
}else{
player=1;
}
numove++;
break;
case 1:
cout << "Invalid Move" << endl;
inputmove();
break;
case 2:
cout << "Invalid Move" << endl;
inputmove();
break;
}
}
}
/////////////////////////////////////////////////////////////////////////
void checkwin()
{
for (i=1; i<3; i=++i)
{
if (board[0]==i && board[3]==i && board[6]==i)
{
win=i;
}
if (board[0]==i && board[3]==i && board[6]==i)
{
win=i;
}
if (board[1]==i && board[4]==i && board[7]==i)
{
win=i;
}
if (board[2]==i && board[5]==i && board[8]==i)
{
win=i;
}
if (board[0]==i && board[1]==i && board[2]==i)
{
win=i;
}
if (board[3]==i && board[4]==i && board[5]==i)
{
win=i;
}
if (board[6]==i && board[7]==i && board[8]==i)
{
win=i;
}
if (board[0]==i && board[4]==i && board[8]==i)
{
win=i;
}
if (board[2]==i && board[4]==i && board[6]==i)
{
win=i;
}
}
if(numove==9)
{
win=3;
}
}
/////////////////////////////////////////////////////////////////////////
int aichoose()
{
cout << "Player vs Player? (1)" << endl;
cout << "Or" << endl;;
cout << "Player vs Computer? (2)" << endl;
cin >> ai;
if (ai==1 ^ ai==2){
}else{
cout << endl;
cout << "Invalid Option";
cout << endl;
aichoose();
}
}
/////////////////////////////////////////////////////////////////////////
int main()
{
srand((unsigned)time(0));
aichoose();
do
{
drawboard();
inputmove();
checkwin();
}while(win==0);
drawboard();
cout << endl;
switch(win)
{
case 1:
cout << "Player 1 Wins!";
break;
case 2:
if (ai==1)
{
cout << "Player 2 Wins!";
}else{
cout << "Computer Wins!";
}
break;
case 3:
cout << "Draw =(";
break;
default:
cout << "QQ";
}
cout << endl;
system("PAUSE");
return 0;
}
-
from my understanding of what you said, the computer can take occupied square ??
If that is the case, you could have an inlined function to decide whether or not the square is occupied
Code:
const char emptySquare = ' ';
bool isTaken(/*pass board here*/)
{
return /*board*/ != emptySquare;
}
And since you have problems with the board as you said, you should pass the board by either refrenece or pointer. good luck
-
No, thats not the problem, it only takes unoccupied squares, but it takes multiple turns when it should only take one.
-
Look at the condition that allows the AI to make it's move, then trace the logic that should switch it back to the players turn.
-
Have you spotted the problem and now trying to help me find it, while me still doing the work, or just suggestign where i should start?
Either way I can't find it.
Will return just breakout of the aichoosemovetwo function? If it lands me somewhere else then that might be the problem...
-
Code:
int aichoosemove()
{
randint = (rand()%9);
if (board[randint]==0)
{
aimove=randint;
}else{
aichoosemove();
}
aiboard[0][0]=board[0];
aiboard[0][1]=board[1];
aiboard[0][2]=board[2];
aiboard[1][0]=board[3];
aiboard[1][1]=board[4];
aiboard[1][2]=board[5];
aiboard[2][0]=board[6];
aiboard[2][1]=board[7];
aiboard[2][2]=board[8];
aichoosemovetwo();
board[aimove]=2;
numove++;
player=1;
}
The bolded code should be moved to the if() clause above. Otherwise aichoosemovetwo() will be called once for each time the else() clause is executed (where it recursively calls aichoosemove()). Or better would be to change the if() into a while() statement, and scrap the else().
-
Yay! Thats the last time I recall a function instead of using a loop: FIXED:
Code:
int aichoosemove()
{
aiboard[0][0]=board[0];
aiboard[0][1]=board[1];
aiboard[0][2]=board[2];
aiboard[1][0]=board[3];
aiboard[1][1]=board[4];
aiboard[1][2]=board[5];
aiboard[2][0]=board[6];
aiboard[2][1]=board[7];
aiboard[2][2]=board[8];
gogo=0;
do{
randint = (rand()%9);
if (board[randint]==0)
{
aimove=randint;
gogo=1;
}
}while(gogo=0);
aichoosemovetwo();
board[aimove]=2;
numove++;
player=1;
}
-
>Yay! Thats the last time I recall a function instead of using a loop: FIXED:
Make sure you fix the condition. Some compilers will warn you about this, if you crank up the warning level.