打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Python案例分析|井字棋(Tic Tac Toe)游戏

【案例目的】       

本案例通过一个井字棋游戏的设计和实现,帮助读者了解Python函数的定义和使用。可以对应于教程正文的第8章。

【案例内容】

01

井字棋游戏概述

井字棋又称三子棋、三连棋,英文名为Tic Tac Toe,是一款休闲益智游戏。具体玩法为在一个3*3的棋盘上,一个玩家用X做棋子,另一个玩家用O做棋子,谁先在棋盘上的一行、一列或者对角线上画满三个棋子,即可获胜,如果棋盘下满无人胜出,即为平局。

02

井字棋游戏设计思路

棋盘采用包含9个元素的列表来表示,board[0]到board[8]存储代表棋子的字符串,字符串中可以包含'X'、'O'、或者数字0到8(表示未落子)。

程序的流程如下:

(1)初始化棋盘;

(2)询问玩家选择棋子:棋子X先走,棋子O后走;

(3)显示棋盘及落子布局(调用函数display_board());

(4)循环轮流落子:

(4-1)如果玩家落子,则询问落子位置(调用函数getPlayerMove(),然后判断玩家是否获胜(调用函数isWinner()),如果获胜,显示棋盘(调用函数display_board()),输出信息,break跳出循环;

(4-2)如果计算机人工智能(AI)落子,则根据计算机人工智能(AI)落子算法计算落子位置,然后判断AI是否获胜(调用函数isWinner()),如果AI获胜,则显示棋盘(调用函数display_board()),输出信息,break跳出循环;

(4-3)判断是否平局(调用函数isTie()),如果平局,则显示棋盘(调用函数display_board()),输出信息,break跳出循环;否则继续轮流落子。

计算机人工智能(AI)落子算法如下:

(1)如果某位置落子可以获胜,则选择该位置;

(2)否则,如果某个位置玩家下一步落子可以获胜,则选择该位置;

(3)否则,按中心(4)、角(0、2、6、8)、边(1、3、5、7)顺序选择空的位置。

判断输赢规则如下:如果三条横线((0,1,2), (3,4,5), (6,7,8))、三条竖线((0,3,6), (1,4,7), (2,5,8))、两条对角线((0,4,8), (2,4,6))共八种情况的三个位置的棋子相同,则该棋子方赢棋。如果全部位置落子,则平局。

03

井字棋游戏实现

【例CS.27】井字棋(Tic Tac Toe)游戏示例程序。y)。

# 模块:c:\pythonpa\cs\tic_tac_toe.py
def display_board(b):
    '''显示棋盘'''
    print('\t{0}|{1}|{2}'.format(b[0],b[1],b[2]))
    print('\t_|_|_')
    print('\t{0}|{1}|{2}'.format(b[3],b[4],b[5]))
    print('\t_|_|_')
    print('\t{0}|{1}|{2}'.format(b[6],b[7],b[8]))
def legal_moves(board):
    '''返回可落子的位置列表'''
    moves = []
    for i in range(9):
        if board[i] in list('012345678'):
            moves.append(i)
    return moves
def getPlayerMove(board):  
    '''询问并确定玩家(player)选择落子位置,无效位置时重复询问'''
    move = 9 # 初始值9为错误的位置
    while move not in legal_moves(board):
        move = int(input('请选择落子位置(0-8):'))
    return move
def getComputerMove(board, computerLetter, playerLetter):         
    '''计算人工智能AI的落子位置,Tic Tac Toe AI核心算法'''  
    boardcopy = board.copy() #拷贝棋盘,不影响原来
    # 规则1:判断如果某位置落子可以获胜,则选择该位置
    for move in legal_moves(boardcopy):
        boardcopy[move] = computerLetter
        if isWinner(boardcopy, computerLetter): #判断是否获胜
            return move
        boardcopy[move] = str(move)
            
    # 规则2:某个位置玩家下一步落子可以获胜,则选择该位置
    for move in legal_moves(boardcopy):
        boardcopy[move] = playerLetter
        if isWinner(boardcopy, playerLetter): #判断是否获胜
            return move
        boardcopy[move] = str(move)
    # 规则2:按照中心(4)、角(0、2、6、8)、
    # 以及边(1、3、5、7)的顺序选择空的位置
    for move in (4,0,2,6,8,1,3,5,7):
        if move in legal_moves(board):
            return move
def isWinner(board, letter): 
    '''判断所给的棋子是否获胜'''
    WAYS_TO_WIN = {(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),
    (0,4,8), (2,4,6)}
    for r in WAYS_TO_WIN:
        if board[r[0]]==board[r[1]]==board[r[2]]:
            return True
    return False
def isTie(board):
    '''判断是否平局'''
    for i in list('012345678'):
        if i in board:
            return False
    return True
def tic_tac_toe():
    '''井字棋'''
    #初始化棋盘为['0', '1', '2', '3', '4', '5', '6', '7', '8']
    board = list('012345678')
    #询问玩家选择棋子:棋子X先走,棋子O后走
    playerLetter = input('请选择棋子X或O(X先走,O后走):')
    if playerLetter in ('X', 'x'):
        turn = 'player'   #玩家先走
        computerLetter = 'O'
    else:
        turn = 'computer'
        computerLetter = 'X'
        playerLetter = 'O'
    print('{}先走!'.format(turn))
    while True: #循环轮流落子
        display_board(board)
        if turn == 'player': # 玩家落子
            move = getPlayerMove(board) #询问落子位置
            board[move] = playerLetter #落子
            if isWinner(board, playerLetter): #判断是否获胜
                display_board(board)
                print('恭喜玩家获胜!')
                break
            else:
                turn = 'computer'
        else: #计算机人工智能AI落子
            # 计算人工智能AI落子位置
            move = getComputerMove(board, computerLetter, playerLetter)
            print('计算机人工智能AI落子位置:', move)
            board[move] = computerLetter #落子
            if isWinner(board, computerLetter): #判断是否获胜
                display_board(board)
                print('计算机人工智能AI获胜!')
                break
            else:
                turn = 'player'       
        #判断是否平局
        if isTie(board):
            display_board(board)
            print('平局!')
            break
    
if __name__ == '__main__':
    tic_tac_toe()

程序运行结果示例。

04

参考书籍

《Python程序设计与算法基础教程(第3版·项目实训·题库·微课视频版)》

ISBN:9787302623816

作者:江红、余青松

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Python实战:用 Python 制作井字棋小游戏
用 Python 跟自己下棋(续)
得闲来玩井字棋--Tic Tac Toe
C# 08.使用 Blazor 构建井字棋游戏
今天,我们来教AI下国际象棋
人工智能和人类未来(上)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服