Efficient algorithm for counting unique states of tic tac toe

后端 未结 6 839
抹茶落季
抹茶落季 2021-02-07 12:51

I\'m trying to build a tic tac toe game to demonstrate and experiment with machine learning algorithms, and i\'ve found an interesting problem.

eg: a tic tac toe board c

相关标签:
6条回答
  • 2021-02-07 12:55

    I think graph theory is good for this, you would have a graph with 9 vertices for the example you gave. The only thing that could still be a problem is juxtapositions.

    0 讨论(0)
  • 2021-02-07 12:58

    Tic tac toe is related to AI, specifically minmax algorithm from Game theory, even more specifically AB Pruning for good results. The entire topic is huge, but is easy and procudural. It is easy to grasp and you can get started at these page:

    http://en.wikipedia.org/wiki/Game_theory

    http://www.cs.trincoll.edu/~ram/cpsc352/notes/minimax.html

    Something lucid and easier than the above link:

    http://www.cs.ucla.edu/~rosen/161/notes/alphabeta.html

    0 讨论(0)
  • 2021-02-07 13:06

    If you care only about optimal moves:

    See this systematic map of optimal tic-tac-toe moves (http://xkcd.com/832/). You can use some (col, row) indexing to identify a particular state.

    If there is more than one equivalent state, use the "lowest" index (you have to define what "lowest" means; e.g. that (col,row) pair whose value 3*col+row is lowest) of all equivalent ones.

    Complete map of optimal tic-tac-toe moves

    0 讨论(0)
  • 2021-02-07 13:09

    I don't know the proper mathematical way, but I'd do it like this. Devise a way to convert any state to one number. For instance, assign empty field to zero, O piece to 1, X piece to 2, and treat 9 digits as a number in base-3 system. Now, transform the state to all 7 remaining mirror states. Calculate their numbers too. Pick the smallest out of those 8 numbers. That's it.

    0 讨论(0)
  • 2021-02-07 13:11

    Combining some of the ideas from the other answers...

    Do not map configurations to numbers. Use numbers to represent configurations. Write methods to operate on the representation if you really need to get/set by x,y location.

    Then choose a representation that you can operate on efficiently to answer the question. Here is one idea.

    You have three operations, so let's give them names:

    • R = rotate board 90 degrees counter-clockwise
    • M = mirror board about y-axis
    • I = invert board (what you call "juxtapose", but I think "invert" is more descriptive)

    You want to count the number of equivalence classes of boards under the orbit of these operations. There are at most 16 elements in each equivalence class. Given a board, you can generate the other 15 equivalent boards by applying the operations in the following sequence:

    R, R, R, I, R, R, R, M, R, R, R, I, R, R, R

    (There are other sequences that work, too...)

    So a good idea would be to pick a representation that makes R fast, I somewhat fast, and not worry too much about M.

    Since R does not change the center, I would hold that somewhere else, and use a sequence of 2-bit numbers to represent the other 8 squares. I would let the first 2-bit number represent the lower-left, the next 2-bit number represent the square next to that, and so on, moving counter-clockwise around the board. I would let 00 represent "O", 11 represent "X", and both 01 and 10 represent "empty" (because then operation I becomes a simple flipping of bits).

    Then if you write those 8 2-bit numbers as a single 16-bit number, operation R is just a rotate operation on the 16-bit number, which your CPU can probably perform in a single instruction. Operation I is just XOR with -1 (but do not forget to invert the center square too). Operation M is a complicated bunch of bit-munging, but since you only do it one time out of 15, who cares?

    This should let you take any representation and quickly generate the other 15 that are equivalent. Then as Dialecticus suggests, pick the numerically smallest representation as your canonical member of the equivalence class and count those.

    0 讨论(0)
  • 2021-02-07 13:18

    Math

    The trick is to use Polyas enumeration theorem:

    http://en.wikipedia.org/wiki/P%C3%B3lya_enumeration_theorem

    Ignoring the duplicates, there are 9 squares of 3 states (x, o and -), so there are 3^9 = 19683 configurations. You need to define the group which provides actions on the board. For your problem the Dihedral Group D4 seems to work for everything but the juxtapositions. But the juxtapositions are easy since there are 2 whenever it is not a board full of don't cares (all -, the initial configuration).

    Computation

    While the math lets us count the configurations, it doesn't help identify them. The perhaps simplest solution is to define a board as a tuple: {p1, p2, p3, ..., p9} where each pn is either {0,1,2}. It requires 2 bits per square and there are 9 of them for a total of 18 bits. A board hence can be represented by a 32bit integer or less.

    Indexing into boards is easily done by a hash table. There are only the 19000 configurations, so it isn't going to kill us.

    Running through all board configurations is best done on radix-3 arithmetic on the 9-tuple above: {0,0,9,...,0}, {0,0,0,..., 1}, {0,0,0,...,1,0} and so on. It is just addition with carry. This generates all boards. Notice how the group action and juxtaposition will transform such a number. There is a limited amount of possibilities (juxta shifts x to o and vice versa, the others moves around positions on the board according to the D4 group. There are 8 such transformations.) You can use Polya to make sure your algorithm got them all.

    As suggested, picking the smallest guy from the set is a unique representant of the configuration modulo the actions.

    0 讨论(0)
提交回复
热议问题