python 井字棋-文字版(下)

时间:2022-07-27
本文章向大家介绍python 井字棋-文字版(下),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

上篇文章 python 井字棋-文字版(上)电脑端下棋策略是随机的,有哪些位置可下棋,就随机选择一个位置;

实际中是不存这么傻的对手的,赋予电脑一个正常的智商还是很有必要的:

  • 至少当对手下一步要赢了,我们应该马上堵住哪个位置;
  • 如果电脑自己能赢了,那就应该下能够赢的位置;
  • 如果双方都赢不了,那就找一个比较好的位置下棋,占据有利的局势;

这样简单的几个策略,就让电脑具备一点AI效果了,

在非常明显情况下,电脑是不会输的;绝大数情况下能保持不败。

完整代码

想要做的更好,可以自己修改提示说明,玩法说明等等

import random

def display_instruct():
    print("游戏规则")

def new_board():
    return [" "]*9

def display_board(board):
    print(
        f"""
        |{board[0]}|{board[1]}|{board[2]}|
        |{board[3]}|{board[4]}|{board[5]}|
        |{board[6]}|{board[7]}|{board[8]}|
        """
    )

def pieces():
    is_go_first = input("你想要先走吗? (y/n): ").lower()
    if is_go_first == "y":
        human,computer =  "X","O"
    else:
        human, computer = "O", "X"
    return human, computer
    
def legal_moves(board):
    moves = []
    for move in range(9):
        if board[move] ==" ":
            moves.append(move)
    return moves

def human_move(board):
    legal =legal_moves(board)
    move = int(input("你要走哪个位置? (0 - 8):"))
    while move not in legal:
        move = int(input("你要走哪个位置? (0 - 8):"))
    return move

def computer_move(board, computer, human):
    # 复制棋盘
    board = board[:]
    # 最优的位置
    best_moves = (4, 0, 2, 6, 8, 1, 3, 5, 7)
    
    # 如果电脑可以赢,就下该位置
    for move in legal_moves(board):
        board[move] = computer
        if winner(board) == computer:
            return move
        # 测试不行,取消重来
        board[move] = " "
    
    # 如果玩家可以赢,就下该位置
    for move in legal_moves(board):
        board[move] = human
        if winner(board) == human:
            return move
        # 测试不行,取消重来
        board[move] = " "

    # 如果双方都不行,选择最优位置下棋
    for move in best_moves:
        if move in legal_moves(board):
            return move

def next_turn(turn):
    if turn == "X":
        return "O"
    else:
        return "X"

def winner(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 row in WAYS_TO_WIN:
        if board[row[0]] == board[row[1]] == board[row[2]] != " ":
            winner = board[row[0]]
            return winner

    if " " not in board:
        return "平局"

    return None

def congrat_winner(winner,human,computer):
    if winner!="平局":
        print(winner, "won!n")
    else:
        print("这是一场平局")
    if winner == human:
        print("恭喜你获得胜利!!")
    elif winner == computer:
        print("你输了!")

display_instruct()
human,computer = pieces()
turn = "X"
board = new_board()
display_board(board)
while not winner(board):
    if turn ==human:
        move = human_move(board)
        board[move] =human 
    else:
        move = computer_move(board, computer, human)
        board[move] = computer
    display_board(board)
    turn = next_turn(turn)
    the_winner = winner(board)
congrat_winner(the_winner,human,computer)

当然这只是针对井字棋这种步骤比较有限的棋;

要是五子棋,那么电脑需要计算的步骤就会比较多了,判断赢的情况也会更复杂了,感兴趣的可以思考一下五子棋游戏的实现;

  1. 棋盘采取那种数据结构?
  2. 如何判断输赢?
  3. 电脑下棋策略?

下篇-python五子棋(上)

我的代码运行效果如下:

x赢了

具体棋盘实现和输赢判断实现下篇文章讲解。

(全文完)