From 5c69552126601a2368a9d4306a63ff8b578aaa81 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 19 Sep 2018 11:59:07 +0545 Subject: [PATCH 1/3] Fixed alpha beta pruning bug --- Engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine.py b/Engine.py index 7bfb8fc..ff48bef 100644 --- a/Engine.py +++ b/Engine.py @@ -54,7 +54,7 @@ def minmax(self, is_max=True, depth=0, alpha=-INF, beta=INF): # ab pruning if alpha >= beta: - return beta + break return beta @@ -77,7 +77,7 @@ def minmax(self, is_max=True, depth=0, alpha=-INF, beta=INF): # ab pruning if alpha >= beta: - return alpha + break return alpha From e263f8658a575b8e3020f0e67888b8739c71fff7 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 19 Sep 2018 20:41:53 +0545 Subject: [PATCH 2/3] Fixed alpha beta algorithm bugs and configurations for who plays first --- Engine.py | 8 +++++--- ui.py | 45 ++++++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Engine.py b/Engine.py index ff48bef..d4e8919 100644 --- a/Engine.py +++ b/Engine.py @@ -21,7 +21,7 @@ def evaluate(self, depth=0): """ winner = self.board.winner if not winner: - return 3 * self.board.movable_tigers() + 7 * self.board.deadGoats - depth + return 30 * self.board.movable_tigers() + 70 * self.board.deadGoats - depth if winner == Board.Player.G: return -Engine.INF @@ -37,6 +37,7 @@ def minmax(self, is_max=True, depth=0, alpha=-INF, beta=INF): # find the minimum attainable value for the minimizer if not is_max: + value = self.INF for move in self.board.generate_move_list(): # first make the move self.board.make_move(move) @@ -56,10 +57,11 @@ def minmax(self, is_max=True, depth=0, alpha=-INF, beta=INF): if alpha >= beta: break - return beta + return value # find the maximum attainable value for the maximizer else: + value = -self.INF for move in self.board.generate_move_list(): # first make the move self.board.make_move(move) @@ -79,7 +81,7 @@ def minmax(self, is_max=True, depth=0, alpha=-INF, beta=INF): if alpha >= beta: break - return alpha + return value def best_tiger_move(self): self.minmax() diff --git a/ui.py b/ui.py index bef0c0f..9a80161 100644 --- a/ui.py +++ b/ui.py @@ -17,7 +17,6 @@ class UIGame(object): _idx_to_col = {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E'} def __init__(self, canvas, statustext): - super(UIGame, self).__init__() # self.board = Board('1GG1G/1GGGT/1GGGG/GGTGG/GTGTG t g0 c3 mA3') self.board = Board() @@ -36,7 +35,7 @@ def __init__(self, canvas, statustext): self.game = None self.win = '' - self.ai_turn = False + self.ai_turn = True self.config = configparser.SafeConfigParser(defaults={ 'sheepcolor': 'gray', @@ -215,6 +214,7 @@ def check_win(self): # self.game = None self.statustext.set('Tigers win!') self.win = 'tigers' + print(self.win) return elif self.board.winner == Board.Player.T: @@ -222,35 +222,37 @@ def check_win(self): # self.game = None self.statustext.set('Goats win!') self.win = 'goats' + print(self.win) return def new(self): - # self.config = configparser.SafeConfigParser() - # self.config.read(os.path.expanduser('uiconf')) - - # if self.config.has_option('game', 'ai'): - # if self.config.get('game', 'ai').lower() == 'sheep': - # cmdline.append('-s') - # elif self.config.get('game', 'ai').lower() == 'tiger': - # cmdline.append('-t') - # else: - # cmdline.append('-s') - - # if self.config.has_option('game', 'aistrength'): - # cmdline.append(self.config.get('game', 'aistrength')) - # else: - # cmdline.append('3') + self.config = configparser.ConfigParser() + self.config.read(os.path.expanduser('uiconf')) + + if self.config.has_option('game', 'ai'): + if self.config.get('game', 'ai').lower() == 'sheep': + self.ai_turn = True + elif self.config.get('game', 'ai').lower() == 'tiger': + self.ai_turn = False + print('tiger') + else: + pass + + if self.config.has_option('game', 'aistrength'): + aistrength = self.config.get('game', 'aistrength') + else: + aistrength = 6 # self.win = '' - self.init_ai() + self.init_ai(int(aistrength)) # self.engine.make_best_move() # self.check_win() self.draw() - def init_ai(self): + def init_ai(self, aistrength): self.ai_vs_ai = False self.board = Board() - self.engine = Engine(self.board, depth=5) + self.engine = Engine(self.board, depth=aistrength) def make_ai_move(self, ev=None): move = self.engine.get_best_move() @@ -258,7 +260,8 @@ def make_ai_move(self, ev=None): def configure(): - config = configparser.SafeConfigParser() + config = configparser.ConfigParser() + print('haha') config.add_section('game') config.read(os.path.expanduser('uiconf')) From 4bbf337650cbc41ebaa2b8c044e5c7625f23ae46 Mon Sep 17 00:00:00 2001 From: Suraj Date: Sun, 23 Sep 2018 16:22:35 +0545 Subject: [PATCH 3/3] Fixed engine error --- Board.py | 1 - Engine.py | 23 ++++++++++++++--------- ui.py | 22 ++++++++++------------ 3 files changed, 24 insertions(+), 22 deletions(-) mode change 100644 => 100755 ui.py diff --git a/Board.py b/Board.py index 0ce4a0a..0fc4fbf 100644 --- a/Board.py +++ b/Board.py @@ -395,7 +395,6 @@ def movable_tigers(self): """ Returns the number of movable tigers on the board """ - return sum(int(self._movable(t)) for t in self.tigerPos) def generate_move_list(self, rdm=True): diff --git a/Engine.py b/Engine.py index d4e8919..4df81ff 100644 --- a/Engine.py +++ b/Engine.py @@ -43,17 +43,20 @@ def minmax(self, is_max=True, depth=0, alpha=-INF, beta=INF): self.board.make_move(move) # go deeper in the search tree recursively - value = self.minmax(True, depth + 1, alpha, beta) + value_t = self.minmax(True, depth + 1, alpha, beta) - if value <= beta: - beta = value + beta = min(beta, value_t) + + + if value_t <= value: + value = value_t + beta = min(beta, value) if depth == 0: self.best_move = move # then revert the move self.board.revert_move(move) - # ab pruning if alpha >= beta: break @@ -67,18 +70,20 @@ def minmax(self, is_max=True, depth=0, alpha=-INF, beta=INF): self.board.make_move(move) # go deeper in the search tree recursively - value = self.minmax(False, depth + 1, alpha, beta) + value_t = self.minmax(False, depth + 1, alpha, beta) - if value >= alpha: - alpha = value + if value_t >= value: + value = value_t + alpha = max(alpha, value) if depth == 0: self.best_move = move + + # then revert the move self.board.revert_move(move) - # ab pruning - if alpha >= beta: + if alpha > beta: break return value diff --git a/ui.py b/ui.py old mode 100644 new mode 100755 index 9a80161..a2814e3 --- a/ui.py +++ b/ui.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import os import configparser import itertools @@ -27,7 +29,7 @@ def __init__(self, canvas, statustext): self.from_idx = None self.tiger_radius = 7 - self.sheep_radius = 5 + self.goat_radius = 5 self.board_grid_x = [10, 60, 110, 160, 210] self.board_grid_y = [10, 60, 110, 160, 210] @@ -37,12 +39,12 @@ def __init__(self, canvas, statustext): self.win = '' self.ai_turn = True - self.config = configparser.SafeConfigParser(defaults={ - 'sheepcolor': 'gray', + self.config = configparser.ConfigParser(defaults={ + 'goatcolor': 'gray', 'tigercolor': 'yellow' }) self.config.add_section('ui') - self.sheep_color = self.config.get('ui', 'sheepcolor') + self.goat_color = self.config.get('ui', 'goatcolor') self.tiger_color = self.config.get('ui', 'tigercolor') self.draw_board() @@ -191,7 +193,7 @@ def draw(self): self.make_ai_move() tr = self.tiger_radius - sr = self.sheep_radius + sr = self.goat_radius # display the tigers and goats on the ui board for entry, (y, x) in zip(Board._get_full_position(self.board.position.split()[0]), @@ -205,7 +207,7 @@ def draw(self): elif entry == "G": self.cids.append(self.canvas.create_oval(x - sr, y - sr, x + sr, y + sr, - fill=self.sheep_color)) + fill=self.goat_color)) def check_win(self): # read the current board position @@ -214,15 +216,13 @@ def check_win(self): # self.game = None self.statustext.set('Tigers win!') self.win = 'tigers' - print(self.win) return - elif self.board.winner == Board.Player.T: + elif self.board.winner == Board.Player.G: # self.game.wait() # self.game = None self.statustext.set('Goats win!') self.win = 'goats' - print(self.win) return def new(self): @@ -230,11 +230,10 @@ def new(self): self.config.read(os.path.expanduser('uiconf')) if self.config.has_option('game', 'ai'): - if self.config.get('game', 'ai').lower() == 'sheep': + if self.config.get('game', 'ai').lower() == 'goat': self.ai_turn = True elif self.config.get('game', 'ai').lower() == 'tiger': self.ai_turn = False - print('tiger') else: pass @@ -261,7 +260,6 @@ def make_ai_move(self, ev=None): def configure(): config = configparser.ConfigParser() - print('haha') config.add_section('game') config.read(os.path.expanduser('uiconf'))