0

I am creating a tic-tac-toe game using HTML and JS. I store the board of any variable size (with width and height being the same) in a 2d array. Aka an array that stores rows of data. The data in those rows is the column, so you can access a position in the array using array[row][column]. I am trying to create a bot that will attempt to play against the player. I was thinking of brute-forcing for semi-empty rows/columns/diagonals with as few of the human-players pieces as possible. I also read about minmax bots being a better use of resources. But I can't find anything in JS, and I can't find anything I could convert to JS, as most other bots I've seen use 1d arrays with 9 elements. Again, my board can be literally any size of equal width an height, so I need to make a bot that understands this. Here is the broken code I have so far.

function startArtificialIdiot() {
    // General analytical skills.
    // First the bot will look for open rows, once it finds one it will check adjacent columns, and diagonals for the best play...
    let optimalPlay = [];
    let safeRows = [];

    // Generate row css.
    for (let row = 1; row <= boardSize; row++) {
        safeRows.push(row);
    }

    console.log(safeRows)

    // Loop through and remove rows that have player one's tile in them, or are full.
    rows: 
    for (let checkedRow = 1; checkedRow <= boardSize; checkedRow++) {
        // Go through each row, and check if all columns are empty.
        let columnsFull = 0;
        for (let column = 1; column <= boardSize; column++) {
            // If a row is occupied, we te add to the columnsFull counter.
            if (board[checkedRow][column] != "") {
                columnsFull ++;
            }
        }

        // If this row is full, then we remove it from the list.
        if (columnsFull == boardSize) {
            console.warn(`AI: Row ${checkedRow} is full. Deleting it from the list.`);
            safeRows.splice(safeRows.indexOf(checkedRow), 1);
        }
    }

    // If we can't find a good play we safely abort with a random play.
    if (safeRows.length == 0) {
        console.warn("AI: Playing randomly because I can't find a good place to play...");
        changePiece(Math.ceil(Math.random()*boardSize), Math.ceil(Math.random()*boardSize));
    }

    // Temporarily randomly play in one of the safe rows.
    let rowPick = safeRows[Math.floor(Math.random() * safeRows.length)];
    console.warn(`AI: Moving to row ${rowPick} from ${safeRows}`);
    changePiece(rowPick, Math.ceil(Math.random()*boardSize));

    console.log(safeRows);
}

Note that this function is called once per turn for the bot. It is also automatically re-called if the bot picks a slot on the board that is already filled.

TimTam
  • 63
  • 1
  • 8
  • 1
    You could look at [Alberto's GitHub repo](https://stackoverflow.com/questions/64882717/solving-tictactoe-with-minimax-algorithm-in-javascript) and see if he's made any progress. – user3386109 Nov 25 '20 at 00:18
  • 1
    If you wanted to do it alone, you could create an array of all the finishing wins, then check this array via your AI for a matching "hole". The "finishing wins" would be all the horizontals, all the verticals, and the two diagonals. – GetSet Nov 25 '20 at 01:07

0 Answers0