Skip to content

Instantly share code, notes, and snippets.

@gvx
Created December 13, 2020 20:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gvx/5321cb6d1957dc876443e6f173a3b248 to your computer and use it in GitHub Desktop.
Save gvx/5321cb6d1957dc876443e6f173a3b248 to your computer and use it in GitHub Desktop.
Generate a 82MB implementation of tic tac toe
from typing import Optional, Literal, Iterator
Player = Literal['X', 'O']
BoardEntry = Literal['X', 'O', ' ']
Board = tuple[BoardEntry, BoardEntry, BoardEntry, BoardEntry, BoardEntry, BoardEntry, BoardEntry, BoardEntry, BoardEntry]
def new_board() -> Board:
return tuple(' ' * 9)
def is_draw(board: Board) -> bool:
return ' ' not in board
def play(board: Board, place: int, player: Player) -> Board:
return board[:place] + (player,) + board[place + 1:]
def other(player: Player) -> Player:
if player == 'X':
return 'O'
return 'X'
def winner(board: Board, place: int) -> Optional[Player]:
player = board[place]
row = place // 3
col = place % 3
if (board[row * 3] == board[row * 3 + 1] == board[row * 3 + 2] or
board[col] == board[col + 3] == board[col + 6] or
(row == col and board[0] == board[4] == board[8]) or
(row == 2 - col and board[2] == board[4] == board[6])):
return player
def indent(depth: int) -> Iterator[str]:
yield ' ' * depth
def generate_play(board: Board, player: Player, place: int, depth: int) -> Iterator[str]:
board = play(board, place, player)
yield from indent(depth)
yield 'print("'
yield '\\n'.join('|'.join(board[n:n + 3]) for n in range(0, 9, 3))
yield '")\n'
if (w := winner(board, place)):
yield from indent(depth)
yield 'print("'
yield w
yield ' wins!")\n'
elif is_draw(board):
yield from indent(depth)
yield 'print("Draw!")\n'
else:
yield from turn_for(board, other(player), depth)
def turn_for(board: Board, player: Player, depth: int = 0) -> Iterator[str]:
yield from indent(depth)
yield 'inp = input("'
yield player
yield ' plays: ")\n'
first = True
for i in range(9):
if board[i] != ' ':
continue
yield from indent(depth)
if not first:
yield 'el'
first = False
yield 'if inp == "'
yield str(i + 1)
yield '":\n'
yield from generate_play(board, player, i, depth + 1)
def generate_full_game():
yield from turn_for(new_board(), 'X')
if __name__ == '__main__':
print(''.join(generate_full_game()))
inp = input("X plays: ")
if inp == "1":
print("X| | \n | | \n | | ")
inp = input("O plays: ")
if inp == "2":
print("X|O| \n | | \n | | ")
inp = input("X plays: ")
if inp == "3":
print("X|O|X\n | | \n | | ")
inp = input("O plays: ")
if inp == "4":
print("X|O|X\nO| | \n | | ")
inp = input("X plays: ")
if inp == "5":
print("X|O|X\nO|X| \n | | ")
inp = input("O plays: ")
if inp == "6":
print("X|O|X\nO|X|O\n | | ")
inp = input("X plays: ")
if inp == "7":
print("X|O|X\nO|X|O\nX| | ")
print("X wins!")
elif inp == "8":
print("X|O|X\nO|X|O\n |X| ")
inp = input("O plays: ")
if inp == "7":
print("X|O|X\nO|X|O\nO|X| ")
inp = input("X plays: ")
if inp == "9":
print("X|O|X\nO|X|O\nO|X|X")
print("X wins!")
elif inp == "9":
print("X|O|X\nO|X|O\n |X|O")
inp = input("X plays: ")
if inp == "7":
print("X|O|X\nO|X|O\nX|X|O")
print("X wins!")
elif inp == "9":
print("X|O|X\nO|X|O\n | |X")
print("X wins!")
elif inp == "7":
print("X|O|X\nO|X| \nO| | ")
inp = input("X plays: ")
if inp == "6":
print("X|O|X\nO|X|X\nO| | ")
inp = input("O plays: ")
if inp == "8":
print("X|O|X\nO|X|X\nO|O| ")
inp = input("X plays: ")
if inp == "9":
print("X|O|X\nO|X|X\nO|O|X")
print("X wins!")
elif inp == "9":
print("X|O|X\nO|X|X\nO| |O")
inp = input("X plays: ")
if inp == "8":
print("X|O|X\nO|X|X\nO|X|O")
print("Draw!")
elif inp == "8":
print("X|O|X\nO|X| \nO|X| ")
inp = input("O plays: ")
if inp == "6":
print("X|O|X\nO|X|O\nO|X| ")
inp = input("X plays: ")
if inp == "9":
print("X|O|X\nO|X|O\nO|X|X")
print("X wins!")
elif inp == "9":
print("X|O|X\nO|X| \nO|X|O")
inp = input("X plays: ")
if inp == "6":
print("X|O|X\nO|X|X\nO|X|O")
print("Draw!")
elif inp == "9":
print("X|O|X\nO|X| \nO| |X")
print("X wins!")
elif inp == "8":
print("X|O|X\nO|X| \n |O| ")
inp = input("X plays: ")
if inp == "6":
print("X|O|X\nO|X|X\n |O| ")
inp = input("O plays: ")
if inp == "7":
print("X|O|X\nO|X|X\nO|O| ")
inp = input("X plays: ")
if inp == "9":
print("X|O|X\nO|X|X\nO|O|X")
print("X wins!")
elif inp == "9":
print("X|O|X\nO|X|X\n |O|O")
inp = input("X plays: ")
if inp == "7":
print("X|O|X\nO|X|X\nX|O|O")
print("X wins!")
elif inp == "7":
print("X|O|X\nO|X| \nX|O| ")
print("X wins!")
elif inp == "9":
print("X|O|X\nO|X| \n |O|X")
print("X wins!")
[1649738 lines omitted...]
@gvx
Copy link
Author

gvx commented Dec 13, 2020

Run both the generator and the resulting game at your own risk 😉

This has no error handling, invalid input causes the game to quit without immediately. Input has to be a single non-zero digit (i.e. [1-9]). Trying to place your X or O where there already is an X or O counts as invalid input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment