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解析发往本机的数据包示例 (解析数据包)
Jan 16 Python
用Python实现协同过滤的教程
Apr 08 Python
django之session与分页(实例讲解)
Nov 13 Python
python中lambda()的用法
Nov 16 Python
详解用Python处理HTML转义字符的5种方式
Dec 27 Python
python对列进行平移变换的方法(shift)
Jan 10 Python
Python模块的制作方法实例分析
Dec 21 Python
python+selenium 脚本实现每天自动登记的思路详解
Mar 11 Python
Selenium启动Chrome时配置选项详解
Mar 18 Python
基于Python把网站域名解析成ip地址
May 25 Python
写一个Python脚本自动爬取Bilibili小视频
Apr 24 Python
使用pycharm运行flask应用程序的详细教程
Jun 07 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
基于MySQL到MongoDB简易对照表的详解
2013/06/03 PHP
Zend Framework教程之Loader以及PluginLoader用法详解
2016/03/09 PHP
Yii核心验证器api详解
2016/11/23 PHP
php对微信支付回调处理的方法
2018/08/23 PHP
jQuery 使用手册(七)
2009/09/23 Javascript
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(上:事件篇)
2010/03/24 Javascript
json的前台操作和后台操作实现代码
2012/01/20 Javascript
script的async属性以非阻塞的模式加载脚本
2013/01/15 Javascript
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
js实现在网页上简单显示时间的方法
2015/03/02 Javascript
js实现模拟银行卡账号输入显示效果
2015/11/18 Javascript
js判断登陆用户名及密码是否为空的简单实例
2016/05/16 Javascript
浅析jquery unbind()方法移除元素绑定的事件
2016/05/24 Javascript
Node.js中的require.resolve方法使用简介
2017/04/23 Javascript
Bootstrap Tree View简单而优雅的树结构组件实例解析
2017/06/15 Javascript
laydate日历控件使用方法详解
2017/11/20 Javascript
利用jQuery+localStorage实现一个简易的计时器示例代码
2017/12/25 jQuery
Angular实现的进度条功能示例
2018/02/18 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
vue中全局路由守卫中替代this操作(this.$store/this.$vux)
2020/07/24 Javascript
解决vue项目获取dom元素宽高总是不准确问题
2020/07/29 Javascript
[54:26]完美世界DOTA2联赛PWL S3 Forest vs Rebirth 第一场 12.10
2020/12/12 DOTA
[09:59]DOTA2-DPC中国联赛2月7日Recap集锦
2021/03/11 DOTA
Python的Bottle框架的一些使用技巧介绍
2015/04/08 Python
Python的Django框架中消息通知的计数器实现教程
2016/06/13 Python
python3之微信文章爬虫实例讲解
2017/07/12 Python
Python程序包的构建和发布过程示例详解
2019/06/09 Python
python中的split()函数和os.path.split()函数使用详解
2019/12/21 Python
python中怎么表示空值
2020/06/19 Python
美国领先的商务贺卡出版商:The Gallery Collection
2018/02/13 全球购物
《长城》教学反思
2014/02/14 职场文书
给学校的建议书
2014/03/12 职场文书
公安机关纪律作风整顿个人剖析材料材料
2014/10/10 职场文书
5分钟教你docker安装启动redis全教程(全新方式)
2021/05/29 Redis
开机音效回归! Windows 11重新引入开机铃声
2021/11/21 数码科技
教你nginx跳转配置的四种方式
2022/07/07 Servers