Olá!
Programei um "Jogo da Velha", "Tic Tac Toe" em inglês, quando me deparei com um fato um tanto interessante. Apesar do programa funcionar normalmente, quando a função
bool isEmpty (int position);
da classe TicTacToe é chamada, ela retorna verdadeiro para a maioria das posições, mesmo elas estando preenchidas com um "X" ou "O".
O problema pode ser observado compilando seguinte código do programa, que já demonstra o erro com consecutivas chamadas à função isEmpty após cada impressão de jogo.
Se alguém encontrar o problema, por favor, me avisem.
Obrigado.
Programei um "Jogo da Velha", "Tic Tac Toe" em inglês, quando me deparei com um fato um tanto interessante. Apesar do programa funcionar normalmente, quando a função
bool isEmpty (int position);
da classe TicTacToe é chamada, ela retorna verdadeiro para a maioria das posições, mesmo elas estando preenchidas com um "X" ou "O".
O problema pode ser observado compilando seguinte código do programa, que já demonstra o erro com consecutivas chamadas à função isEmpty após cada impressão de jogo.
Se alguém encontrar o problema, por favor, me avisem.
Obrigado.
Código:
//Tic Tac Toe Class
#ifndef TICTACTOE_H
#define TICTACTOE_H
class TicTacToe {
public:
TicTacToe();
bool setMark(char symbol, char position); //Sets a Mark
char getMark(int position=1); //Gets a Mark
bool isEmpty(int position=1); //Checks if position is empty
char checkGame(); //Check Winner
void printGame(); //Prints Game
private:
char table[3][3]; //Game's Table
};
#endif
Código:
//TicTacToe member funciton definition
#include <iostream>
using std::cout;
using std::endl;
#include "tictactoe.h"
TicTacToe::TicTacToe()
{
for(int x=0; x<3; x++)
for(int y=0; y<3; y++)
table[x][y]='-';
}
bool TicTacToe::setMark(char symbol, char position)
{
switch (position)
{
case '7': if(table[0][0]=='-') table[0][0]=symbol; else return false; break;
case '4': if(table[1][0]=='-') table[1][0]=symbol; else return false; break;
case '1': if(table[2][0]=='-') table[2][0]=symbol; else return false; break;
case '8': if(table[0][1]=='-') table[0][1]=symbol; else return false; break;
case '5': if(table[1][1]=='-') table[1][1]=symbol; else return false; break;
case '2': if(table[2][1]=='-') table[2][1]=symbol; else return false; break;
case '9': if(table[0][2]=='-') table[0][2]=symbol; else return false; break;
case '6': if(table[1][2]=='-') table[1][2]=symbol; else return false; break;
case '3': if(table[2][2]=='-') table[2][2]=symbol; else return false; break;
default: return false;
}
return true;
}
char TicTacToe::getMark(int position)
{
switch (position)
{
case 7: return table[0][0];
case 4: return table[1][0];
case 1: return table[2][0];
case 8: return table[0][1];
case 5: return table[1][1];
case 2: return table[2][1];
case 9: return table[0][2];
case 6: return table[1][2];
case 3: return table[2][2];
default: return -1;
}
}
bool TicTacToe::isEmpty(int position)
{
switch (position)
{
case 7: if(table[0][0]=='-') return true;
case 4: if(table[1][0]=='-') return true;
case 1: if(table[2][0]=='-') return true;
case 8: if(table[0][1]=='-') return true;
case 5: if(table[1][1]=='-') return true;
case 2: if(table[2][1]=='-') return true;
case 9: if(table[0][2]=='-') return true;
case 6: if(table[1][2]=='-') return true;
case 3: if(table[2][2]=='-') return true;
default: return false;
}
return false;
}
void TicTacToe::printGame()
{
cout <<' ' <<((table[0][0]=='-')? '7': table[0][0]) <<" | " <<((table[0][1]=='-')? '8': table[0][1]) <<" | " << ((table[0][2]=='-')? '9': table[0][2]) <<endl;
cout <<"-----------" <<endl;
cout <<' ' <<((table[1][0]=='-')? '4': table[1][0]) <<" | " <<((table[1][1]=='-')? '5': table[1][1]) <<" | " << ((table[1][2]=='-')? '6': table[1][2]) <<endl;
cout <<"-----------" <<endl;
cout <<' ' <<((table[2][0]=='-')? '1': table[2][0]) <<" | " <<((table[2][1]=='-')? '2': table[2][1]) <<" | " << ((table[2][2]=='-')? '3': table[2][2]) <<endl;
}
char TicTacToe::checkGame()
{
if(table[0][0]==table[0][1] && table[0][1]==table[0][2] && table[0][0]!='-') return table[0][0];
else if(table[1][0]==table[1][1] && table[1][1]==table[1][2] && table[1][0]!='-') return table[1][0];
else if(table[2][0]==table[2][1] && table[2][1]==table[2][2] && table[2][0]!='-') return table[2][0];
else if(table[0][0]==table[1][0] && table[1][0]==table[2][0] && table[0][0]!='-') return table[0][0];
else if(table[0][1]==table[1][1] && table[1][1]==table[2][1] && table[0][1]!='-') return table[0][1];
else if(table[0][2]==table[1][2] && table[1][2]==table[2][2] && table[0][2]!='-') return table[0][2];
else if(table[0][0]==table[1][1] && table[1][1]==table[2][2] && table[0][0]!='-') return table[0][0];
else if(table[0][2]==table[1][1] && table[1][1]==table[2][0] && table[0][2]!='-') return table[0][2];
else if(table[0][0]!='-' && table[1][0]!='-' && table[2][0]!='-' && table[0][1]!='-' && table[1][1]!='-' && table[2][1]!='-' && table[0][2]!='-' && table[1][2]!='-' && table[2][2]!='-') return 'V';
return '-';
}
Código:
//Tic Tac Toe Game
#include <time.h>
#include <conio.h>
#include <iostream>
using std::cout;
using std::endl;
#include "tictactoe.h"
inline char AI_ComputerMark(TicTacToe &);
int main()
{
TicTacToe jogo;
char jogadores='0';
int turno=1;
cout <<"X O X O X O X O X O" <<endl
<<"O X Tic Tac Toe O X" <<endl
<<"X O X O X O X O X O" <<endl <<endl;
cout << "[1] Jogador [2] Jogadores" <<endl;
do{jogadores=_getch();}while(jogadores!='1' && jogadores!='2');
srand(time(0));
if(jogadores=='1' && (turno=(rand()%2)+1)==2)
cout <<"\nComputador Inicia!";
else if(jogadores=='1')
cout <<"\nJogador Inicia!";
_getch();
do{
system("cls");
cout <<endl;
jogo.printGame();
cout <<"Casas Vazias (teste)" <<endl;
for(int x=1; x<10; x++)
if(jogo.isEmpty(x))
cout <<x <<" vazio!" <<endl;
switch(turno)
{
case 1: if(jogo.setMark('O', _getch())) ++turno; break;
case 2:
if(jogadores=='2' && jogo.setMark('X', _getch()))
--turno;
else if(jogadores=='1' && jogo.setMark('X', AI_ComputerMark(jogo)))
--turno;
break;
}
}while(jogo.checkGame()=='-');
system("cls");
jogo.printGame();
cout <<endl;
if(jogo.checkGame()=='V') cout <<"Velha!" <<endl;
else cout <<jogo.checkGame() << " Ganhou!" <<endl;
system("pause");
return 0;
}
inline char AI_ComputerMark(TicTacToe & jogo)
{
//PRIMEIRO A JOGAR
if(jogo.getMark(7)=='-' && jogo.getMark(8)=='-' && jogo.getMark(9)=='-' && jogo.getMark(4)=='-' && jogo.getMark(5)=='-' && jogo.getMark(6)=='-' && jogo.getMark(1)=='-' && jogo.getMark(2)=='-' && jogo.getMark(3)=='-')
switch((rand()%5))
{
case 0: return '1';
case 1: return '3';
case 2: return '5';
case 3: return '7';
case 4: return '9';
}
//ATAQUE
//LINHAS
if(jogo.getMark(7)=='X' && jogo.getMark(8)=='X' && jogo.getMark(9)=='-') return '9';
if(jogo.getMark(7)=='X' && jogo.getMark(8)=='-' && jogo.getMark(9)=='X') return '8';
if(jogo.getMark(7)=='-' && jogo.getMark(8)=='X' && jogo.getMark(9)=='X') return '7';
if(jogo.getMark(4)=='X' && jogo.getMark(5)=='X' && jogo.getMark(6)=='-') return '6';
if(jogo.getMark(4)=='X' && jogo.getMark(5)=='-' && jogo.getMark(6)=='X') return '5';
if(jogo.getMark(4)=='-' && jogo.getMark(5)=='X' && jogo.getMark(6)=='X') return '4';
if(jogo.getMark(1)=='X' && jogo.getMark(2)=='X' && jogo.getMark(3)=='-') return '3';
if(jogo.getMark(1)=='X' && jogo.getMark(2)=='-' && jogo.getMark(3)=='X') return '2';
if(jogo.getMark(1)=='-' && jogo.getMark(2)=='X' && jogo.getMark(3)=='X') return '1';
//COLUNAS
if(jogo.getMark(7)=='X' && jogo.getMark(4)=='X' && jogo.getMark(1)=='-') return '1';
if(jogo.getMark(7)=='X' && jogo.getMark(4)=='-' && jogo.getMark(1)=='X') return '4';
if(jogo.getMark(7)=='-' && jogo.getMark(4)=='X' && jogo.getMark(1)=='X') return '7';
if(jogo.getMark(8)=='X' && jogo.getMark(5)=='X' && jogo.getMark(2)=='-') return '2';
if(jogo.getMark(8)=='X' && jogo.getMark(5)=='-' && jogo.getMark(2)=='X') return '5';
if(jogo.getMark(8)=='-' && jogo.getMark(5)=='X' && jogo.getMark(2)=='X') return '8';
if(jogo.getMark(9)=='X' && jogo.getMark(6)=='X' && jogo.getMark(3)=='-') return '3';
if(jogo.getMark(9)=='X' && jogo.getMark(6)=='-' && jogo.getMark(3)=='X') return '6';
if(jogo.getMark(9)=='-' && jogo.getMark(6)=='X' && jogo.getMark(3)=='X') return '9';
//DIAGONAIS
if(jogo.getMark(7)=='X' && jogo.getMark(5)=='X' && jogo.getMark(3)=='-') return '3';
if(jogo.getMark(7)=='X' && jogo.getMark(5)=='-' && jogo.getMark(3)=='X') return '5';
if(jogo.getMark(7)=='-' && jogo.getMark(5)=='X' && jogo.getMark(3)=='X') return '7';
if(jogo.getMark(9)=='X' && jogo.getMark(5)=='X' && jogo.getMark(1)=='-') return '1';
if(jogo.getMark(9)=='X' && jogo.getMark(5)=='-' && jogo.getMark(1)=='X') return '5';
if(jogo.getMark(9)=='-' && jogo.getMark(5)=='X' && jogo.getMark(1)=='X') return '9';
//DEFESA
//LINHAS
if(jogo.getMark(7)=='O' && jogo.getMark(8)=='O' && jogo.getMark(9)=='-') return '9';
if(jogo.getMark(7)=='O' && jogo.getMark(8)=='-' && jogo.getMark(9)=='O') return '8';
if(jogo.getMark(7)=='-' && jogo.getMark(8)=='O' && jogo.getMark(9)=='O') return '7';
if(jogo.getMark(4)=='O' && jogo.getMark(5)=='O' && jogo.getMark(6)=='-') return '6';
if(jogo.getMark(4)=='O' && jogo.getMark(5)=='-' && jogo.getMark(6)=='O') return '5';
if(jogo.getMark(4)=='-' && jogo.getMark(5)=='O' && jogo.getMark(6)=='O') return '4';
if(jogo.getMark(1)=='O' && jogo.getMark(2)=='O' && jogo.getMark(3)=='-') return '3';
if(jogo.getMark(1)=='O' && jogo.getMark(2)=='-' && jogo.getMark(3)=='O') return '2';
if(jogo.getMark(1)=='-' && jogo.getMark(2)=='O' && jogo.getMark(3)=='O') return '1';
//COLUNAS
if(jogo.getMark(7)=='O' && jogo.getMark(4)=='O' && jogo.getMark(1)=='-') return '1';
if(jogo.getMark(7)=='O' && jogo.getMark(4)=='-' && jogo.getMark(1)=='O') return '4';
if(jogo.getMark(7)=='-' && jogo.getMark(4)=='O' && jogo.getMark(1)=='O') return '7';
if(jogo.getMark(8)=='O' && jogo.getMark(5)=='O' && jogo.getMark(2)=='-') return '2';
if(jogo.getMark(8)=='O' && jogo.getMark(5)=='-' && jogo.getMark(2)=='O') return '5';
if(jogo.getMark(8)=='-' && jogo.getMark(5)=='O' && jogo.getMark(2)=='O') return '8';
if(jogo.getMark(9)=='O' && jogo.getMark(6)=='O' && jogo.getMark(3)=='-') return '3';
if(jogo.getMark(9)=='O' && jogo.getMark(6)=='-' && jogo.getMark(3)=='O') return '6';
if(jogo.getMark(9)=='-' && jogo.getMark(6)=='O' && jogo.getMark(3)=='O') return '9';
//DIAGONAIS
if(jogo.getMark(7)=='O' && jogo.getMark(5)=='O' && jogo.getMark(3)=='-') return '3';
if(jogo.getMark(7)=='O' && jogo.getMark(5)=='-' && jogo.getMark(3)=='O') return '5';
if(jogo.getMark(7)=='-' && jogo.getMark(5)=='O' && jogo.getMark(3)=='O') return '7';
if(jogo.getMark(9)=='O' && jogo.getMark(5)=='O' && jogo.getMark(1)=='-') return '1';
if(jogo.getMark(9)=='O' && jogo.getMark(5)=='-' && jogo.getMark(1)=='O') return '5';
if(jogo.getMark(9)=='-' && jogo.getMark(5)=='O' && jogo.getMark(1)=='O') return '9';
//NEUTRA
/*else if((jogo.getMark(5)=='O' && (jogo.getMark(3)=='O' || jogo.getMark(9)=='O' || jogo.getMark(7)=='O' || jogo.getMark(1)=='O')))
if(jogo.getMark(3)=='-') return '3';
else if(jogo.getMark(1)=='-') return '1';
else if(jogo.getMark(9)=='-') return '9';
else if(jogo.getMark(7)=='-') return '7';*/
//INDIVIDUAIS
if(jogo.getMark(5)=='-') return '5';
if(jogo.getMark(3)=='-') return '3';
if(jogo.getMark(6)=='-') return '6';
if(jogo.getMark(1)=='-') return '1';
if(jogo.getMark(4)=='-') return '4';
if(jogo.getMark(9)=='-') return '9';
if(jogo.getMark(8)=='-') return '8';
if(jogo.getMark(7)=='-') return '7';
if(jogo.getMark(2)=='-') return '2';
return '0';
}