0% found this document useful (0 votes)
5 views3 pages

Minimax Algorithm for Othello AI

The document defines a Python class 'MyPlayer' that implements a minimax algorithm for playing a board game, likely Othello. It includes methods for validating moves, making moves, evaluating the board, and selecting the best move based on a scoring system that considers both position and mobility. The class also prioritizes moves by corners and edges to enhance strategic gameplay.

Uploaded by

pes240605
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views3 pages

Minimax Algorithm for Othello AI

The document defines a Python class 'MyPlayer' that implements a minimax algorithm for playing a board game, likely Othello. It includes methods for validating moves, making moves, evaluating the board, and selecting the best move based on a scoring system that considers both position and mobility. The class also prioritizes moves by corners and edges to enhance strategic gameplay.

Uploaded by

pes240605
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

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

You might also like