I was trying to write a tic-tac-toe game and I came up with this. It *works* but lacks intelligence. I was wondering if anyone could help me make it smart. I was looking at the negamax algorithm but I don't know how to put it to work on my program. Thanks.
Code:
#include <iostream>
#include <string>
#include <cctype>
#include <sstream>
#include <windows.h>
void mostrar_matrix(void);
char movimento_jogador(void);
char movimento_computador(void);
bool posicao_valida(std::string &, int &, int &, char &);
char analizar_matrix(void);
char matrix[3][3];
int main()
{
char resultado = ' ';
// muda o nome do console
SetConsoleTitle("Jogo da velha!");
// coloca um espaço em branco em todas as posições da matrix
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
matrix[i][j] = ' ';
mostrar_matrix();
while(resultado == ' '){
resultado = movimento_jogador();
mostrar_matrix();
if(resultado == 'X')
break;
resultado = movimento_computador();
Sleep(2000);
mostrar_matrix();
}
if(resultado == 'X'){
std::cout << "Voce ganhou! ";
std::cin.get();
}
else{
std::cout << "Eu ganhei! ";
std::cin.get();
}
return 0;
}
void mostrar_matrix(void)
{
// limpa a tela
// funciona no Visual C++ 7.0 e pode não ser portável...
system("cls");
std::cout << " A B C\n\n";
for(int j = 0; j < 3; j++){
std::cout << j + 1 << " "
<< matrix[j][0] << " | "
<< matrix[j][1] << " | "
<< matrix[j][2] << '\n';
if(j != 2)
std::cout << " ---|---|---\n";
}
std::cout << '\n';
}
char movimento_jogador(void)
{
int x, y;
char z;
std::string posicao;
do{
std::cout << "Posicao para o X: ";
std::getline(std::cin, posicao);
}while(!posicao_valida(posicao, x, y, z));
matrix[x][y] = 'X';
return analizar_matrix();
}
bool posicao_valida(std::string &posicao, int &x, int &y, char &z)
{
// testa se foi digitado alguma coisa
if(posicao.length() == 0){
std::cout << "Voce precisa especificar uma posicao para o X ";
std::cin.get();
mostrar_matrix();
return false;
}
// testa se foram digitados mais do que dois caracteres
if(posicao.length() > 2){
std::cout << "Nao digite mais do que dois caracteres ";
std::cin.get();
mostrar_matrix();
return false;
}
// testa o primeiro caractere para ver se ele é um
// número e o segundo para ver se ele é uma letra
if(!isdigit(posicao[0]) || !isalpha(posicao[1])){
std::cout << "Digite um numero e uma letra. Exemplo: 1a ";
std::cin.get();
mostrar_matrix();
return false;
}
// preciso colocar o primeiro caractere da string posicao
// em outra string pois não posso passar só o index (posicao[0])
// para a istringstream pois assim o valor de x não será modificado
std::string foo;
foo.assign(posicao, 0, 1);
// converte o primeiro caractere da string posicao para int
std::istringstream bar(foo);
bar >> x;
// testa pra ver se a parte numérica da posição indicada pelo
// usuário é um número de 1 até 3
if(x < 1 || x > 3){
std::cout << "Numero invalido ";
std::cin.get();
mostrar_matrix();
return false;
}
// subtrai 1 do x pq o array começa a ser contado do 0
x--;
// coloca a parte alfabética da posição indicada pelo usuário no char z
z = posicao[1];
// testa o char z para ver se o que o usuário digitou é uma letra de A até C
if(toupper(z) < 'A' || toupper(z) > 'C'){
std::cout << "Letra invalida ";
std::cin.get();
mostrar_matrix();
return false;
}
// dá o valor para o y de acordo com a letra escolhida
// A = 0, B = 1 e C = 2...
switch(toupper(z)){
case 'A':
y = 0;
break;
case 'B':
y = 1;
break;
case 'C':
y = 2;
break;
}
// testa se o usuário não está tentando marcar um lugar ocupado
if(matrix[x][y] != ' '){
std::cout << "Esta posicao ja esta ocupada ";
std::cin.get();
mostrar_matrix();
return false;
}
return true;
}
char analizar_matrix(void)
{
int i;
// testa as linhas
for(i = 0; i < 3; i++)
if(matrix[i][0] == matrix[i][1] && matrix[i][0] == matrix[i][2])
return matrix[i][0];
// testa as colunas
for(i = 0; i < 3; i++)
if(matrix[0][i] == matrix[1][i] && matrix[0][i] == matrix[2][i])
return matrix[0][i];
// testa as diagonais
if(matrix[0][0] == matrix[1][1] && matrix[1][1] == matrix[2][2])
return matrix[0][0];
if(matrix[0][2] == matrix[1][1] && matrix[1][1] == matrix[2][0])
return matrix[0][2];
return ' ';
}
char movimento_computador(void)
{
int i, j;
static bool flag00 = false; /* matrix[0][0] */
static bool flag01 = false; /* matrix[0][1] */
static bool flag02 = false; /* matrix[0][2] */
static bool flag10 = false; /* matrix[1][0] */
static bool flag11 = false; /* matrix[1][1] */
static bool flag12 = false; /* matrix[1][2] */
static bool flag20 = false; /* matrix[2][0] */
static bool flag21 = false; /* matrix[2][1] */
static bool flag22 = false; /* matrix[2][2] */
if(flag00 == false)
{
if(matrix[0][0] == 'X')
{
while(1)
{
if((matrix[1][0] == 'X') && (matrix[2][0] == ' '))
{
matrix[2][0] = 'O';
break;
}
else if((matrix[2][0] == 'X') && (matrix[1][0] == ' '))
{
matrix[1][0] = 'O';
break;
}
else if((matrix[0][1] == 'X') && (matrix[0][2] == ' '))
{
matrix[0][2] = 'O';
break;
}
else if((matrix[0][2] == 'X') && (matrix[0][1] == ' '))
{
matrix[0][1] = 'O';
break;
}
else if((matrix[1][1] == 'X') && (matrix[2][2] == ' '))
{
matrix[2][2] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag00 = true;
}
}
if(flag01 == false)
{
if(matrix[0][1] == 'X')
{
while(1)
{
if((matrix[0][0] == 'X') && (matrix[0][2] == ' '))
{
matrix[0][2] = 'O';
break;
}
else if((matrix[0][2] == 'X') && (matrix[0][0] == ' '))
{
matrix[0][0] = 'O';
break;
}
else if((matrix[1][1] == 'X') && (matrix[2][1] == ' '))
{
matrix[2][1] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag01 = true;
}
}
if(flag02 == false)
{
if(matrix[0][2] == 'X')
{
while(1)
{
if((matrix[0][1] == 'X') && (matrix[0][0] == ' '))
{
matrix[0][0] = 'O';
break;
}
else if((matrix[0][0] == 'X') && (matrix[0][1] == ' '))
{
matrix[0][1] = 'O';
break;
}
else if((matrix[1][1] == 'X') && (matrix[2][0] == ' '))
{
matrix[2][0] = 'O';
break;
}
else if((matrix[2][0] == 'X') && (matrix[1][1] == ' '))
{
matrix[1][1] = 'O';
break;
}
else if((matrix[1][2] == 'X') && (matrix[2][2] == ' '))
{
matrix[2][2] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag02 = true;
}
}
if(flag10 == false)
{
if(matrix[1][0] == 'X')
{
while(1)
{
if((matrix[0][0] == 'X') && (matrix[2][0] == ' '))
{
matrix[2][0] = 'O';
break;
}
else if((matrix[2][0] == 'X') && (matrix[0][0] == ' '))
{
matrix[0][0] = 'O';
break;
}
else if((matrix[1][1] == 'X') && (matrix[1][2] == ' '))
{
matrix[1][2] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag10 = true;
}
}
if(flag11 == false)
{
if(matrix[1][1] == 'X')
{
while(1)
{
if((matrix[0][1] == 'X') && (matrix[2][1] == ' '))
{
matrix[2][1] = 'O';
break;
}
else if((matrix[2][1] == 'X') && (matrix[0][1] == ' '))
{
matrix[0][1] = 'O';
break;
}
else if((matrix[0][0] == 'X') && (matrix[2][2] == ' '))
{
matrix[2][2] = 'O';
break;
}
else if((matrix[2][2] == 'X') && (matrix[0][0] == ' '))
{
matrix[0][0] = 'O';
break;
}
else if((matrix[0][2] == 'X') && (matrix[2][0] == ' '))
{
matrix[2][0] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag11 = true;
}
}
if(flag12 == false)
{
if(matrix[1][2] == 'X')
{
while(1)
{
if((matrix[0][2] == 'X') && (matrix[2][2] == ' '))
{
matrix[2][2] = 'O';
break;
}
else if((matrix[2][2] == 'X') && (matrix[0][2] == ' '))
{
matrix[0][2] = 'O';
break;
}
else if((matrix[1][1] == 'X') && (matrix[1][0] == ' '))
{
matrix[1][0] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag12 = true;
}
}
if(flag20 == false)
{
if(matrix[2][0] == 'X')
{
while(1)
{
if((matrix[1][0] == 'X') && (matrix[0][0] == ' '))
{
matrix[0][0] = 'O';
break;
}
else if((matrix[0][0] == 'X') && (matrix[1][0] == ' '))
{
matrix[1][0] = 'O';
break;
}
else if((matrix[2][1] == 'X') && (matrix[2][2] == ' '))
{
matrix[2][2] = 'O';
break;
}
else if((matrix[2][2] == 'X') && (matrix[2][1] == ' '))
{
matrix[2][1] = 'O';
break;
}
else if((matrix[1][1] == 'X') && (matrix[0][2] == ' '))
{
matrix[0][2] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag20 = true;
}
}
if(flag21 == false)
{
if(matrix[2][1] == 'X')
{
while(1)
{
if((matrix[2][2] == 'X') && (matrix[2][0] == ' '))
{
matrix[2][0] = 'O';
break;
}
else if((matrix[2][0] == 'X') && (matrix[2][2] == ' '))
{
matrix[2][2] = 'O';
break;
}
else if((matrix[1][1] == 'X') && (matrix[0][1] == ' '))
{
matrix[0][1] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag21 = true;
}
}
if(flag22 == false)
{
if(matrix[2][2] == 'X')
{
while(1)
{
if((matrix[1][2] == 'X') && (matrix[0][2] == ' '))
{
matrix[0][2] = 'O';
break;
}
else if((matrix[0][2] == 'X') && (matrix[1][2] == ' '))
{
matrix[1][2] = 'O';
break;
}
else if((matrix[2][1] == 'X') && (matrix[2][0] == ' '))
{
matrix[2][0] = 'O';
break;
}
else if((matrix[2][0] == 'X') && (matrix[2][1] == ' '))
{
matrix[2][1] = 'O';
break;
}
else if((matrix[1][1] == 'X') && (matrix[0][0] == ' '))
{
matrix[0][0] = 'O';
break;
}
else
{
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
if(matrix[i][j] == ' ')
break;
if(matrix[i][j] == ' ')
break;
}
matrix[i][j] = 'O';
break;
}
}
flag22 = true;
}
}
return analizar_matrix();
}