1

I have table and some functions like Generate_moves() etc. but for the minmax algorithm to work I need to set a score for tables to make the computer choose the best table.

        public int Score()
        {
            if (Turn == "X")
            {
                if (gameWon("X")) return 100;
                if (gameWon("O")) return -100;
                if (gameDrawn()) return 0;

                return n - canWin("X");
            }

            if (Turn == "O")
            {
                if (gameWon("O")) return 100;
                if (gameWon("X")) return -100;
                if (gameDrawn()) return 0;

                return n - canWin("O");
            }

            return -1;
        }

My canWin(string) returns a number that tells me how many Xs or Os i have in a straight line or column but I doubt it is a great why to set the score for a table.

If I have the table:

X - X
0 X 0
- - 0

the score should be the same as

X - -
0 - X
0 0 X

and should be bigger than

X - X
0 - -
- 0 -

And I don't have any idea how to make the Score function tell me different scores. How can I implement the method Score to tell me this?

Edit:

if computer is first with X and me with O

X - -      X - -      X - -     X - -
- - -   -> 0 - -   -> 0 X -  -> 0 X -
- - -      - - -      - - -     - - 0

now how can i make the computer choose that the next best option is

X - X
0 X -
- - 0
Dementor
  • 241
  • 1
  • 6
  • 12
  • 1
    I don't understand. The best thing you can do is to win, play draw, or loose, shouldn't 1, 0 and -1 be enough for scores? – aioobe Feb 08 '12 at 13:58
  • I'm not sure I understand how you are attempting to score this. In all three examples X is 1 move from winning while O is always 2 moves. How are they different? – Mark Smith Feb 08 '12 at 13:59
  • I need a Score function for MinMax. 1 0 -1 are not accurate enough because in the first X - X 0 X 0 - - 0 i can't say 0 1 -1 because non fit so it should be expanded – Dementor Feb 08 '12 at 14:03
  • @mark yes it's true but between the first and the third i prefer the first because it leads to more wins for X than the third I should modify it a little like 1)X - X 0 X - - - 0 2) X - X 0 - - - - - – Dementor Feb 08 '12 at 14:05

5 Answers5

1

Tic-Tac-Toe is a relatively easy game for computers - since the branch factor and number of possibilities is relatively small, thus: It'll be best to create the easiest [to calculate] possible heuristic function, and let the minmax reach the deepest level, the leaves of the game tree, which are all a certain win/loss/draw.

If you are still looking for a heuristic, you can use number of rows/cols/diagonals with exactly 2 "X"s and left square is empty

Nevertheless, I still think [for this specific problem] a minmax algorithm that returns -1 for loss, 1 for win and 0 for all other possibilities will perform better - since it will reach the game's leaves faster, and thus will be more informed then any heuristic.

amit
  • 175,853
  • 27
  • 231
  • 333
  • ok but when MinMax reaches its deepest level there will be lets say 10 wins 20 draws and 10 loses which branch that leads me to a win should i take? – Dementor Feb 08 '12 at 14:21
  • @Dementor: minmax does not handle with equalities - any decision which branch to take is an optimization and a heuristic over minmax. You should take a branch that can guarantee you - you won't lose in it, if you continue to follow minmax. You can make an extra optimization of `if two paths has the same score: use a "tie-breaker: the path with most paths calculated victorious" – amit Feb 08 '12 at 14:25
  • @Dementor: p.s. minmax doesn't handle with this because it "doesn't care" - if both you and your oponent will follow minmax, the score of the game will be **exactly** the score returned by minmax – amit Feb 08 '12 at 14:26
  • I did a minmax that reaches the deepest level and it tells me if the game will end in a win/draw/lose but for a normal tictactoe (3by3) for first move it takes ~1sec and if I increase 5by5 i waited 1 min and it was still calculating so there must be another way not to wait that much. – Dementor Feb 11 '12 at 08:05
1

I think you are overcomplicating things. There are less than 400,000 possible Tic-tac-toe games - in fact, Tic-tac-toe is simple enough that you can write down the best moves for every possible game on a single sheet of paper

(complete tic-tic-toe map) - XKCD

Even an algorithm as simple as minmax is overkill - just check all possible moves by brute-force. It should only take a few milliseconds on a modern PC.

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
0

I know what you're talking about. What you need is a good heuristic function. You can find heuristic functions from here (I did not try any of them):

Solve Tic Tac Toe with the MiniMax algorithm

Visualgos: Tic-Tac-Toe

batbaatar
  • 5,448
  • 2
  • 20
  • 26
0

One possibility...Score = Number of remaining ways (rows, columns or diagonals which can still be filled to winning state) to win for x - Number of remaining ways to win for 0 for every state which is not a leaf (final state) For the leaf states you only have Score = 1, 0 or -1

xyz
  • 211
  • 1
  • 3
  • my problem with the score function is that i need the score function for if (score(move) > score(best_move)) { best_move < - move; } – Dementor Feb 08 '12 at 14:17
  • Winning = +infinite, Losing = -infinite, Draw = 0, the rest is the difference above mentioned. – xyz Feb 08 '12 at 14:21
0

To answer your second question:

now how can i make the computer choose that the next best option is...

This is the task of the minimax algorithm. It peeks the best move from the game-tree. For tic-tac-toe you don't need a very sophisticated evaluation function, it's enough to return a positiv or negativ value if a player has won or 0 otherwise. If you like, you can extend it by evaluating if one player can win in the next move. More sophisticated evaluation functions you need in games with a greater branching factor and where the game-tree can get much deeper (not only 9 moves).
My experience* was, that going one ply deeper in game-tree search yields to better results than not reaching this ply (in the same time) because of a smarter evaluation function. It's not so easy to distinguish between deeper searches because of a simple evaluation or not so deep searches because of a sophisticated evaluation. There are a lot of other significant enhancements to the minimax algorithm which are promising, don't get stuck with a complicated evaluation, first think of:

After then you still can improve the evaluation function. Some other thoughts to the evaluation: Maybe it's better to do some work in the function makeMove, here you only need to check one (instead of all) row, one column and one or two diagonals. Then, beside the current board, keep the information got from this check. This information includes, if this was a winning move (set the score), or if the next move from the other player is forced (remember the move the next player has to make, getMoves will only return this one). Last but not least, if one column/row and one diagonal includes a forced move, the player wins in two moves (keep the score).

Good luck with your evaluation function!

* Some time ago I worked on the evaluation function of a Connect-Four-Game-Engine. The best approach for evaluating a connect-four board was to analyze the odd and even threats as descibed in the chapter "Threat Analysis" of the articel Expert Play in Connect-Four from James D. Allen. The algorithm analyzed major and minor threats. After removing the minor threat analisis part, the alpha-beta search performed better!

Christian Ammer
  • 7,464
  • 6
  • 51
  • 108