python井字棋游戏实现人机对战


Posted in Python onApril 28, 2022

游戏简介:在九宫格内进行,如果一方抢先于另一方向(横、竖、斜)连成3子,则获得胜利。游戏中输入方格位置代号的形式如下:

python井字棋游戏实现人机对战

设计前的思路:

游戏中,board棋盘存储玩家、计算机的落子信息,未落子处未EMPTY。由于人机对战,需要实现计算机智能性,下面是为这个计算机机器人设计的简单策略:
如果有一步棋可以让计算机机器人在本轮获胜,那就选那一步走。
否则,如果有一步棋可以让玩家在本轮获胜,那就选那一步走。
否则,计算机机器人应该选择最佳位置来走。
最佳位置就是中间,其次是四个角
定义第一个元组best_weizhi存储最佳方格位置:
按优劣顺序排序的下棋位置
best_weizhi= (4, 0, 2, 6, 8, 1, 3, 5, 7)
井字棋盘输赢判断规则只有8种方式。每种获胜方式都被写成一个元组,利用嵌套元组表达:
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))

代码:

#全局常量
best_weizhi= (4, 0, 2, 6, 8, 1, 3, 5, 7)
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)) 
X = "X"
O = "O"
EMPTY = " "
#定义函数产生一个新的棋盘
def new_board():
    board = []
    for square in range(9):
        board.append(EMPTY)
    return board
#询问该谁下棋
def ask_yes_no(question):
    response = None
    #如果输入不是"y", "n",继续重新输入
    while response not in ("y", "n"):    
           response = input(question).lower()
    return response
#询问谁先走,先走方为X,后走方为O
#函数返回电脑方、玩家的角色代号
def pieces():
    go_first = ask_yes_no("玩家你是否先走 (y/n): ")
    if go_first == "y":
        print("\n玩家你先走.")
        human = X
        computer = O
    else:
        print("\n电脑先走.")
        computer = X
        human = O
    return computer, human
#显示棋盘
def display_board(board):
    board2=board[:]     #创建副本,修改不影响原来列表board
    for i in range(len(board)):
        if board[i]==EMPTY:
            board2[i]=i
    print("\t", board2[0], "|", board2[1], "|", board2[2])
    print("\t", "---------")
    print("\t", board2[3], "|", board2[4], "|", board2[5])
    print("\t", "---------")
    print("\t", board2[6], "|", board2[7], "|", board2[8], "\n")
#输入你想下的位置数字
def ask_number(question, low, high):
    response = None
    while response not in range(low, high):
        response = int(input(question))
    return response
#产生可以合法走棋位置序列(也就是还未下过子位置)
def legal_moves(board):
    moves = []
    for i in range(9):
        if board[i] == EMPTY:
            moves.append(i)
    return moves
#判断输赢
def winner(board):
    for row in win:
        if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:
            winner = board[row[0]]
            return winner       #返回赢方
    #棋盘没有空位置
    if EMPTY not in board:
        return "True"            #"平局和棋,游戏结束"
    return False
#人走棋
def human_move(board, human):
    legal = legal_moves(board)
    move = None
    while move not in legal:
        move = ask_number("你走那个位置? (0 - 9):", 0, 9)
        if move not in legal:
            print("\n此位置已经落过子了")
    return move
#电脑走棋
def computer_move(board, computer, human):
    # make a copy to work with since function will be changing list
    board = board[:]     #创建副本,修改不影响原来列表board
    #按优劣顺序排序的下棋位置best_weizhi
    # 如果电脑能赢,就走那个位置
    for move in legal_moves(board):
        board[move] = computer
        if winner(board) == computer:
            print("电脑下棋位置是" ,move)
            return move
        # 取消走棋方案
        board[move] = EMPTY
    # 如果玩家能赢,就堵住那个位置
    for move in legal_moves(board):
        board[move] = human
        if winner(board) == human:
            print("电脑下棋位置是" ,move)
            return move
        #取消走棋方案
        board[move] = EMPTY
    #不是上面情况则,也就是这一轮时都赢不了则
    #从最佳下棋位置表中挑出第一个合法位置
    for move in best_weizhi:
        if move in legal_moves(board):
            print("电脑下棋位置是" ,move)
            return move
#转换角色
def next_turn(turn):
    if turn == X:
        return O
    else:
        return X
#主方法:
def main():
    computer, human = pieces()
    turn = X
    board = new_board()
    display_board(board)
    
    while not winner(board):
        if turn == human:
            move = human_move(board, human)
            board[move] = human
        else:
            move = computer_move(board, computer, human)
            board[move] = computer
        display_board(board)
        turn = next_turn(turn)
        the_winner = winner(board)
    #游戏结束输出输赢信息
    if the_winner == computer:
        print("电脑赢!\n")    
    elif the_winner == human:         
        print("玩家赢!\n")
    elif the_winner == "True":    #"平局"        
        print("平局,和棋,游戏结束\n")

# start the program
main()
input("按任意键退出游戏.")

在最后附上结果图:

python井字棋游戏实现人机对战

python井字棋游戏实现人机对战

python井字棋游戏实现人机对战

python井字棋游戏实现人机对战

python井字棋游戏实现人机对战

python井字棋游戏实现人机对战

python井字棋游戏实现人机对战

至此一个简单的井字棋就完成了。


Tags in this post...

Python 相关文章推荐
python操作redis的方法
Jul 07 Python
详解Python命令行解析工具Argparse
Apr 20 Python
PYTHON 中使用 GLOBAL引发的一系列问题
Oct 12 Python
Python实现解析Bit Torrent种子文件内容的方法
Aug 29 Python
PyQt5每天必学之布局管理
Apr 19 Python
浅谈Pandas 排序之后索引的问题
Jun 07 Python
Pandas读取并修改excel的示例代码
Feb 17 Python
python模块导入的方法
Oct 24 Python
基于Django统计博客文章阅读量
Oct 29 Python
python使用配置文件过程详解
Dec 28 Python
python中使用paramiko模块并实现远程连接服务器执行上传下载功能
Feb 29 Python
python UIAutomator2使用超详细教程
Feb 19 Python
Python开发五子棋小游戏
Python简易开发之制作计算器
Apr 28 #Python
Python实现对齐打印 format函数的用法
Apr 28 #Python
python实现简单的三子棋游戏
Apr 28 #Python
Python内置类型集合set和frozenset的使用详解
使用Python获取字典键对应值的方法
Apr 26 #Python
PyTorch中permute的使用方法
Apr 26 #Python
You might like
最省空间的计数器
2006/10/09 PHP
7个超级实用的PHP代码片段
2011/07/11 PHP
深入PHP empty(),isset(),is_null()的实例测试详解
2013/06/06 PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
2016/12/15 PHP
php中通用的excel导出方法实例
2017/12/30 PHP
PHP Swoole异步Redis客户端实现方法示例
2019/10/24 PHP
求解开jscript.encode代码的asp函数
2007/02/28 Javascript
使用Post提交时须将空格转换成加号的解释
2013/01/14 Javascript
解决bootstrap中modal遇到Esc键无法关闭页面
2015/03/09 Javascript
JS插件overlib用法实例详解
2015/12/26 Javascript
jQuery实现TAB选项卡切换特效简单演示
2016/03/04 Javascript
NodeJs安装npm包一直失败的解决方法
2017/04/28 NodeJs
es6学习之解构时应该注意的点
2017/08/29 Javascript
基于Vue的ajax公共方法(详解)
2018/01/20 Javascript
nuxt.js 缓存实践
2018/06/25 Javascript
json前后端数据交互相关代码
2018/09/19 Javascript
微信小程序下拉框组件使用方法详解
2018/12/28 Javascript
js中数组对象去重的两种方法
2019/01/18 Javascript
详解JSON和JSONP劫持以及解决方法
2019/03/08 Javascript
详解如何理解vue的key属性
2019/04/14 Javascript
LayUI动态设置checkbox不显示的解决方法
2019/09/02 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
2020/05/11 Javascript
python删除特定文件的方法
2015/07/30 Python
常用python编程模板汇总
2016/02/12 Python
Python中单例模式总结
2018/02/20 Python
python实现单张图像拼接与批量图片拼接
2020/03/23 Python
python数据分析工具之 matplotlib详解
2020/04/09 Python
Python try except异常捕获机制原理解析
2020/04/18 Python
Python如何实现大型数组运算(使用NumPy)
2020/07/24 Python
CSS3为背景图设置遮罩并解决遮罩样式继承问题
2020/06/22 HTML / CSS
html5组织文档结构_动力节点Java学院整理
2017/07/11 HTML / CSS
canvas实现滑动验证的实现示例
2020/08/11 HTML / CSS
运动会入场词100字
2014/02/06 职场文书
企业理念标语
2014/06/09 职场文书
公务员群众路线专题民主生活会发言材料
2014/09/17 职场文书
丽江古城导游词
2015/02/03 职场文书