using System.Collections.Generic;
namespace TicTacToeCombos
public static void Main(string[] args)
Console.WriteLine($"Total number of distinct games: {Play(Board.Empty)}");
static int Play(Board board)
foreach (Board b in board.NextBoards())
private readonly Piece[,] m_pieces = new Piece[3, 3];
private readonly Piece m_nextPiece;
private readonly int m_piecesPlaced;
public readonly bool IsFinished;
private Board(Piece[,] pieces, Piece nextPiece, int piecesPlayed)
m_piecesPlaced = piecesPlayed;
IsFinished = GetIsFinished();
public static readonly Board Empty = new Board(new Piece[3, 3], Piece.X, 0);
public Board Next(Position pos, Piece piece)
Piece[,] next = new Piece[3,3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
next[i, j] = m_pieces[i, j];
if (m_pieces[x, y] != Piece.Empty)
throw new ArgumentException();
return new Board(next, piece == Piece.X ? Piece.O : Piece.X, m_piecesPlaced + 1);
public IEnumerable<Position> PossibleNextMoves()
foreach (Position pos in AllPositions())
if (m_pieces[pos.x, pos.y] == Piece.Empty)
public IEnumerable<Board> NextBoards()
foreach (Position pos in PossibleNextMoves())
yield return Next(pos, m_nextPiece);
private bool GetIsFinished()
for (int i = 0; i < 3; i++)
if (piece != Piece.Empty && m_pieces[1, i] == piece && m_pieces[2, i] == piece)
if (piece != Piece.Empty && m_pieces[i, 1] == piece && m_pieces[i, 2] == piece)
if (piece != Piece.Empty && m_pieces[1, 1] == piece && m_pieces[2, 2] == piece)
return piece != Piece.Empty && m_pieces[1, 1] == piece && m_pieces[2, 0] == piece;
private static IEnumerable<Position> AllPositions()
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++)
yield return new Position { x = x, y = y };