Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12141

How do I fix this minimax algorithm for Mancala?

$
0
0

As a challenge I've decided to try and code a minimax algorithm without using the internet. I haven't even written the AI class, but I have built a Node class and a search ahead method. The problem I'm running into is that all of the values I'm getting are poorly weighed towards the first player, which makes no sense.

I've even tried playing through some of the branches myself on a physical board to make sure I'm not going crazy, and a lot of the values just aren't matching up. I'd love to know what I'm screwing up, this has been driving me crazy!

When I included a print statement in my search ahead that prints the values of all successive moves, and then input a depth greater than 3, for some reason all of the returned values are negative.

Here's some example values when I check the node1 with a depth of 3:

pocket 8: [-1, -1, -1, -1, -1]pocket 9: [0, -1, -1, -1, -1]pocket 10: [-1, -1, -2, -2, -2]pocket 11: [-1, -1, -2, -2, -2]pocket 12: [-8, -1, -2, -2, -2]pocket 13: [-1, -3, -2, -2, -2]pocket 1: [-1, -1, -2, -2, -8, -3].

When I actually play the game, the resulting values are different than what search ahead seems to think they are(where the values represent the difference between the bottom players score and the top players score)

import copyimport randomimport numpyclass Board():    def __init__(self,turn,position,pockets,game_state):        self.turn=turn        self.position=position        self.pockets=pockets        self.game_state=game_state    def make_pieces(self):        for i in range(1,7):            self.pockets[f"pocket_{i}"]=4        for i in range(8,14):            self.pockets[f"pocket_{i}"]=4        self.pockets["pocket_7"]=0        self.pockets["pocket_14"]=0    def move_pieces(self):        starting_position=self.position        current_position=self.position        pieces_in_pocket=self.pockets[f"pocket_{self.position}"]        pieces_dropped=0        move_again="False"        valid_move="True"        board_values=[valid_move,move_again]        if starting_position==7 or starting_position==14:            valid_move="False"            move_again="False"            board_values=[valid_move,move_again]            return board_values        elif self.turn=="top" and starting_position in range(1,8):            valid_move="False"            move_again="False"            board_values=[valid_move,move_again]            return board_values        elif self.turn=="bottom" and starting_position in range(8,15):            valid_move="False"            move_again="True"            board_values=[valid_move,move_again]            return board_values        else:            valid_move="True"            if self.pockets[f"pocket_{self.position}"]==0:                valid_move="False"                final_move=current_position                move_again="False"                board_values=[valid_move,move_again]                return board_values            else:                for i in range(0,pieces_in_pocket):                    if current_position==13 and self.turn=="bottom":                        current_position=0                    if current_position==6 and self.turn=="top":                        current_position=7                    if current_position==14 and self.turn=="top":                        current_position=0                    self.pockets[f"pocket_{current_position+1}"]+=1                    self.pockets[f"pocket_{starting_position}"]-=1                    pieces_in_pocket-=1                    pieces_dropped+=1                    current_position+=1                    final_move=current_position            if final_move==7 and self.turn=="bottom":                move_again="True"            elif final_move==14 and self.turn=="top":                move_again="True"            else:                move_again="False"            for i in range(1,7):                if final_move==i and self.pockets[f"pocket_{i}"]==1 and self.turn=="bottom":                    if self.pockets[f"pocket_{14-i}"]==0:                        self.pockets[f"pocket_7"]=self.pockets[f"pocket_7"]                    else:                        self.pockets["pocket_7"]=self.pockets["pocket_7"]+self.pockets[f"pocket_{14-i}"]                        self.pockets[f"pocket_{14-i}"]=0                        self.pockets[f"pocket_7"]=self.pockets[f"pocket_7"]+self.pockets[f"pocket_{i}"]                        self.pockets[f"pocket_{i}"]=0            for i in range(8,14):                if final_move==i and self.pockets[f"pocket_{i}"]==1 and self.turn=="top":                    if self.pockets[f"pocket_{14-i}"]==0:                        self.pockets[f"pocket_14"]=self.pockets[f"pocket_14"]                    else:                        self.pockets[f"pocket_14"]=self.pockets["pocket_14"]+self.pockets[f"pocket_{14-i}"]                        self.pockets[f"pocket_{14-i}"]=0                        self.pockets[f"pocket_14"]=self.pockets["pocket_14"]+self.pockets[f"pocket_{i}"]                        self.pockets[f"pocket_{i}"]=0            board_values=[valid_move,move_again]        return board_valuesclass Node():    def __init__(self,game_state,pocket,children,depth,values,parent):        self.game_state=game_state        self.pocket=pocket        self.children=children        self.depth=depth        self.values=values        self.parent=parent    def search_ahead(self):        if self.depth==1:            test_board=copy.deepcopy(self.game_state)            test_board.position=self.pocket            useful_list=test_board.move_pieces()            pocket_7=test_board.pockets["pocket_7"]            pocket_14=test_board.pockets["pocket_14"]            value=pocket_7-pocket_14            if useful_list[0]=="False" and self.parent==None:                return None            elif useful_list[0]=="False" and self.parent!=None:                return None            elif useful_list[0]=="True" and self.parent!=None:                self.parent.values.append(value)            elif useful_list[0]=="True" and self.parent==None:                self.values.append(value)        elif self.depth!=1:            test_board=copy.deepcopy(self.game_state)            test_board.position=self.pocket            useful_list=test_board.move_pieces()            if useful_list[0]=="False" and self.parent==None:                self.values="Invalid"                return None            elif useful_list[0]=="False" and self.parent!=None:                return None            if useful_list[1]=="True" and test_board.turn=="bottom":                test_board.turn="bottom"            elif useful_list[1]=="True" and test_board.turn=="top":                test_board.turn="top"            elif useful_list[1]=="False" and test_board.turn=="bottom":                test_board.turn="top"            elif useful_list[1]==False and test_board.turn=="top":                test_board.turn="bottom"            if test_board.turn=="bottom":                condition="max"                for i in range(1,7):                    self.children.append(Node(test_board,i,[],(self.depth-1),[],self))            elif test_board.turn=="top":                condition="min"                for i in range(8,14):                    self.children.append(Node(test_board,i,[],(self.depth-1),[],self))            for node in self.children:                node.search_ahead()            if condition=="max" and self.parent!=None:                x=max(self.values)                self.values=x                self.parent.values.append(x)            if condition=="min" and self.parent!=None:                x=min(self.values)                self.parent.values.append(x)            print(self.pocket)            print(self.values)game_board=Board("bottom",1,"","")game_board.pockets={"pocket_1":[],"pocket_2":[],"pocket_3":[],"pocket_4":[],"pocket_5":[],"pocket_6":[],"pocket_7":[],"pocket_8":[],"pocket_9":[],"pocket_10":[],"pocket_11":[],"pocket_12":[],"pocket_13":[],"pocket_14":[]}game_board.make_pieces()#Bottom pocket nodesnodep1=Node(game_board,1,[],7,[],None)nodep2=Node(game_board,2,[],1,[],None)nodep3=Node(game_board,3,[],1,[],None)nodep4=Node(game_board,4,[],1,[],None)nodep5=Node(game_board,5,[],1,[],None)nodep6=Node(game_board,6,[],1,[],None)#Top pocket nodesnodep8=Node(game_board,8,[],1,[],None)nodep9=Node(game_board,9,[],1,[],None)nodep10=Node(game_board,10,[],1,[],None)nodep11=Node(game_board,11,[],1,[],None)nodep12=Node(game_board,12,[],1,[],None)nodep13=Node(game_board,13,[],1,[],None)nodep1.search_ahead()

Viewing all articles
Browse latest Browse all 12141

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>