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网络编程学习笔记(四):域名系统
Jun 09 Python
Python编写电话薄实现增删改查功能
May 07 Python
python实现截取屏幕保存文件,删除N天前截图的例子
Aug 27 Python
python打印n位数“水仙花数”(实例代码)
Dec 25 Python
python sitk.show()与imageJ结合使用常见的问题
Apr 20 Python
解决Keras自带数据集与预训练model下载太慢问题
Jun 12 Python
基于Python实现下载网易音乐代码实例
Aug 10 Python
PyTorch 导数应用的使用教程
Aug 31 Python
pandas按照列的值排序(某一列或者多列)
Dec 13 Python
解决numpy数组互换两行及赋值的问题
Apr 17 Python
Python 文本滚动播放器的实现代码
Apr 25 Python
Python 如何利用ffmpeg 处理视频素材
Nov 27 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
PHP stream_context_create()作用和用法分析
2011/03/29 PHP
PHP的curl实现get,post和cookie(实例介绍)
2013/06/17 PHP
有关于PHP中常见数据类型的汇总分享
2014/01/06 PHP
php多线程并发实现方法
2016/09/30 PHP
ThinkPHP5.0框架使用build 自动生成模块操作示例
2019/04/11 PHP
用javascript编写的第一人称射击游戏
2007/02/25 Javascript
js汉字转拼音实现代码
2013/02/06 Javascript
开发 Internet Explorer 右键功能表(ContextMenu)
2013/07/03 Javascript
JavaScript中操作字符串之localeCompare()方法的使用
2015/06/06 Javascript
Jqgrid之强大的表格插件应用
2015/12/02 Javascript
详解Angularjs filter过滤器
2016/02/06 Javascript
JS弹出层遮罩,隐藏背景页面滚动条细节优化分析
2016/04/29 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
2016/12/05 Javascript
解决Angular.Js与Django标签冲突的方案
2016/12/20 Javascript
js数字舍入误差以及解决方法(必看篇)
2017/02/28 Javascript
JS HTML图片显示Canvas 压缩功能
2017/07/21 Javascript
ES6 Set结构的应用实例分析
2019/06/26 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
2019/11/15 Javascript
[42:06]2019国际邀请赛全明星赛 8.23
2019/09/05 DOTA
python根据路径导入模块的方法
2014/09/30 Python
深入解析Python中的上下文管理器
2016/06/28 Python
python基础教程项目二之画幅好画
2018/04/02 Python
基于python神经卷积网络的人脸识别
2018/05/24 Python
python学习之hook钩子的原理和使用
2018/10/25 Python
Python笔记之代理模式
2019/11/20 Python
Python3.5 win10环境下导入kera/tensorflow报错的解决方法
2019/12/19 Python
python mysql自增字段AUTO_INCREMENT值的修改方式
2020/05/18 Python
属性与 @property 方法让你的python更高效
2020/09/21 Python
html5文本内容_动力节点Java学院整理
2017/07/11 HTML / CSS
Html5写一个简单的俄罗斯方块小游戏
2019/12/03 HTML / CSS
美国非常受欢迎的Spa品牌:Bliss必列斯
2018/04/10 全球购物
给老婆的搞笑检讨书
2014/01/12 职场文书
经销商年会策划方案
2014/05/29 职场文书
出差报告范文
2014/11/06 职场文书
党员年终个人总结
2015/02/14 职场文书
小米11和iphone12哪个值得买?小米11对比iphone12评测
2021/04/21 数码科技