井字棋游戏(Python案例研究八)

井字棋,英文名叫Tic-Tac-Toe,是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。

游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线,则为获胜


不得不说,井字棋是我们上课时与同桌打发枯燥时光,必不可少的游戏。简单又有趣,但玩透了之后,基本是平局。

在这里插入图片描述

  • 中心(4)
  • 角(0、2、6、8)
  • 边(1、3、5、7)

获胜规律:
先手下角,后手必中
先手下中,后手必角
否则,必有一个死棋

实现效果


这是一次我与AI对弈的过程:

请选择棋子X或者O(X先走,O后走):x
player先走!
	0 | 1 | 2
	_ | _ | _
	3 | 4 | 5
	_ | _ | _
	6 | 7 | 8
请选择落子位置(0-8):3
	0 | 1 | 2
	_ | _ | _
	X | 4 | 5
	_ | _ | _
	6 | 7 | 8
计算机人工智能AI落子位置: 4
	0 | 1 | 2
	_ | _ | _
	X | O | 5
	_ | _ | _
	6 | 7 | 8
请选择落子位置(0-8):6
	0 | 1 | 2
	_ | _ | _
	X | O | 5
	_ | _ | _
	X | 7 | 8
计算机人工智能AI落子位置: 0
	O | 1 | 2
	_ | _ | _
	X | O | 5
	_ | _ | _
	X | 7 | 8
请选择落子位置(0-8):8
	O | 1 | 2
	_ | _ | _
	X | O | 5
	_ | _ | _
	X | 7 | X
计算机人工智能AI落子位置: 7
	O | 1 | 2
	_ | _ | _
	X | O | 5
	_ | _ | _
	X | O | X
请选择落子位置(0-8):1
	O | X | 2
	_ | _ | _
	X | O | 5
	_ | _ | _
	X | O | X
计算机人工智能AI落子位置: 2
	O | X | O
	_ | _ | _
	X | O | 5
	_ | _ | _
	X | O | X
请选择落子位置(0-8):5
	O | X | O
	_ | _ | _
	X | O | X
	_ | _ | _
	X | O | X
平局!!!

井字棋的设计思路


棋盘采用包含9个元素的列表来实现

棋盘bord,

bord[0]到bord[8]存储代表棋子的字符串

字符串0到8代表未落子
字符串XO表示两种棋子

程序的流程:

  1. 初始化棋盘
    在这里插入图片描述
  2. 询问玩家选择棋子:棋子X先走,棋子O后走
  3. 显示棋盘及落子布局
  4. 循环轮流落子

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

  • 如果某位置落子可以获胜,则选择该位置
  • 否则,如果某个位置,玩家下一步落子可以获胜,则选择该位置
  • 否则,按中心(4)、角(0、2、6、8)、边(1、3、5、7)顺序选择空的位置

就按照这个规律,我下不赢AI,把把都是平手…

判断输赢规则如下:

  1. 三条横线
    0、1、2
    3、4、5
    6、7、8
  2. 三条竖线
    0、3、6
    1、4、7
    2、5、8
  3. 两条对角线
    0、4、8
    2、4、6

以上八种情况的三个位置的棋子相同,则该棋子方赢棋。
如果全部位置落子,则平局

代码实现


def display_board(board):
    """显示棋盘"""
    print("\t{0} | {1} | {2}".format(board[0], board[1], board[2]))
    print("\t_ | _ | _")
    print("\t{0} | {1} | {2}".format(board[3], board[4], board[5]))
    print("\t_ | _ | _")
    print("\t{0} | {1} | {2}".format(board[6], board[7], board[8]))


def legal_moves(board):
    """返回可落子的位置列表"""
    moves = []#存放的是int类型
    for i in range(9):
        if board[i] in list("012345678"):
            moves.append(i)
    return moves


def getPlayerMove(board):
    """询问并确定玩家的选择落子位置,无效位置时重复询问"""
    move = 9
    while move not in legal_moves(board):
        move = int(input("请选择落子位置(0-8):"))
    return move


def getComputerMove(board, computerLetter, playerLetter):
    """核心算法:计算人工智能AI的落子位置"""
    boardcopy = board.copy()

    # 规则一:判断如果某位置落子可以获胜,则选择该位置
    for move in legal_moves(boardcopy):
        boardcopy[move] = computerLetter
        if isWinner(boardcopy):
            return move
        boardcopy[move] = str(move)
    
    # 规则二:某个位置玩家下一步落子可以获胜,则选择该位置
    for move in legal_moves(boardcopy):
        boardcopy[move] = playerLetter
        if isWinner(boardcopy):
            return move
        boardcopy[move] = str(move)
    
    # 规则三:按照中心、角、边的顺序选择空的位置
    for move in (4,0,2,6,8,1,3,5,7):
        if move in legal_moves(board):
            return move

        
def isWinner(board):
    """判断所给的棋子是否获胜"""
    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():
    """井字棋"""
    board = list("012345678")
    playerLetter = input("请选择棋子X或者O(X先走,O后走):")
    if playerLetter in ("X", "x"):
        turn = "player"
        playerLetter = "X"
        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):
                display_board(board)
                print("恭喜玩家获胜!")
                break
            else:
                turn = "computer"
        else:
            move = getComputerMove(board, computerLetter, playerLetter)
            print("计算机人工智能AI落子位置:", move)
            board[move] = computerLetter
            if isWinner(board):
                display_board(board)
                print("计算机人工智能AI获胜!")
                break
            else:
                turn = "player"

        if isTie(board):
            display_board(board)
            print('平局!!!')
            break


if __name__ == '__main__':
    tic_tac_toe()


参考资料:

发布了150 篇原创文章 · 获赞 267 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/Zhangguohao666/article/details/103280740