Skip to content

Instantly share code, notes, and snippets.

@milesrout
Created March 23, 2017 22:51
Show Gist options
  • Save milesrout/1510d08a600d2a31c77de923e922a18e to your computer and use it in GitHub Desktop.
Save milesrout/1510d08a600d2a31c77de923e922a18e to your computer and use it in GitHub Desktop.
import random
def make_board():
return [[None, None, None], [None, None, None], [None, None, None]]
def f(x):
if x is None:
return 'X'
elif x == 'X':
return '1'
else:
return '0'
def do_move(b, move):
return [[b[i][j] if (i, j) != move else f(b[i][j])
for j in range(0, 3)]
for i in range(0, 3)]
def is_done(b):
rows = [[(0, i), (1, i), (2, i)] for i in range(3)]
cols = [[(i, 0), (i, 1), (i, 2)] for i in range(3)]
diags = [[(0, 0), (1, 1), (2, 2)], [(0, 2), (1, 1), (2, 0)]]
for (x, y, z) in rows + cols + diags:
if get(b, x) == get(b, y) and get(b, y) == get(b, z):
if get(b, x) == 'X' or get(b, x) == '0':
trace(x, y, z)
trace(get(b, x), get(b, y), get(b, z))
return True
return False
def get(b, x):
i, j = x
return b[i][j]
def print_board(b):
trace(template.format(*(' ' if y is None else y for x in b for y in x)))
def trace(*args, **kwds):
pass # print(*args, **kwds)
template = '\n\
{} | {} | {} \n\
---+---+---\n\
{} | {} | {} \n\
---+---+---\n\
{} | {} | {} \n'
def main():
players = [input(f'What is your name, player {i}? ')
for i in range(1, 2+1)]
player = False
b = make_board()
while True:
trace()
print_board(b)
trace()
move = input(f'What is your move, {players[player]}? ')
move = map(int, move.split())
b = do_move(b, move)
if is_done(b):
trace()
print_board(b)
trace()
trace(f'{players[player]} has WON!')
break
player = not player
def great_move(b, m):
return is_done(do_move(b, m))
def shit_move(b, m):
b1 = do_move(b, m)
return any(great_move(b1, m) for m in possible_moves(b1))
def legal_move(b, m):
return get(b, m) != '0'
def possible_moves(b):
return [(i, j) for i in range(0, 3) for j in range(0, 3)
if legal_move(b, (i, j))]
def optimal_move(b):
if any(great_move(b, m) for m in possible_moves(b)):
return random.choice([m for m in possible_moves(b)
if great_move(b, m)])
if any(not shit_move(b, m) for m in possible_moves(b)):
return random.choice([m for m in possible_moves(b)
if not shit_move(b, m)])
return random.choice(possible_moves(b))
def ai(b, name):
while True:
m = optimal_move(b)
b = do_move(b, m)
trace(f'{name}:')
print_board(b)
b = do_move(b, (yield m))
def trial():
b = make_board()
p1 = ai(b, 'p1')
p1.__name__ = 'p1'
move = p1.send(None)
b = do_move(b, move)
p2 = ai(b, 'p2')
p2.__name__ = 'p2'
move = p2.send(None)
b = do_move(b, move)
while True:
move = p1.send(move)
trace(f'move from {p1.__name__}: {move}')
b = do_move(b, move)
if is_done(b):
trace(p1.__name__, 'has won!')
return p1.__name__
(p1, p2) = (p2, p1)
def aimain():
winners = {
'p1': 0,
'p2': 0
}
for i in range(1000):
winners[trial()] += 1
print(winners)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment