【Python】井字棋 Tic_Tac_Toe

这是我在做综合设计“机械臂下井字棋”时,“井字棋”的代码,在写代码期间我参考了很多博客。

该代码没有运用高级的算法,实现功能也非常简单,没有悔棋、没有重新开始,运行一次只能玩一局。

该代码是我在控制机械臂时调用的一个库,其中存储棋盘状态的矩阵board含有三个状态:0代表没有棋子,1代表红色,2代表蓝色。为了使这个库能够单独运行,我对其进行改进,单独运行时矩阵board也有三个状态,“ ”代表没有棋子。“X”代表一种棋子,“O”代表另一种棋子。

直接上代码吧!

# !/usr/bin/env python3
# -*- coding:UTF-8 -*-
# Tic_Toc_Toe
# @ Author: Marvel
# @ Dara: 2019.10.25
import random


# 绘制出当前棋盘
def draw_board(board_):
    print('\n\n')
    print('\t\t┌─┬─┬─┐')
    print('\t\t│' + str(board_[0]) + ' │' + str(board_[1]) + ' │' + str(board_[2]) + ' │')
    print('\t\t├─┼─┼─┤')
    print('\t\t│' + str(board_[3]) + ' │' + str(board_[4]) + ' │' + str(board_[5]) + ' │')
    print('\t\t├─┼─┼─┤')
    print('\t\t│' + str(board_[6]) + ' │' + str(board_[7]) + ' │' + str(board_[8]) + ' │')
    print('\t\t└─┴─┴─┘')


# 在指定范围内,随机选择可以落子的位置
def random_pos(board_, list_):
    possible_choice_ = []
    for i in list_:
        if board_[i] == ' ' or board_[i] == 0:
            possible_choice_.append(i)

    if len(possible_choice_) > 0:
        return random.choice(possible_choice_)
    else:
        return None


# 判断是否取得胜利
def is_win(board_, color_flag_):
    if [board_[0], board_[1], board_[2]] == [color_flag_, color_flag_, color_flag_]:
        return True
    if [board_[3], board_[4], board_[5]] == [color_flag_, color_flag_, color_flag_]:
        return True
    if [board_[6], board_[7], board_[8]] == [color_flag_, color_flag_, color_flag_]:
        return True
    if [board_[0], board_[3], board_[6]] == [color_flag_, color_flag_, color_flag_]:
        return True
    if [board_[1], board_[4], board_[7]] == [color_flag_, color_flag_, color_flag_]:
        return True
    if [board_[2], board_[5], board_[8]] == [color_flag_, color_flag_, color_flag_]:
        return True
    if [board_[0], board_[4], board_[8]] == [color_flag_, color_flag_, color_flag_]:
        return True
    if [board_[2], board_[4], board_[6]] == [color_flag_, color_flag_, color_flag_]:
        return True


# 判断棋盘是否下满
def is_full(board_):
    for i in range(9):
        if board_[i] == ' ' or board_[i] == 0:
            return False
    return True


# 分析下一步棋的选择
def get_computer_move(board_, computer_color_flag_):

    # 当棋子分别为1、2时
    if computer_color_flag_ == 1:
        player_color_flag_ = 2
    elif computer_color_flag_ == 2:
        player_color_flag_ = 1

    # 当棋子分别为X、0时
    elif computer_color_flag_ == 'X':
        player_color_flag_ = 'O'
    elif computer_color_flag_ == 'O':
        player_color_flag_ = 'X'

    # 分析Player先手是否落在角落,如果落在角落,那么Computer必须落在中间
    player_first_corner = False
    player_count = 0
    computer_count = 0
    for i in range(9):
        if board_[i] == player_color_flag_:
            player_count += 1
        if board_[i] == computer_color_flag_:
            computer_count += 1
    if player_count == 1 and computer_count == 0:
        for i in [0, 2, 6, 8]:
            if board_[i] == player_color_flag_:
                player_first_corner = True

    # 首先判断电脑方能否通过一次落子直接获得游戏胜利
    for i in range(9):
        temp_board = board_.copy()
        if board_[i] == ' ' or board_[i] == 0:             # 无其他棋子
            temp_board[i] = computer_color_flag_
            if is_win(temp_board,computer_color_flag_):
                return i

    # 判断玩家下一次落子能否获得胜利,如果能,给他堵上
    for i in range(9):
        temp_board = board_.copy()
        if board_[i] == ' ' or board_[i] == 0:              # 无其他棋子
            temp_board[i] = player_color_flag_
            if is_win(temp_board,player_color_flag_):
                return i

    # 优先级1:随机落子在四个角
    if player_first_corner is False:
        random_move = random_pos(temp_board, [0, 2, 6, 8])
        if random_move is not None:
            return random_move

    # 优先级2:落子在中心
    if board_[4] == ' ' or board_[4] == 0:
        return 4

    # 优先级3:随机落子其他位置
    random_move = random_pos(board_, [1, 3, 5, 7])
    if random_move is not None:
        return random_move


if __name__ == '__main__':
    board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']          # 初始化棋盘
    letter = ' '      # player 的棋子
    first_turn = ' '    # 谁先手

    # 玩家选择棋子,当玩家选择正确时跳出该循环
    while True:
        if letter == 'X' or letter == 'O':
            break
        else:
            print('Do you want bo be X or O')
            letter = input().upper()  # 获得输入字母的大写符号

    # 玩家选择谁先落子
    while True:
        if first_turn == 'A' or first_turn == 'B':
            break
        else:
            print('Who first?    A: player    B:Computer')
            first_turn = input().upper()  # 获得输入字母的大写符号

    # 确定棋子标志
    if letter == 'X':
        player_color = 'X'
        computer_color = 'O'
    else:
        player_color = 'O'
        computer_color = 'X'

    if first_turn == 'A':
        print('Please choose  position where you want to place. From 1 to 9')
        num = int(input()) # 获得输入数字
        board[num-1] = player_color
        draw_board(board)

    while True:
        # p判断是否又输赢
        if is_wn(board, computer_color):
            print("Player Win")
            break
        k = get_computer_move(board, computer_color)
        print(k)
        board[k] = computer_color
        draw_board(board)
        if is_full(board):
            print('Draw')       # 平局
            break

        if is_win(board, player_color):
            print("Computer Win")
            break
        print('Please choose  position where you want to place')
        num = int(input())  # 获得输入数字
        board[num - 1] = player_color
        draw_board(board)
        if is_full(board):
            print('Draw')         # 平局
            break
    exit()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

望天边星宿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值