2

For my Tic Tac Toe AI it is only necessary to generate a random move. I have a class AIPlayer with a makeAMove function. It simply generates two random numbers from 0 - 3 (row and column) and checks if the cell is taken. It seems to work okay, but for some reason it will never take a winning move. On the command line when I try to let it win and there are only winning moves left for it to take, it will not take them--it just gets stuck.

Also, I think using a 1-dimesional array would be easier with the AI, but I'm trying to stick with the 2-dimesional array.

I think it would be better to somehow collect the available cells in another array and generate a random move from these cells.

Any suggestions are welcome.

Here is my AI class:

Implementation file:

#include <stdlib.h> // rand, srand
#include <time.h> // time
#include "AIPlayer.h"

AIPlayer::AIPlayer(char token) : Player(token)
{
}

void AIPlayer::makeAMove(Board &myBoard)
{
    int row;
    int column;

    bool done = false;
    do
    {
        srand (time(0));
        row = rand() % 3;
        column = rand() % 3;

        if (myBoard.getCell(row, column) == ' ')
        { 
            myBoard.setCell(row, column, getToken());
            done = true;
        }
    }
    while (!done);

    std::cout <<    "\nComputer move (" << getToken() << ")\n"
                    "row " << row << ", column " << column;
}

Header file:

#pragma once // include guard
#include "Player.h"

class AIPlayer: public Player
{
    public:
        AIPlayer(char token);
        virtual void makeAMove(Board &myBoard);
};
navig8tr
  • 1,724
  • 8
  • 31
  • 69

1 Answers1

3

In each iteration of the loop you call srand(time(0)).

This resets the random number generation based on the number of elapsed seconds.

This means that each time the computer will select the same random place to move (until the number of seconds change)

Probably it will actually work after around a minute, but it is better to move srand out of the loop.

Peter de Rivaz
  • 33,126
  • 4
  • 46
  • 75
  • 1
    actually `time(0)` will change each second. It is good to move the code out of the loop but I doubt this is the problem. I bet on the board not being initialized with `' '` – Ivaylo Strandjev Dec 16 '13 at 19:10
  • 1
    Good point. You should not constantly re-initialize your random number generators. – Mad Physicist Dec 16 '13 at 19:10
  • @Peter de Rivaz: Moving `srand(time(0))` outside the loop seems to have fixed it. Thanks. – navig8tr Dec 16 '13 at 19:14
  • It's very confusing why that would be, since as @IvayloStrandjev says, `time(0)` should change every second... – Andrey Mishchenko Dec 16 '13 at 19:16
  • 2
    @Andrey maybe OP is **really** unlucky ;) – Ivaylo Strandjev Dec 16 '13 at 19:18
  • 3
    The default rand function only has 32767 possible values, and is statistically [absolutely terrible](http://stackoverflow.com/questions/10692388/can-rand-really-be-this-bad). The first random number you generate from a given seed diverge very slowly as the seed changes. On top of that you're taking rand() % 3 which is a very bad thing to do as again it destroys the randomness due to the bad algorithm used. Get a better (literally any other) RNG and this problem will disappear. – user2711915 Dec 16 '13 at 19:28