Python游戏编程(五)Tic Tac Toe

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

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

  1. 首先,判断是否有能够让计算机获胜的落子位置。如果是,在那里落子;否则,执行步骤2.
  2. 判断受否有能够让玩家失败的落子位置。如果是,在那里落子,以便堵住玩家;否则,执行步骤3.
  3. 判断是否还有角(格子1、3、7或者9)为空。如果有,在此处落子;如果没有角为空,那么执行步骤4.
  4. 判断是否中心(格子5)为空。如果有,在此处落子;否则,执行步骤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
            
发布了9 篇原创文章 · 获赞 1 · 访问量 415

猜你喜欢

转载自blog.csdn.net/weixin_45755966/article/details/104278769
今日推荐