Skip to content

Instantly share code, notes, and snippets.

@nsmaciej
Created December 30, 2019 13:37
Show Gist options
  • Save nsmaciej/7b555c1dce45a023bffcaaff2c5b271e to your computer and use it in GitHub Desktop.
Save nsmaciej/7b555c1dce45a023bffcaaff2c5b271e to your computer and use it in GitHub Desktop.
Best Tic-tac-toe starting position
from functools import lru_cache
def straight(board, i):
return (
board[i][0] == board[i][1] == board[i][2] is not None
or board[0][i] == board[1][i] == board[2][i] is not None
)
def across(board):
return (
board[0][0] == board[1][1] == board[2][2] is not None
or board[0][2] == board[1][1] == board[2][0] is not None
)
def update(board, y, x, value):
return board[:y] + (board[y][:x] + (value,) + board[y][x + 1 :],) + board[y + 1 :]
@lru_cache(maxsize=None)
def outcome(board, turn=False, *, win):
if any(straight(board, i) for i in range(3)) or across(board):
return win != turn
return sum(
outcome(update(board, y, x, turn), not turn, win=win)
for y in range(3)
for x in range(3)
if board[y][x] is None
)
def find_ratio(pos):
board = update(empty_board, *pos, True)
return outcome(board, win=True) / outcome(board, win=False)
cache = {}
empty_board = ((None, None, None),) * 3
print(max([(0, 0), (0, 1), (1, 1)], key=find_ratio))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment