Skip to content

Instantly share code, notes, and snippets.

@haansn08
Last active May 29, 2022 19:01
Show Gist options
  • Save haansn08/c94adf1798aae5ec1a6a46210146e10d to your computer and use it in GitHub Desktop.
Save haansn08/c94adf1798aae5ec1a6a46210146e10d to your computer and use it in GitHub Desktop.
Variation of Tic-Tac-Toe where players have numbers 1 to 9 for their moves
# board is an array with indices in following arrangement
#
# 1 | 5 | 2
# ---------
# 6 | 0 | 7
# ---------
# 3 | 8 | 4
win_indices = [
(1,5,2), (6,0,7), (3,8,4), #left to right
(1,6,3), (5,0,8), (2,7,4), #top to bottom
(1,0,4), (2,0,3) #diagonal
]
# Player A uses the numbers 1,2,...,9
# Player B uses the numbers -1,-2,...,-9
# 0 means the field is not taken
# returns 1 for player A, -1 for player B, 0 for no winner
def winner(board):
for a,b,c in win_indices:
if board[a] > 0 and board[b] > 0 and board[c] > 0:
return 1
if board[a] < 0 and board[b] < 0 and board[c] < 0:
return -1
return 0
# enumerate valid moves for player A (player=1) or player B (player=-1)
def moves(player, board):
player_numbers = range(9,0,-1) if player > 0 else range(-9,0)
numbers_left = set(player_numbers)
numbers_left.difference_update(board)
for i in range(9):
number = abs(board[i])
for x in player_numbers:
if abs(x) > number and x in numbers_left:
yield i,x
def evaluate(player, board):
winning_player = winner(board)
if winning_player != 0: #we already have a winner
return winning_player
best = -player
for i,x in moves(player, board):
old, board[i] = board[i], x #update board
best_opponent = evaluate(-player, board)
board[i] = old #reset - avoids slow copy of array
if best_opponent == 0: #player can force a draw
best = 0
if best_opponent == player: #player can force a win
best = player
break
return best
print(evaluate(-1, [9] + [0]*8))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment