tutor profile

Response Time

98%

12213

Tutor Profile

Subjects

Database, Digital Marketing, Python, Networking

Python Project on Artificial Intelligence Alpha Beta pruning Algorithm

#!/usr/bin/python3

### CSCI-B 351 / COGS-Q 351 Fall 2021
### Framework code copyright 2020 B351/Q351 instruction team.
### Do not copy or redistribute this code without permission
### and do not share your solutions outside of this class.
### Doing so constitutes academic misconduct and copyright infringement.

import math
import random
from board import Board

class BasePlayer:
def __init__(self, max_depth):
self.max_depth = max_depth

##################
# TODO #
##################
# Assign integer scores to the three terminal states
# P2_WIN_SCORE < TIE_SCORE < P1_WIN_SCORE
# Access these with "self.TIE_SCORE", etc.
P1_WIN_SCORE = 100
P2_WIN_SCORE = -100
TIE_SCORE = 0
# Returns a heuristic for the board position
# Good positions for 0 pieces should be positive and
# good positions for 1 pieces should be negative
# for all boards, P2_WIN_SCORE < heuristic(b) < P1_WIN_SCORE
def heuristic(self, board):
'''
URL: https://www.researchgate.net/publication/261452468_Exploration_and_analysis_of_the_evolution_of_strategies_for_Mancala_variants
Help was taken from this url was used to understand relevant heuristics that can be used to reflect the "goodness" of the game.

score: Heuristic score.

Heuristics
H1: Keep as many seeds on the players own side
H2: To check how late into the game it is we will check
remaining moves possible from which to choose
H3: Maximise the amount of seeds in a players own store
'''
score = 0
p1_possible_moves = []
p2_possible_moves = []

if not board.game_over: # check if game is not over
H1 = sum(board.p1_pits) - sum(board.p2_pits)

for i in range(len(board.p1_pits)):
if board.p1_pits[i] != 0:
p1_possible_moves.append(board.p1_pits[i])

for i in range(len(board.p2_pits)):
if board.p2_pits[i] != 0:
p2_possible_moves.append(board.p2_pits[i])

H2 = len(p1_possible_moves) - len(p2_possible_moves)

H3 = board.p1_pot - board.p2_pot

score = 100 * ((1/3 * H1) + (1/3 * H2) + (1/3 * H3))

else: # otherwise if game is over
if board.winner == 0: # if player 1 wins the game
score = self.P1_WIN_SCORE
elif board.winner == 1: # if player 2 wins the game
score = self.P2_WIN_SCORE
else:
score = self.TIE_SCORE # if the game ends in a draw

return score

 

# You are not expected to implement anything here.
def findMove(self, trace):
raise NotImplementedError

class ManualPlayer(BasePlayer):
def __init__(self, max_depth=None):
BasePlayer.__init__(self, max_depth)

def findMove(self, trace):
board = Board(trace)
opts = " "
for c in range(6):
opts += " "+(str(c+1) if board.isValidMove(c) else ' ')+" "

while True:
if(board.turn == 0):
print("\n")
board.printSpaced()
print(opts)
pit = input("Pick a pit (P1 side): ")
else:
print("\n")
print(" " + opts[::-1])
board.printSpaced()
pit = input("Pick a pit (P2 side): ")
try: pit = int(pit) - 1
except ValueError: continue
if board.isValidMove(pit):
return pit

class RandomPlayer(BasePlayer):
def __init__(self, max_depth=None):
BasePlayer.__init__(self, max_depth)
self.random = random.Random(max_depth)
def findMove(self, trace):
board = Board(trace)
options = list(board.getAllValidMoves())
return self.random.choice(options)

Read More

class RemotePlayer(BasePlayer):
def __init__(self, max_depth=None):
BasePlayer.__init__(self, max_depth)
self.instructor_url = "http://silo.cs.indiana.edu:30005"
if self.max_depth > 8:
print("It refused to go that hard. Sorry.")
self.max_depth = 8
def findMove(self, trace):
import requests
r = requests.get(f'{self.instructor_url}/getmove/{self.max_depth},{trace}')
move = int(r.text)
return move

class PlayerMM(BasePlayer):
##################
# TODO #
##################
# performs minimax on board with depth.
# returns the best move and best score as a tuple
def minimax(self, board, depth):
# return null move and score for board's terminal state
# when game is over
if board.game_over == True:
move = 0
if board.winner == 0:
score = self.P1_WIN_SCORE
elif board.winner == 1:
score = self.P2_WIN_SCORE
else: # in case of tie
score = self.TIE_SCORE
return move, score

# return a null move and the heuristic value for board
# when non-end state and depth = 0
if depth == 0:
move = 0
score = self.heuristic(board)
return move, score

if board.turn == 0: # turn of maximising player
score = -math.inf
moves = board.getAllValidMoves()
for move in moves:
board = board.makeMove(move)
b_move, score = move, max(score, self.minimax(board, depth - 1))
board = board.undoMove()
return b_move, score
else: # turn of minimising player
score = math.inf
moves = board.getAllValidMoves()
for move in moves:
board = board.makeMove(move)
b_move, score = move, min(score, self.minimax(board, depth - 1))
board = board.undoMove()
return b_move, score

def findMove(self, trace):
board = Board(trace)
move, score = self.minimax(board, self.max_depth)
return move

class PlayerAB(BasePlayer):
##################
# TODO #
##################
# performs minimax with alpha-beta pruning on board with depth.
# alpha represents the score of max's current strategy
# beta represents the score of min's current strategy
# in a cutoff situation, return the score that resulted in the cutoff
# returns the best move and best score as a tuple
def alphaBeta(self, board, depth, alpha, beta):
# return null move and score for board's terminal state
# when game is over
if board.game_over:
move = 0
if board.winner == 0:
score = self.P1_WIN_SCORE
elif board.winner == 1:
score = self.P2_WIN_SCORE
else: # in case of tie
score = self.TIE_SCORE
return move, score

# return a null move and the heuristic value for board
# when non-end state and depth = 0
if depth == 0:
move = 0
score = self.heuristic(board)
return move, score

if board.turn == 0: # turn of maximising player
score = -math.inf
moves = board.getAllValidMoves()
for move in moves:
board = board.makeMove(move)
b_move, score = b_move, max(score, self.alphaBeta(board, depth - 1, alpha, beta))
if score >= beta:
break # beta cutoff
alpha = max(alpha, score)
return b_move, score

else:
score = math.inf
moves = board.getAllValidMoves()
for move in moves:
board = board.makeMove(move)
b_move, score = b_move, min(score, self.alphaBeta(board, depth - 1, alpha, beta))
if score <= alpha:
break # alpha cutoff
beta = min(beta, score)
return b_move, score

def findMove(self, trace):
board = Board(trace)
move, score = self.alphaBeta(board, self.max_depth, -math.inf, math.inf)
return move

class PlayerDP(PlayerAB):
''' A version of PlayerAB that implements dynamic programming
to cache values for its heuristic function, improving performance. '''
def __init__(self, max_depth):
PlayerAB.__init__(self, max_depth)
self.resolved = {}

##################
# TODO #
##################
# if a saved heuristic value exists in self.resolved for board.state, returns that value
# otherwise, uses BasePlayer.heuristic to get a heuristic value and saves it under board.state
def heuristic(self, board: Board):
if board.state in self.resolved.keys():
return self.resolved.get(str(board.state))
else:
score = BasePlayer.heuristic(board)
self.resolved{str(board.state)} = score
return score

class PlayerBonus(BasePlayer):
''' This class is here to give you space to experiment for your ultimate Mancala AI,
your one and only PlayerBonus. This is only used for the extra credit tournament. '''
def findMove(self, trace):
raise NotImplementedError

#######################################################
###########Example Subclass for Testing
#######################################################

# This will inherit your findMove from above, but will override the heuristic function with
# a new one; you can swap out the type of player by changing X in "class TestPlayer(X):"
class TestPlayer(BasePlayer):
# define your new heuristic here
def heuristic(self):
pass

 

Get Assignment Help from Me

TOP
Order Notification

[variable_1] from [variable_2] has just ordered [variable_3] Assignment [amount] minutes ago.