Hi all,

This is my second post. I got some awesome help last time I posted. Thanks.

So for my intro to programming class we had to write a Tic Tac Toe game played against the computer. The computer A.I will just pick randomly until:

1. it's possible to win in one move

2. it's possible to block the user's winning move

3. or continue to pick randomly until one of the above come true

Alright. I got all of this to work just fine. My question to you is:

How would I modify the computerAI() method to work with a larger board?

Basically my A.I does not translate to bigger boards.

I know I can add more &&'s and if statements but that just seems too half ass. I want to be able to just change the constants ROW and COL(declared at the class level) to create a bigger board and have the rest of the code remain unchanged.

Maybe someone has a suggestion on how I could rewrite the computerAI() to be more "portable" or "generic" and less specific to a 3X3 game of Tic Tac Toe.

Hope that makes some sense.

I feel like I'm so close, but I might be missing something very elementary.

BTW I looked into the minimax algorithm a little and it looks daunting to me right now. I do want to take a crack at it once I get this solved.

Thanks for reading.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TicTacToe
{
    class Program 
    {
        const int ROWS = 3;
        const int COLS = 3;

        static void Main(string[] args)
        {
            string[,] board = new string[ROWS, COLS];/*{{"1","2","3"},
                                                        {"4","5","6"},
                                                        {"7","8","9"}}*/
            setBoard(board);            
            bool endGame = false;
            while (!endGame)
            {
                playerTurn(board);
                endGame = checkForWin(board, "X");
                if (endGame)
                {
                    printBoard(board);
                    Console.WriteLine("You win!");
                }
                else
                {
                    endGame = checkForTie(board);
                    if (endGame)
                    {
                        printBoard(board);
                        Console.WriteLine("Tie Game");
                    }
                    else
                    {
                        endGame = computerTurn(board,"O");
                        endGame = checkForWin(board, "O");
                        if (endGame)
                        {
                            printBoard(board);
                            Console.WriteLine("Computer wins");
                        }
                        else
                        {
                            endGame = checkForTie(board);
                            if (endGame)
                            {
                                printBoard(board);
                                Console.WriteLine("Tie Game");
                            }
                        }
                    }
                }
            }
        }
        static void setBoard(string[,] board)
        {
            int position = 1;
            while (position < ROWS * COLS + 1)
                for (int row = 0; row < ROWS; row++)                
                    for (int col = 0; col < COLS; col++)
                        board[row, col] = Convert.ToString(position++);
        }
        static void printBoard(string[,] board)
        {
            Console.Clear();
            for (int row = 0; row < ROWS; row++)
            {
                Console.WriteLine("\n");
                for (int col = 0; col < COLS; col++)
                {
                    Console.Write("{0,2}{1,2}", board[row, col], " ");
                }
            }
            Console.WriteLine();
        }
        static void playerTurn(string[,] board)
        {
            int pick = 0, row = 0, col = 0;
            bool validPick = false;
            while (!validPick)
            {
                try
                {
                    printBoard(board);
                    Console.WriteLine("\n");
                    Console.WriteLine("Pick a position # then press Enter");
                    pick = Convert.ToInt32(Console.ReadLine());
                    row = (pick - 1) / ROWS;
                    col = (pick - 1) % COLS;
                    if (board[row, col] == "X" || board[row, col] == "O")
                    {
                        validPick = false;
                        Console.WriteLine("Position already taken, press enter to pick again");
                        Console.ReadLine();
                    }
                    else
                        validPick = true;
                }
                catch (Exception myException)
                {
                    validPick = false;
                    Console.WriteLine(myException.Message);
                    Console.WriteLine("Press enter to pick agian");
                    Console.ReadLine();
                }
            }
            board[row, col] = "X";
        }
        static bool computerTurn(string[,] board, string mark)
        {
            bool smartMove = false;
            smartMove = computerAI(board,"O");//check for one move win
            if (!smartMove)
            {
                smartMove = computerAI(board, "X");//check for blocking move
            } 
            //If there's no one move win or block move then computer picks randomly
            while (!smartMove)
            {
                Random randNum = new Random();
                int pick = 0, row = 0, col = 0;
                do
                {
                    pick = randNum.Next(1, ROWS * COLS + 1);
                    row = (pick - 1) / ROWS;
                    col = (pick - 1) % COLS;
                }
                while (board[row, col] == "X" || board[row, col] == "O");
                {
                    board[row, col] = "O";
                    smartMove = true;
                }
            }
            return smartMove;
        }
        static bool computerAI(string[,] board, string mark)
        {
            // computer checks for one move win on first call
            //then checks for block move on second call
            int row, col;
            bool smartMove = false;
            if (!smartMove)
            {
                for (row = 0; row < ROWS; row++)
                {
                     col = 0;
                    if ((board[row, col] == board[row, col + 1]) && (board[row, col] == mark) && 
                        (board[row, col + 2] != "X") && (board[row, col + 2] != "O") && smartMove == false)
                    {
                        board[row, col + 2] = "O";
                        smartMove = true;
                    }
                    if ((board[row, col + 1] == board[row, col + 2]) && (board[row, col + 1] == mark) &&
                        (board[row, col] != "X") && (board[row, col] != "O") && (smartMove == false))
                    {
                        board[row, col] = "O";
                        smartMove = true;
                    }
                    if ((board[row, col] == board[row, col + 2]) && (board[row, col] == mark) && 
                        (board[row, col + 1] != "X") && (board[row, col +  1] != "O") && (smartMove == false))
                    {
                        board[row, col + 1] = "O"; ;
                        smartMove = true;
                    }
                }
                for (col = 0; col < COLS; col++)
                {
                     row = 0;
                    if ((board[row, col] == board[row + 1, col]) && (board[row, col] == mark) &&
                        (board[row + 2, col] != "X") && (board[row + 2, col] != "O") && (smartMove == false))
                    {
                        board[row + 2, col] = "O";
                        smartMove = true;
                    }
                    if ((board[row + 1, col] == board[row + 2, col]) && (board[row + 1, col] == mark) &&
                        (board[row, col] != "X") && (board[row, col] != "O") && (smartMove == false))
                    {
                        board[row, col] = "O";
                        smartMove = true;
                    }
                    if ((board[row, col] == board[row + 2, col]) && (board[row, col] == mark) &&
                        (board[row + 1, col] != "X") && (board[row + 1, col] != "O") && (smartMove == false))
                    {
                        board[row + 1, col] = "O";
                        smartMove = true;
                    }
                }
                //first diagonal
                row = 0;
                col = 0;
                if ((board[row, col] == board[row + 1, col + 1]) && (board[row + 1, col + 1] == mark) &&
                    (board[row + 2, col + 2] != "X") && (board[row + 2 ,col + 2] != "O") && (smartMove == false))
                {
                    board[row + 2, col + 2] = "O";
                    smartMove = true;
                }
                if ((board[row + 2, col + 2] == board[row + 1, col + 1]) && (board[row + 1, col + 1] == mark) &&
                    (board[row, col] != "X") && (board[row, col] != "O") && (smartMove == false))
                {
                    board[row, col] = "O";
                    smartMove = true;
                }
                if ((board[row, col] == board[row + 2, col + 2]) && (board[row + 2, col + 2] == mark) &&
                    (board[row + 1, col + 1] != "X") && (board[row + 1, col + 1] != "O") && (smartMove == false))
                {
                    board[row + 1, col + 1] = "O";
                    smartMove = true;
                }
                //second diagonal
                if ((board[row + 2, col] == board[row + 1, col + 1]) && (board[row + 1, col + 1] == mark) &&
                    (board[row, col + 2] != "X") && (board[row, col + 2] != "O") && (smartMove == false))
                {
                    board[row, col + 2] = "O";
                    smartMove = true;
                }
                if ((board[row, col + 2] == board[row + 1, col + 1]) && (board[row + 1, col + 1] == mark) &&
                    (board[row + 2, col] != "X") && (board[row + 2, col] != "O") && (smartMove == false))
                {
                    board[row + 2, col] = "O";
                    smartMove = true;
                }
                if ((board[row + 2, col] == board[row,col +  2]) && (board[row, col + 2] == mark) &&
                    (board[row + 1, col + 1] != "X") && (board[row + 1, col + 1] != "O") && (smartMove == false))
                {
                    board[row + 1, col +  1] = "O";
                    smartMove = true;
                }
            }
            return smartMove;
        }
        static bool checkForTie(string[,] board)
        {
            bool tie = true;
            for (int row = 0; row < ROWS; row++)
                for (int col = 0; col < COLS; col++)                
                    if (board[row, col] != "X" && board[row, col] != "O")
                        tie = false;                                
            return tie;
        }
        static bool checkForWin(string[,] board, string mark)
        {
            bool win = false;
            int row, col;
            //check rows for 3 = marks
            row = 0;
            while (row < ROWS && !win)
            {
                win = true;
                col = 0;

                while (col < COLS && win)
                {
                    if (board[row, col] != mark)
                        win = false;                    
                    col++;
                }
                row++;
            }
            //check colums for 3 = marks
            col = 0;
            while (col < COLS && !win)
            {
                win = true;
                row = 0;
                while (row < ROWS && win)
                {
                    if (board[row, col] != mark)
                    {
                        win = false;
                    }
                    row++;
                }
                col++;
            }
            if (!win)
            {
                //check diagonal for 3 = marks
                win = true;
                row = 0;
                while (row < ROWS && win)
                {
                    if (board[row, row] != mark)
                    {
                        win = false;
                    }
                    row++;
                }
            }
            if (!win)
            {
                //check other diagonal for 3 = marks
                win = true;
                row = 0;
                while (row < ROWS && win)
                {
                    if (board[row, 2 - row] != mark)
                    {
                        win = false;
                    }
                    row++;
                }
            }
            return win;
        }
    }
}

Edited 6 Years Ago by brettbed: n/a

I think your main problem is you are not making an option to where neither a wining move or a blocking move is found anywhere. I think you need to check each one instead of checking randomly. If no good moves are found then pick a random spot to put it in maybe. Just a suggestion. Sorry I didn't go more in depth but I gotta leave here in a minute.

I think your main problem is you are not making an option to where neither a wining move or a blocking move is found anywhere. I think you need to check each one instead of checking randomly. If no good moves are found then pick a random spot to put it in maybe. Just a suggestion. Sorry I didn't go more in depth but I gotta leave here in a minute.

Take another look or rum the program and you should find that if the computer has a chance to win or block it will. It just doesn't start out knowing how to win. Anyway thanks for replying. I've moved on to other stuff for now. I'll get back to this once school is out.

Peace.

This article has been dead for over six months. Start a new discussion instead.