import math
class MyPlayer:
'''Using minimax.'''
def __init__(self, my_color, opponent_color):
self.my_color, self.opponent_color = my_color, opponent_color
[Link] = [
(0, 1), (1, 0), (0, -1), (-1, 0), # Horizontal and vertical directions
(1, 1), (1, -1), (-1, 1), (-1, -1) # Diagonal directions
]
# Scoring weights for board positions
[Link] = [
[100, -20, 10, 5, 5, 10, -20, 100],
[-20, -50, -2, -2, -2, -2, -50, -20],
[ 10, -2, 5, 1, 1, 5, -2, 10],
[ 5, -2, 1, 0, 0, 1, -2, 5],
[ 5, -2, 1, 0, 0, 1, -2, 5],
[ 10, -2, 5, 1, 1, 5, -2, 10],
[-20, -50, -2, -2, -2, -2, -50, -20],
[100, -20, 10, 5, 5, 10, -20, 100]
]
def in_bounds(self, row, col):
return 0 <= row < 8 and 0 <= col < 8
def is_valid_move(self, board, row, col):
if board[row][col] != -1:
return False
for dr, dc in [Link]:
r, c = row + dr, col + dc
found_opponent = False
while self.in_bounds(r, c) and board[r][c] == self.opponent_color:
found_opponent = True
r += dr
c += dc
if found_opponent and self.in_bounds(r, c) and board[r][c] ==
self.my_color:
return True
return False
def get_valid_moves(self, board):
return [(row, col) for row in range(8) for col in range(8) if
self.is_valid_move(board, row, col)]
def make_move(self, board, row, col):
board[row][col] = self.my_color
for dr, dc in [Link]:
r, c = row + dr, col + dc
pieces_to_flip = []
while self.in_bounds(r, c) and board[r][c] == self.opponent_color:
pieces_to_flip.append((r, c))
r += dr
c += dc
if self.in_bounds(r, c) and board[r][c] == self.opponent_color:
for rr, cc in pieces_to_flip:
board[rr][cc] = self.my_color
def evaluate_board(self, board, ):
score = 0
# Weighted board score
for row in range(8):
for col in range(8):
if board[row][col] == self.my_color:
score += [Link][row][col]
elif board[row][col] == self.opponent_color:
score -= [Link][row][col]
# Mobility: Encourage moves that limit opponent's options
player_moves = len(self.get_valid_moves(board))
opponent_moves = len(self.get_valid_moves(board))
mobility_score = player_moves - opponent_moves
# Combine scores with appropriate weights
return score + (10 * mobility_score)
def minimax(self, board, depth, alpha, beta, maximizing, moves=[]):
moves = self.get_valid_moves(board) if not moves else moves
if depth == 0 or not moves:
return self.evaluate_board(board), None
best_move = None
if maximizing:
max_eval = -[Link]
for move in moves:
new_board = [row[:] for row in board]
self.make_move(new_board, move[0], move[1])
eval, _ = [Link](new_board, depth - 1, alpha, beta, False)
if eval > max_eval:
max_eval = eval
best_move = move
alpha = max(alpha, eval)
if beta <= alpha:
break
return max_eval, best_move
else:
min_eval = [Link]
for move in moves:
new_board = [row[:] for row in board]
self.make_move(new_board, move[0], move[1])
eval, _ = [Link](new_board, depth - 1, alpha, beta, True)
if eval < min_eval:
min_eval = eval
best_move = move
beta = min(beta, eval)
if beta <= alpha:
break
return min_eval, best_move
def prioritize_moves(self, moves):
corner_moves = []
edge_moves = []
other_moves = []
for move in moves:
row, col = move
if (row, col) in [(0, 0), (0, 7), (7, 0), (7, 7)]: # Corners
corner_moves.append(move)
elif row in [0, 7] or col in [0, 7]: # Edges
edge_moves.append(move)
else:
other_moves.append(move)
return corner_moves + edge_moves + other_moves
def select_move(self, board):
valid_moves = self.get_valid_moves(board)
prioritized_moves = self.prioritize_moves(valid_moves)
_, best_move = [Link](board, depth=3, alpha=-[Link], beta=[Link],
maximizing=True, moves=prioritized_moves)
return best_move