Grid:
TTTSize[s_] := IntegerPart[Sqrt[Length[s]]];
TTTMatrix[s_] := Partition[s, TTTSize[s]];
TTTGrid[s_] := Grid[TTTMatrix[s], Frame -> All, ItemSize -> {N@GoldenRatio, N@GoldenRatio}];
TTTGrid[Characters["XXOO-OXOX"]]
Winner?
TTTWinner[s_, t_] := With[
{n = TTTSize[s], T = TTTMatrix[s]},
MemberQ[
Join[T, Transpose[T], {Diagonal[T]}, {Diagonal[Reverse[T]]}],
Array[t &, n]
]
];
X wins when {X, X, X} is a row, a column, or a diagonal.
Two-player game using row-major indexing:
n = 3;
t = Riffle[Array["X" &, Ceiling[n^2/2]], Array["O" &, Floor[n^2/2]]];
s = Array["-" &, n^2];
d = 1;
b = False;
While[d <= n^2 && !b,
a = ToExpression[Input[]];
s[[a]] = t[[d]];
Print[t[[d]], "@", a];
Print@TTTGrid[s];
If[TTTWinner[s, t[[d]]],
Print[t[[d]] <> " is a winner."];
b = True;
];
d++;
];
Given that X starts and the players alternate turns, a game ending is represented as a sequence of integers corresponding to grid positions chosen by the players at each turn. With this representation, the possible tic-tac-toe game endings are the permutations of {1, 2, 3, 4, 5, 6, 7, 8, 9}; they are all valid by construction.
n = 3;
t = Riffle[Array["X" &, Ceiling[n^2/2]], Array["O" &, Floor[n^2/2]]];
won = 0;
draw = 0;
lost = 0;
total = 0;
Do[
s = Array["-" &, 9];
d = 1;
b = False;
While[d <= n^2 && !b,
s[[i[[d]]]] = t[[d]];
If[TTTWinner[s, t[[d]]],
If[OddQ[d], won++, lost++];
b = True;
];
d++;
];
If[!b, draw++];
, {i, Permutations[Range[9]]}
];
won
draw
lost
won + draw + lost
212256
46080
104544
362880
However, this is an overestimate of the number of "actual" games, because two game endings can map to the same game, e.g., {
1, 2, 3, 4, 5, 6, 7, 8, 9} and {
1, 2, 3, 4, 5, 6, 7, 9, 8} (X has already won by the 7th turn). To get the right numbers, the rest of a permutation is dropped whenever one of the players wins, e.g., {
1, 2, 3, 4, 5, 6, 7, 8, 9} and {
1, 2, 3, 4, 5, 6, 7, 9, 8} would both map to {1, 2, 3, 4, 5, 6, 7} and X wins a single game instead of two.
n = 3;
t = Riffle[Array["X" &, Ceiling[n^2/2]], Array["O" &, Floor[n^2/2]]];
won = 0;
draw = 0;
lost = 0;
total = 0;
Clear[h];
h[_] := False;
Do[
s = Array["-" &, 9];
d = 1;
b = False;
While[d <= n^2 && !b,
s[[i[[d]]]] = t[[d]];
If[TTTWinner[s, t[[d]]],
If[!h[Take[i, d]],
h[Take[i, d]] = True;
If[OddQ[d], won++, lost++];
];
b = True;
];
d++;
];
If[!b, draw++];
, {i, Permutations[Range[9]]}
];
won
draw
lost
won + draw + lost
131184
46080
77904
255168
The numbers can be verified at the
Wikipedia article.