簡體   English   中英

Python 中的井字游戲,帶 Minmax

[英]Tic Tac Toe in Python with Minmax

作為一個項目,我在 Python 中實現了 MinMax Tic Tac Toe AI。 我進一步實現了 Alpha - Beta Pruning 並提出了這個龐大的代碼。

代碼:-

class TicTacToe:
    game_state = [[' ',' ',' '],
                [' ',' ',' '],
                [' ',' ',' ']]
    players = ['X','O']
    def __init__(self,player_idx=0):
        if(player_idx>1 or player_idx<0):
        raise Exception("player index can only be 0 or 1")
        self.current_player=player_idx
    def check_current_state(self):
        # Check if draw
        draw_flag = 0
        for i in range(3):
            for j in range(3):
                if self.game_state[i][j] is ' ':
                    draw_flag = 1
        if draw_flag is 0:
            return None, "Draw"
        
        # Check horizontals
        if (self.game_state[0][0] == self.game_state[0][1] and self.game_state[0][1] == self.game_state[0][2] and self.game_state[0][0] is not ' '):
            return self.game_state[0][0], "Done"
        if (self.game_state[1][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[1][2] and self.game_state[1][0] is not ' '):
            return self.game_state[1][0], "Done"
        if (self.game_state[2][0] == self.game_state[2][1] and self.game_state[2][1] == self.game_state[2][2] and self.game_state[2][0] is not ' '):
            return self.game_state[2][0], "Done"
        
        # Check verticals
        if (self.game_state[0][0] == self.game_state[1][0] and self.game_state[1][0] == self.game_state[2][0] and self.game_state[0][0] is not ' '):
            return self.game_state[0][0], "Done"
        if (self.game_state[0][1] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[2][1] and self.game_state[0][1] is not ' '):
            return self.game_state[0][1], "Done"
        if (self.game_state[0][2] == self.game_state[1][2] and self.game_state[1][2] == self.game_state[2][2] and self.game_state[0][2] is not ' '):
            return self.game_state[0][2], "Done"
        
        # Check diagonals
        if (self.game_state[0][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[2][2] and self.game_state[0][0] is not ' '):
            return self.game_state[1][1], "Done"
        if (self.game_state[2][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[0][2] and self.game_state[2][0] is not ' '):
            return self.game_state[1][1], "Done"
        
        return None, "Not Done"
    def evaluate(self):
        a,b=self.check_current_state()
        if(a != None and b == "Done" and a == 'X'):
        return 1
        elif(a != None and b == "Done" and a == 'O'):
        return -1
        elif(a == None and b == "Draw"):
        return 0
        else:
        return 6
    def MiniMax(self,depth,isMax):
        score=self.evaluate()
        if(score==1):
        return score;
        if(score==-1):
        return score;
        if(score==0):
        return score
        if(isMax==True):
        best=-100
        for i in range(3):
            for j in range(3):
            if(self.game_state[i][j]==' '):
                self.game_state[i][j]='X'
                best=max(best,self.MiniMax(depth+1,False))
                self.game_state[i][j]=' '
        return best
        elif(isMax==False):
        best=100
        for i in range(3):
            for j in range(3):
            if(self.game_state[i][j]==' '):
                self.game_state[i][j]='O'
                best=min(best,self.MiniMax(depth+1,True))
                self.game_state[i][j]=' '
        return best
    
    def best_move(self):
        best=-100
        r=-1
        c=-1
        for i in range(3):
        for j in range(3):
            if(self.game_state[i][j]==' '):
            self.game_state[i][j]='X'
            move = self.MiniMax(0, False)
            self.game_state[i][j]=' '
            if(move>best):
                r=i
                c=j
                best=move
        return r,c
    def play_move(self, block_num):
        if self.game_state[int((block_num-1)/3)][(block_num-1)%3] is ' ' and self.current_player==1:
            self.game_state[int((block_num-1)/3)][(block_num-1)%3] = self.players[self.current_player]
            self.current_player=1-self.current_player
        elif self.current_player==0:
            i,j=self.best_move()
            self.game_state[i][j] = self.players[self.current_player]
            self.current_player=1-self.current_player
        elif self.game_state[int((block_num-1)/3)][(block_num-1)%3] != ' ' and self.current_player==1:
            block_num = int(input("Block is not empty, ya blockhead! Choose again: "))
            self.play_move(block_num)
        
    def print_board(self):
        print('----------------')
        print('| ' + str(self.game_state[0][0]) + ' || ' + str(self.game_state[0][1]) + ' || ' + str(self.game_state[0][2]) + ' |')
        print('----------------')
        print('| ' + str(self.game_state[1][0]) + ' || ' + str(self.game_state[1][1]) + ' || ' + str(self.game_state[1][2]) + ' |')
        print('----------------')
        print('| ' + str(self.game_state[2][0]) + ' || ' + str(self.game_state[2][1]) + ' || ' + str(self.game_state[2][2]) + ' |')
        print('----------------')

    def play(self):
        current_state = "Not Done"
        print("New Game!")
        self.print_board()
        winner = None
        while current_state == "Not Done":
            if(self.current_player==1):
            block_choice = int(input(str(self.players[self.current_player]) + "s Turn! Choose where to place (1 to 9): "))
            self.play_move(block_choice)
            elif(self.current_player==0):
            self.play_move(1)
            self.print_board()
            winner, current_state = self.check_current_state()
            if winner is not None:
                print(str(winner) + " won!")

            if current_state is "Draw":
                print("Draw!")

    game=TicTacToe()
    game.play()

我不知道為什么,但這段代碼給出了問題。

請幫幫我。

你有縮進問題我已經為你解決了:

class TicTacToe:
    game_state = [[' ',' ',' '],
                [' ',' ',' '],
                [' ',' ',' ']]
    players = ['X','O']
    def __init__(self,player_idx=0):
        if(player_idx>1 or player_idx<0):
            raise Exception("player index can only be 0 or 1")
        self.current_player=player_idx
    def check_current_state(self):
        # Check if draw
        draw_flag = 0
        for i in range(3):
            for j in range(3):
                if self.game_state[i][j] is ' ':
                    draw_flag = 1
        if draw_flag is 0:
            return None, "Draw"
        
        # Check horizontals
        if (self.game_state[0][0] == self.game_state[0][1] and self.game_state[0][1] == self.game_state[0][2] and self.game_state[0][0] is not ' '):
            return self.game_state[0][0], "Done"
        if (self.game_state[1][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[1][2] and self.game_state[1][0] is not ' '):
            return self.game_state[1][0], "Done"
        if (self.game_state[2][0] == self.game_state[2][1] and self.game_state[2][1] == self.game_state[2][2] and self.game_state[2][0] is not ' '):
            return self.game_state[2][0], "Done"
        
        # Check verticals
        if (self.game_state[0][0] == self.game_state[1][0] and self.game_state[1][0] == self.game_state[2][0] and self.game_state[0][0] is not ' '):
            return self.game_state[0][0], "Done"
        if (self.game_state[0][1] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[2][1] and self.game_state[0][1] is not ' '):
            return self.game_state[0][1], "Done"
        if (self.game_state[0][2] == self.game_state[1][2] and self.game_state[1][2] == self.game_state[2][2] and self.game_state[0][2] is not ' '):
            return self.game_state[0][2], "Done"
        
        # Check diagonals
        if (self.game_state[0][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[2][2] and self.game_state[0][0] is not ' '):
            return self.game_state[1][1], "Done"
        if (self.game_state[2][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[0][2] and self.game_state[2][0] is not ' '):
            return self.game_state[1][1], "Done"
        
        return None, "Not Done"
    def evaluate(self):
        a,b=self.check_current_state()
        if(a != None and b == "Done" and a == 'X'):
            return 1
        elif(a != None and b == "Done" and a == 'O'):
            return -1
        elif(a == None and b == "Draw"):
            return 0
        else:
            return 6
    def MiniMax(self,depth,isMax):
        score=self.evaluate()
        if(score==1):
            return score;
        if(score==-1):
            return score;
        if(score==0):
            return score
        if(isMax==True):
            best=-100
            for i in range(3):
                for j in range(3):
                    if(self.game_state[i][j]==' '):
                        self.game_state[i][j]='X'
                        best=max(best,self.MiniMax(depth+1,False))
                        self.game_state[i][j]=' '
            return best
        elif(isMax==False):
            best=100
            for i in range(3):
                for j in range(3):
                    if(self.game_state[i][j]==' '):
                        self.game_state[i][j]='O'
                        best=min(best,self.MiniMax(depth+1,True))
                        self.game_state[i][j]=' '
            return best
    
    def best_move(self):
        best=-100
        r=-1
        c=-1
        for i in range(3):
            for j in range(3):
                if(self.game_state[i][j]==' '):
                    self.game_state[i][j]='X'
                    move = self.MiniMax(0, False)
                    self.game_state[i][j]=' '
                    if(move>best):
                        r=i
                        c=j
                        best=move
        return r,c
    def play_move(self, block_num):
        if self.game_state[int((block_num-1)/3)][(block_num-1)%3] is ' ' and self.current_player==1:
            self.game_state[int((block_num-1)/3)][(block_num-1)%3] = self.players[self.current_player]
            self.current_player=1-self.current_player
        elif self.current_player==0:
            i,j=self.best_move()
            self.game_state[i][j] = self.players[self.current_player]
            self.current_player=1-self.current_player
        elif self.game_state[int((block_num-1)/3)][(block_num-1)%3] != ' ' and self.current_player==1:
            block_num = int(input("Block is not empty, ya blockhead! Choose again: "))
            self.play_move(block_num)
        
    def print_board(self):
        print('----------------')
        print('| ' + str(self.game_state[0][0]) + ' || ' + str(self.game_state[0][1]) + ' || ' + str(self.game_state[0][2]) + ' |')
        print('----------------')
        print('| ' + str(self.game_state[1][0]) + ' || ' + str(self.game_state[1][1]) + ' || ' + str(self.game_state[1][2]) + ' |')
        print('----------------')
        print('| ' + str(self.game_state[2][0]) + ' || ' + str(self.game_state[2][1]) + ' || ' + str(self.game_state[2][2]) + ' |')
        print('----------------')

    def play(self):
        current_state = "Not Done"
        print("New Game!")
        self.print_board()
        winner = None
        while current_state == "Not Done":
            if(self.current_player==1):
                block_choice = int(input(str(self.players[self.current_player]) + "s Turn! Choose where to place (1 to 9): "))
                self.play_move(block_choice)
            elif(self.current_player==0):
                self.play_move(1)
                self.print_board()
            winner, current_state = self.check_current_state()
            if winner is not None:
                print(str(winner) + " won!")

            if current_state is "Draw":
                print("Draw!")

game=TicTacToe()
game.play()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM