Minimax

講者: penguin123

日期: 2021/11/15

大綱

  • Minimax介紹
  • Minimax井字遊戲應用
  • 程式範例參考

Minimax介紹

算法是一個零總和算法,即一方要在可選的選項中選擇將其優勢最大化的選擇,另一方則選擇令對手優勢最小化的方法

X: +1

O: -1

X: +1

O: -1

X's turn(MAX)

Minimax

井字遊戲

X: +1

O: -1

X's turn(MAX)

Minimax

井字遊戲

X: +1

O: -1

X's turn(MAX)

Minimax

井字遊戲

X: +1

O: -1

X's turn(MAX)

Minimax

井字遊戲

X: +1

O: -1

X's turn(MAX)

Minimax

井字遊戲

程式範例參考

global firstComputerMove
firstComputerMove = True

player = 'O'
bot = 'X'

board = {1: ' ', 2: ' ', 3: ' ',
         4: ' ', 5: ' ', 6: ' ',
         7: ' ', 8: ' ', 9: ' '}

def printBoard(board):
    print(board[1] + '|' + board[2] + '|' + board[3])
    print('-+-+-')
    print(board[4] + '|' + board[5] + '|' + board[6])
    print('-+-+-')
    print(board[7] + '|' + board[8] + '|' + board[9])
    print("\n")


def spaceIsFree(position):      
    if board[position] == ' ':
        return True
    else:
        return False


def insertLetter(letter, position):     
    if spaceIsFree(position):
        board[position] = letter
        printBoard(board)
        if (checkDraw()):
            print("Draw!")
            exit()
        if checkForWin():
            if letter == 'X':
                print("X wins!")
                exit()
            else:
                print("O wins!")
                exit()
        return
    else:
        print("Can't insert there!")
        position = int(input("Please enter new position:  "))
        insertLetter(letter, position)
        return


def checkForWin():
    if (board[1] == board[2] and board[1] == board[3] and board[1] != ' '):
        return True
    elif (board[4] == board[5] and board[4] == board[6] and board[4] != ' '):
        return True
    elif (board[7] == board[8] and board[7] == board[9] and board[7] != ' '):
        return True
    elif (board[1] == board[4] and board[1] == board[7] and board[1] != ' '):
        return True
    elif (board[2] == board[5] and board[2] == board[8] and board[2] != ' '):
        return True
    elif (board[3] == board[6] and board[3] == board[9] and board[3] != ' '):
        return True
    elif (board[1] == board[5] and board[1] == board[9] and board[1] != ' '):
        return True
    elif (board[7] == board[5] and board[7] == board[3] and board[7] != ' '):
        return True
    else:
        return False


def checkWhichMarkWon(mark):
    if board[1] == board[2] and board[1] == board[3] and board[1] == mark:
        return True
    elif (board[4] == board[5] and board[4] == board[6] and board[4] == mark):
        return True
    elif (board[7] == board[8] and board[7] == board[9] and board[7] == mark):
        return True
    elif (board[1] == board[4] and board[1] == board[7] and board[1] == mark):
        return True
    elif (board[2] == board[5] and board[2] == board[8] and board[2] == mark):
        return True
    elif (board[3] == board[6] and board[3] == board[9] and board[3] == mark):
        return True
    elif (board[1] == board[5] and board[1] == board[9] and board[1] == mark):
        return True
    elif (board[7] == board[5] and board[7] == board[3] and board[7] == mark):
        return True
    else:
        return False


def checkDraw():
    for key in board.keys():
        if (board[key] == ' '):
            return False
    return True

def playerMove():
    position = int(input("Enter the position for 'O':  "))
    insertLetter(player, position)
    return


def botMove():
    bestScore = -10000      
    bestMove = 0        #只是初始化 值可以隨便設
    for key in board.keys():
        if (board[key] == ' '):
            board[key] = bot
            score = minimax(board, 0, False)
            board[key] = ' '    #這裡只計算bestmove, score 因此不填入X
            if (score > bestScore):
                bestScore = score
                bestMove = key

    insertLetter(bot, bestMove)
    return


def minimax(board, depth, isMaximizing):    #在圈差遊戲用不到depth因為只有九個位置 但在更複雜的棋盤遊戲中會用到 
    if (checkWhichMarkWon(bot)):
        return 1
    elif (checkWhichMarkWon(player)):
        return -1
    elif (checkDraw()):
        return 0

    if (isMaximizing):
        bestScore = -10000
        for key in board.keys():
            if (board[key] == ' '):
                board[key] = bot
                score = minimax(board, depth, False)
                board[key] = ' '
                if (score > bestScore):
                    bestScore = score
        return bestScore

    else:
        bestScore = 10000
        for key in board.keys():
            if (board[key] == ' '):
                board[key] = player
                score = minimax(board, depth, True)
                board[key] = ' '
                if (score < bestScore):
                    bestScore = score
        return bestScore


printBoard(board)
print("Computer goes first! Good luck.")
print("Positions are as follow:")
print("1, 2, 3 ")
print("4, 5, 6 ")
print("7, 8, 9 ")
print("\n")

while not checkForWin():
    botMove()
    playerMove()
    
    

minimax

By penguin123

minimax

  • 121