Thread: Tic-tac-toe

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    204

    Tic-tac-toe

    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();
    }

  2. #2
    VA National Guard The Brain's Avatar
    Join Date
    May 2004
    Location
    Manassas, VA USA
    Posts
    903
    La manera barata y fácil sería de utilizar apenas AI "duro-codificado". He googled el algoritmo nega-máx. No mire excesivamente difícil.

    Siempre se preguntó lo que codifica se pareció a en idiomas diferentes. Muy bueno.
    • "Problem Solving C++, The Object of Programming" -Walter Savitch
    • "Data Structures and Other Objects using C++" -Walter Savitch
    • "Assembly Language for Intel-Based Computers" -Kip Irvine
    • "Programming Windows, 5th edition" -Charles Petzold
    • "Visual C++ MFC Programming by Example" -John E. Swanke
    • "Network Programming Windows" -Jones/Ohlund
    • "Sams Teach Yourself Game Programming in 24 Hours" -Michael Morrison
    • "Mathmatics for 3D Game Programming & Computer Graphics" -Eric Lengyel

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    204
    That's portuguese, not spanish. I didn't understand everything you said. Could it write it in english please?

  4. #4
    VA National Guard The Brain's Avatar
    Join Date
    May 2004
    Location
    Manassas, VA USA
    Posts
    903

    Lightbulb

    oh my bad. I was just saying that most people just hard-code a static AI for tic-tac-toe.. but you obviously want to expand your AI horizons.. I googled for negamax and found many tutorials on the subject.. the code doesn't seem too overly difficult. Also, here is post of someone who was in the same situation as yourself. You will see tic-tac-toe using both the mini-max and nega-max methods of predicting the best move.
    • "Problem Solving C++, The Object of Programming" -Walter Savitch
    • "Data Structures and Other Objects using C++" -Walter Savitch
    • "Assembly Language for Intel-Based Computers" -Kip Irvine
    • "Programming Windows, 5th edition" -Charles Petzold
    • "Visual C++ MFC Programming by Example" -John E. Swanke
    • "Network Programming Windows" -Jones/Ohlund
    • "Sams Teach Yourself Game Programming in 24 Hours" -Michael Morrison
    • "Mathmatics for 3D Game Programming & Computer Graphics" -Eric Lengyel

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help me with my simple Tic tac toe prog
    By maybnxtseasn in forum C Programming
    Replies: 2
    Last Post: 04-04-2009, 06:25 PM
  2. tic tac toe
    By holden in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 05-09-2004, 09:59 AM
  3. Help with Tic Tac Toe game
    By snef73 in forum C++ Programming
    Replies: 1
    Last Post: 04-25-2003, 08:33 AM
  4. tic tac toe game
    By Leeman_s in forum Game Programming
    Replies: 9
    Last Post: 04-24-2002, 03:24 AM
  5. my tic tac toe game, please try it
    By Leeman_s in forum C++ Programming
    Replies: 2
    Last Post: 04-14-2002, 05:16 PM