locked
Tic Tac Toe AI RRS feed

  • Question

  • Hi there!

    Iam almost done with my projects and need help with this last bit in my tic tac toe game. Currently it set as 2 player person vs. person but I know I'll have to implement a simple AI to be approved. Now I need your help with this. I know I'll have to think about it in small steps as such :

    3 "make a move " methods like

    If AI has a move in the 1st column && the two box to the right is open make a move in either box and return true If AI has a move in the middle && the box to the left and right is open make a move in either box and return true If AI has a move in the 3rd column && the two box to the left is open make a move in either box and return true

    Now Iam braindead at this moment and can't get to grips exacly how I can implement it in my code below :

    Please Help my poor soul!

    #include <iostream>
    using namespace std;
    char matrix[3][3] = { '7', '8', '9', '4', '5', '6', '1', '2', '3' };
    char player = 'X';
    int n;
    void Draw()
    {
    	system("cls");
    	cout << "Tic Tac Toe !\n" << endl;
    	for (int i = 0; i < 3; i++)
    	{
    		for (int j = 0; j < 3; j++)
    		{
    			cout << matrix[i][j] << " ";
    		}
    		cout << endl;
    	}
    }
    void Input()
    {
    	int a;
    	cout << "\nIt's " << player << " turn. " << "Press the number of the field: ";
    	cin >> a;
    
    	if (a == 7)
    	{
    		if (matrix[0][0] == '7')
    			matrix[0][0] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    	else if (a == 8)
    	{
    		if (matrix[0][1] == '8')
    			matrix[0][1] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    	else if (a == 9)
    	{
    		if (matrix[0][2] == '9')
    			matrix[0][2] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    	else if (a == 4)
    	{
    		if (matrix[1][0] == '4')
    			matrix[1][0] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    	else if (a == 5)
    	{
    		if (matrix[1][1] == '5')
    			matrix[1][1] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    	else if (a == 6)
    	{
    		if (matrix[1][2] == '6')
    			matrix[1][2] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    	else if (a == 1)
    	{
    		if (matrix[2][0] == '1')
    			matrix[2][0] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    	else if (a == 2)
    	{
    		if (matrix[2][1] == '2')
    			matrix[2][1] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    	else if (a == 3)
    	{
    		if (matrix[2][2] == '3')
    			matrix[2][2] = player;
    		else
    		{
    			cout << "Field is already in use try again!" << endl;
    			Input();
    		}
    	}
    
    }
    void TogglePlayer()
    {
    	if (player == 'X')
    		player = 'O';
    	else
    		player = 'X';
    }
    char Win()
    {
    	//first player
    	if (matrix[0][0] == 'X' && matrix[0][1] == 'X' && matrix[0][2] == 'X')
    		return 'X';
    	if (matrix[1][0] == 'X' && matrix[1][1] == 'X' && matrix[1][2] == 'X')
    		return 'X';
    	if (matrix[2][0] == 'X' && matrix[2][1] == 'X' && matrix[2][2] == 'X')
    		return 'X';
    
    	if (matrix[0][0] == 'X' && matrix[1][0] == 'X' && matrix[2][0] == 'X')
    		return 'X';
    	if (matrix[0][1] == 'X' && matrix[1][1] == 'X' && matrix[2][1] == 'X')
    		return 'X';
    	if (matrix[0][2] == 'X' && matrix[1][2] == 'X' && matrix[2][2] == 'X')
    		return 'X';
    
    	if (matrix[0][0] == 'X' && matrix[1][1] == 'X' && matrix[2][2] == 'X')
    		return 'X';
    	if (matrix[2][0] == 'X' && matrix[1][1] == 'X' && matrix[0][2] == 'X')
    		return 'X';
    
    	//second player
    	if (matrix[0][0] == 'O' && matrix[0][1] == 'O' && matrix[0][2] == 'O')
    		return 'O';
    	if (matrix[1][0] == 'O' && matrix[1][1] == 'O' && matrix[1][2] == 'O')
    		return 'O';
    	if (matrix[2][0] == 'O' && matrix[2][1] == 'O' && matrix[2][2] == 'O')
    		return 'O';
    
    	if (matrix[0][0] == 'O' && matrix[1][0] == 'O' && matrix[2][0] == 'O')
    		return 'O';
    	if (matrix[0][1] == 'O' && matrix[1][1] == 'O' && matrix[2][1] == 'O')
    		return 'O';
    	if (matrix[0][2] == 'O' && matrix[1][2] == 'O' && matrix[2][2] == 'O')
    		return 'O';
    
    	if (matrix[0][0] == 'O' && matrix[1][1] == 'O' && matrix[2][2] == 'O')
    		return 'O';
    	if (matrix[2][0] == 'O' && matrix[1][1] == 'O' && matrix[0][2] == 'O')
    		return 'O';
    
    	return '/';
    }
    
    int main()
    {
    	n = 0;
    	Draw();
    	while (1)
    	{
    		n++;
    		Input();
    		Draw();
    		if (Win() == 'X')
    		{
    			cout << "X wins!" << endl;
    			break;
    		}
    		else if (Win() == 'O')
    		{
    			cout << "O wins!" << endl;
    			break;
    		}
    		else if (Win() == '/' && n == 9)
    		{
    			cout << "It's a draw!" << endl;
    			break;
    		}
    		TogglePlayer();
    	}
    	system("pause");
    	return 0;
    }

    Tuesday, January 13, 2015 3:23 PM

Answers

  • I know how I might tackle an AI at a high level (I realize that tic-tac-toe is solved, so there are probably tables out there somewhere enumerating every possible game state and specifying the strongest possible move from each state).

    This AI would never think more than one move ahead, there are certainly improvements to be made to handle that.

    1. Figure out each possible move (never more than 9).
    2. Assign a score to each move.  Something like:  Win=100, Block opponent from winning=90, Set up a scenario where you have two in a row in two columns/rows/diagonals=80, Set up a scenario where you have  two in a row one a single column/row/diagonal=70, anything else=60.
    3. Select the highest scoring move.

    There are certainly refinements -- for example as a tie-breaker run the AI as if had just made the move you are considering and see what your opponents strongest move would be and selecting the one that leaves your opponent in the weakest position.

    • Marked as answer by Shu 2017 Thursday, January 22, 2015 9:17 AM
    Tuesday, January 13, 2015 4:32 PM

All replies

  • I know how I might tackle an AI at a high level (I realize that tic-tac-toe is solved, so there are probably tables out there somewhere enumerating every possible game state and specifying the strongest possible move from each state).

    This AI would never think more than one move ahead, there are certainly improvements to be made to handle that.

    1. Figure out each possible move (never more than 9).
    2. Assign a score to each move.  Something like:  Win=100, Block opponent from winning=90, Set up a scenario where you have two in a row in two columns/rows/diagonals=80, Set up a scenario where you have  two in a row one a single column/row/diagonal=70, anything else=60.
    3. Select the highest scoring move.

    There are certainly refinements -- for example as a tie-breaker run the AI as if had just made the move you are considering and see what your opponents strongest move would be and selecting the one that leaves your opponent in the weakest position.

    • Marked as answer by Shu 2017 Thursday, January 22, 2015 9:17 AM
    Tuesday, January 13, 2015 4:32 PM
  • Hello,

    Lots of comments here on your code before you even get to the AI part..

    1: handling the input. If you transform your matrix in an array of int, you can replace all your input handling by this simple function...

    void Play(int a, char player)

    {

    for (i=0; i<9;i++)

      if (matrix[i]==a)

      {

        matrix[i]= player;

        return;

      }

    cout<<"Field is already in use, try again!" << endl;


    }

    2: win can be replaced by:

    char win()

    {

      for (int i=0; i<3; i++) if (matrix[0][i]==matrix[1][i] && matrix[0][i]==matrix[2][i]) return matrix[0][i];

      for (int i=0; i<3; i++) if (matrix[i][0]==matrix[i][1] && matrix[i][0]==matrix[i][2]) return matrix[i][0];

      if (matrix[0][0]==matrix[1][1] && matrix[0][0]==matrix[2][2]) return matrix[0][0];

      if (matrix[0][2]==matrix[1][1] && matrix[0][2]==matrix[0][2]) return matrix[0][2];

    return '/';

    }

    As far as AI goes... tic tac toe has a very limited number of moves (9!=362880 to be exact)...  ALL the moves can be calculated in a split second at every turn...

    So, you need to create a function that evaluates ALL the possible plays at any level, and for each of the 'up to 9' possible plays, counts the number of wins, lose and draws. Then you pick the ones with the most wins..

    This will be a recursive function of course... I assume that you are familiar with that.

    cyrille

    Tuesday, January 13, 2015 4:46 PM