Python游戏编程(五)Tic Tac Toe

Hazel ·
更新时间:2024-11-01
· 503 次阅读

Tic Tac Toe就是我们熟悉的井字棋游戏。我们将通过这个游戏,设计出来第一个人工智能(artificial intelligence, AI)程序,它可以对玩家的落子智能地作出相应。当然井字棋游戏地AI并不复杂,只是简单地几行代码而已。

这个游戏的AI可以概括如下:

首先,判断是否有能够让计算机获胜的落子位置。如果是,在那里落子;否则,执行步骤2. 判断受否有能够让玩家失败的落子位置。如果是,在那里落子,以便堵住玩家;否则,执行步骤3. 判断是否还有角(格子1、3、7或者9)为空。如果有,在此处落子;如果没有角为空,那么执行步骤4. 判断是否中心(格子5)为空。如果有,在此处落子;否则,执行步骤5。 在任意一个边(格子2、3、6或者8)落子。没有其他步骤了,因为如果执行到第5步,边是仅剩的空地了。

该算法在getComputerMove()函数以及getComputerMove()所调用的其他函数中实现。

这里我们用一个简单的数据表示游戏版,也就是一系列的文本。

(一)导入模块


 

#Tic-Tac-Toe
import random
(二)drawBoard(board):

我们将通过一个函数实现打印游戏棋盘。将board列表传递给drawBoard()函数,根据board列表中的元素进行打印。

#打印棋盘
def drawBoard(board):
    #This function prints out the board that it was passed.
    #"board" is a list of 10 strings representing the board (ignore index 0)
    print(board[7]+'|'+board[8]+'|'+board[9])
    print('-+-+-')
    print(board[4]+'|'+board[5]+'|'+board[6])
    print('-+-+-')
    print(board[1]+'|'+board[2]+'|'+board[3])
    print('-+-+-')
(三)inputPlayerLetter():
#让玩家来选择X或者是O
def inputPlayerLetter():
    #Let the player enter which letter they want to be.
    #Return a list with the player's letter as the first item and the computer's letter as the secend.
    letter = ' '
    while not (letter == 'X' or letter == 'O'):
        print('Do you want to be X or O ?')
        letter = input().upper()
        #The first element in the list is the player 's letter; the secend is the computer's letter.
        if letter == 'X':
            return ['X', 'O']
        else:
            return ['O', 'X']
(四)whoGoesFirst():
#决定谁先走
def whoGoesFirst():
    #Randomly choose which player goes first.
    if random.randint(0, 2) == 0:
        return 'computer'
    else:
        return 'player'
(五)makeMove(board, letter, move):
#在游戏版上放置一个标记
def makeMove(board, letter, move):
    board[move] = letter
列表的引用

所谓列表引用,简单理解就是对于列表来说,赋值符号(=)不是代表复制,而是代表对列表的引用。

>>> x = [1, 2, 3, 4] >>> y = x >>> y.append(5) >>> y [1, 2, 3, 4, 5] >>> x [1, 2, 3, 4, 5] (六)isWinner(bo,le):
#判断玩家是否获胜
def isWinner(bo,le):
    return ((bo[7] == le and bo[8] == le and bo[9] == le) or # across the top
    (bo[4] == le and bo[5] == le and bo[6] == le) or # across the middle
    (bo[1] == le and bo[2] == le and bo[3] == le) or # across the bottom
    (bo[7] == le and bo[4] == le and bo[1] == le) or # down the left side
    (bo[8] == le and bo[5] == le and bo[2] == le) or # down the middle
    (bo[9] == le and bo[6] == le and bo[3] == le) or # down the right side
    (bo[7] == le and bo[5] == le and bo[3] == le) or # diagonal
    (bo[9] == le and bo[5] == le and bo[1] == le)) # diagonal
(七)getBoardCopy(board):
#复制游戏版的数据
def getBoardCopy(board):
    #Make a copy of the board list and return it.
    boardCopy = []
    for i in board:
        boardCopy.append(i)
    return boardCopy
(八)isSpaceFree(board, move):
#判断游戏板上的格子是否为空
def isSpaceFree(board, move):
    #Return True if the passed move is free on the passed board.
    return board[move] == ' '
(九)getPlayerMove(board):
#让玩家输入落子的格子的编号
def getPlayerMove(board):
    #Let the player enter their move.
    move = ' '
    while move not in '1 2 3 4 5 6 7 8 9'.split() or not isSpaceFree(board, int(move)):
        print('What is your next move ? (1-9)')
        move = input()
    return int(move)
短路求值

短路(short-circuiting)在这里表示由于关键字or左边部分为True,Python解释器就知道整个表达式的计算结果为True。

>>> def ReturnTrue(): print('ReturnTrue() was called') return True >>> def ReturnFalse(): print('ReturnFalse() was called') return False >>> ReturnTrue() ReturnTrue() was called True >>> ReturnFalse() ReturnFalse() was called False >>> ReturnFalse() or ReturnTrue() ReturnFalse() was called ReturnTrue() was called True >>> ReturnTrue() or ReturnFalse() ReturnTrue() was called True (十)chooseRandomMoveFromList(board, moveList):
#从落子列表选择一个落子
def chooseRandomMoveFromList(board, moveList):
    #Returns a valid move from the passed list on the passed board.
    #Returns  None if there in no valid move.
    possibleMoves = []
    for i in moveList:
        if isSpaceFree(board, i):
            possibleMoves.append(i)
    if len(possibleMoves) != 0:
        return random.choice(possibleMoves)
    else:
        return None
(十一)getComputerMove(board, computerLetter):
def getComputerMove(board, computerLetter):
    #Given a board and the computer 's letter, determine where to move and return that move.
    if computerLetter == 'X':
        playerLetter = 'O'
    else:
        playerLetter = 'X'
    #Here is the algorithm for our Tic-Tac-Toe AI:
    #First, check if we can win in the next move.
    for i in range(0, 10):
        boardCopy = getBoardCopy(board)
        if isSpaceFree(boardCopy, i):
            makeMove(boardCopy, computerLetter, i)
            if isWinner(boardCopy, computerLetter):
                return i
    #Check if the player could win on their next move and blockthem.
    for i in range(0, 10):
        boardCopy = getBoardCopy(board)
        if isSpaceFree(boardCopy, i):
            makeMove(boardCopy, playerLetter, i)
            if isWinner(boardCopy, playerLetter):
                return i
    #Try to take one of the corners, if they are free.
    move = chooseRandomMoveFromList(board, [1, 3, 7, 9])
    if move != None:
        return move
    #Try to take the center, if it is free.
    if isSpaceFree(board, 5):
        return 5
    #Move on the sides.
    return chooseRandomMoveFromList(board, [2, 4, 6, 8])
(十二)isBoardFull(board):
def isBoardFull(board):
    #Return True if every space on the board has taken. Otherwise, return False
    for i in range(1, 10):
        if isSpaceFree(board, i):
            return False
    return True
(十三)游戏循环
print('Welcome to Tic-Tac-Toe!')
while True:
    #Reset the board.
    theBoard = [' '] * 10
    playerLetter,computerLetter = inputPlayerLetter()
    turn = whoGoesFirst()
    print('The '+turn+' will go first.')
    gameIsplaying = True
    while gameIsplaying:
        if turn == 'player':
            #Player's turn
            drawBoard(theBoard)
            move = getPlayerMove(theBoard)
            makeMove(theBoard, playerLetter, move)
            print(theBoard)
            if isWinner(theBoard,playerLetter):
                drawBoard(theBoard)
                print('Hooray, You have won the game!')
                gameIsplaying = False
            else:
                if isBoardFull(theBoard):
                    drawBoard(theBoard)
                    print('The game is a tie!')
                    break
                else:
                    turn = 'computer'
        else:
            #Computer's turn
            move = getComputerMove(theBoard, computerLetter)
            makeMove(theBoard, computerLetter, move)
            print(theBoard)
            if isWinner(theBoard,computerLetter):
                drawBoard(theBoard)
                print('The computer has beaten you! You lose.')
                gameIsplaying = False
            else:
                if isBoardFull(theBoard):
                    drawBoard(theBoard)
                    print('The game is a tie!')
                    break
                else:
                    turn = 'player'
    print('Do you want to play again ?(yes or no)')
    if not input().lower().startswith('y'):
        break

源代码:

#Tic-Tac-Toe
import random
#打印棋盘
def drawBoard(board):
    #This function prints out the board that it was passed.
    #"board" is a list of 10 strings representing the board (ignore index 0)
    print(board[7]+'|'+board[8]+'|'+board[9])
    print('-+-+-')
    print(board[4]+'|'+board[5]+'|'+board[6])
    print('-+-+-')
    print(board[1]+'|'+board[2]+'|'+board[3])
    print('-+-+-')
#让玩家来选择X或者是O
def inputPlayerLetter():
    #Let the player enter which letter they want to be.
    #Return a list with the player's letter as the first item and the computer's letter as the secend.
    letter = ' '
    while not (letter == 'X' or letter == 'O'):
        print('Do you want to be X or O ?')
        letter = input().upper()
        #The first element in the list is the player 's letter; the secend is the computer's letter.
        if letter == 'X':
            return ['X', 'O']
        else:
            return ['O', 'X']
#决定谁先走
def whoGoesFirst():
    #Randomly choose which player goes first.
    if random.randint(0, 2) == 0:
        return 'computer'
    else:
        return 'player'
#在游戏版上放置一个标记
def makeMove(board, letter, move):
    board[move] = letter
#判断玩家是否获胜
def isWinner(bo,le):
    return ((bo[7] == le and bo[8] == le and bo[9] == le) or # across the top
    (bo[4] == le and bo[5] == le and bo[6] == le) or # across the middle
    (bo[1] == le and bo[2] == le and bo[3] == le) or # across the bottom
    (bo[7] == le and bo[4] == le and bo[1] == le) or # down the left side
    (bo[8] == le and bo[5] == le and bo[2] == le) or # down the middle
    (bo[9] == le and bo[6] == le and bo[3] == le) or # down the right side
    (bo[7] == le and bo[5] == le and bo[3] == le) or # diagonal
    (bo[9] == le and bo[5] == le and bo[1] == le)) # diagonal
#复制游戏版的数据
def getBoardCopy(board):
    #Make a copy of the board list and return it.
    boardCopy = []
    for i in board:
        boardCopy.append(i)
    return boardCopy
#判断游戏板上的格子是否为空
def isSpaceFree(board, move):
    #Return True if the passed move is free on the passed board.
    return board[move] == ' '
#让玩家输入落子的格子的编号
def getPlayerMove(board):
    #Let the player enter their move.
    move = ' '
    while move not in '1 2 3 4 5 6 7 8 9'.split() or not isSpaceFree(board, int(move)):
        print('What is your next move ? (1-9)')
        move = input()
    return int(move)
#从落子列表选择一个落子
def chooseRandomMoveFromList(board, moveList):
    #Returns a valid move from the passed list on the passed board.
    #Returns  None if there in no valid move.
    possibleMoves = []
    for i in moveList:
        if isSpaceFree(board, i):
            possibleMoves.append(i)
    if len(possibleMoves) != 0:
        return random.choice(possibleMoves)
    else:
        return None
def getComputerMove(board, computerLetter):
    #Given a board and the computer 's letter, determine where to move and return that move.
    if computerLetter == 'X':
        playerLetter = 'O'
    else:
        playerLetter = 'X'
    #Here is the algorithm for our Tic-Tac-Toe AI:
    #First, check if we can win in the next move.
    for i in range(0, 10):
        boardCopy = getBoardCopy(board)
        if isSpaceFree(boardCopy, i):
            makeMove(boardCopy, computerLetter, i)
            if isWinner(boardCopy, computerLetter):
                return i
    #Check if the player could win on their next move and blockthem.
    for i in range(0, 10):
        boardCopy = getBoardCopy(board)
        if isSpaceFree(boardCopy, i):
            makeMove(boardCopy, playerLetter, i)
            if isWinner(boardCopy, playerLetter):
                return i
    #Try to take one of the corners, if they are free.
    move = chooseRandomMoveFromList(board, [1, 3, 7, 9])
    if move != None:
        return move
    #Try to take the center, if it is free.
    if isSpaceFree(board, 5):
        return 5
    #Move on the sides.
    return chooseRandomMoveFromList(board, [2, 4, 6, 8])
def isBoardFull(board):
    #Return True if every space on the board has taken. Otherwise, return False
    for i in range(1, 10):
        if isSpaceFree(board, i):
            return False
    return True
print('Welcome to Tic-Tac-Toe!')
while True:
    #Reset the board.
    theBoard = [' '] * 10
    playerLetter,computerLetter = inputPlayerLetter()
    turn = whoGoesFirst()
    print('The '+turn+' will go first.')
    gameIsplaying = True
    while gameIsplaying:
        if turn == 'player':
            #Player's turn
            drawBoard(theBoard)
            move = getPlayerMove(theBoard)
            makeMove(theBoard, playerLetter, move)
            print(theBoard)
            if isWinner(theBoard,playerLetter):
                drawBoard(theBoard)
                print('Hooray, You have won the game!')
                gameIsplaying = False
            else:
                if isBoardFull(theBoard):
                    drawBoard(theBoard)
                    print('The game is a tie!')
                    break
                else:
                    turn = 'computer'
        else:
            #Computer's turn
            move = getComputerMove(theBoard, computerLetter)
            makeMove(theBoard, computerLetter, move)
            print(theBoard)
            if isWinner(theBoard,computerLetter):
                drawBoard(theBoard)
                print('The computer has beaten you! You lose.')
                gameIsplaying = False
            else:
                if isBoardFull(theBoard):
                    drawBoard(theBoard)
                    print('The game is a tie!')
                    break
                else:
                    turn = 'player'
    print('Do you want to play again ?(yes or no)')
    if not input().lower().startswith('y'):
        break


作者:_低头写作业



tic tac Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号