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操作日期和时间的方法
Mar 11 Python
Python实现的查询mysql数据库并通过邮件发送信息功能
May 17 Python
基于OpenCV python3实现证件照换背景的方法
Mar 22 Python
Pyqt5实现英文学习词典
Jun 24 Python
Python Django 实现简单注册功能过程详解
Jul 29 Python
Django项目中实现使用qq第三方登录功能
Aug 13 Python
Python3.7+tkinter实现查询界面功能
Dec 24 Python
如何通过python实现人脸识别验证
Jan 17 Python
使用 tf.nn.dynamic_rnn 展开时间维度方式
Jan 21 Python
Python爬取365好书中小说代码实例
Feb 28 Python
Python编程快速上手——strip()函数的正则表达式实现方法分析
Feb 29 Python
django 利用Q对象与F对象进行查询的实现
May 15 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
相对路径转化成绝对路径
2007/04/10 PHP
php实现的Captcha验证码类实例
2014/09/22 PHP
php使用cookie保存登录用户名的方法
2015/01/26 PHP
关于PHP文件的自动运行方法分析
2016/05/13 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
pjblog中的UBBCode.js
2007/04/25 Javascript
JSQL SQLProxy 的 php 版本代码
2010/05/05 Javascript
学习面向对象之面向对象的术语
2010/11/30 Javascript
js实现单行文本向上滚动效果实例代码
2013/11/28 Javascript
JavaScript事件学习小结(三)js事件对象
2016/06/09 Javascript
jQuery选择器总结之常用元素查找方法
2016/08/04 Javascript
Node.js中使用jQuery的做法
2016/08/17 Javascript
JS获得多个同name 的input输入框的值的实现方法
2017/01/09 Javascript
jQuery EasyUI Accordion可伸缩面板组件使用详解
2017/02/28 Javascript
Vue导出页面为PDF格式的实现思路
2018/07/31 Javascript
JS事件流与事件处理程序实例分析
2019/08/16 Javascript
Node.js HTTP服务器中的文件、图片上传的方法
2019/09/23 Javascript
[01:11:48]Fnatic vs IG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python模块restful使用方法实例
2013/12/10 Python
Python复数属性和方法运算操作示例
2017/07/21 Python
Flask解决跨域的问题示例代码
2018/02/12 Python
解决python pandas读取excel中多个不同sheet表格存在的问题
2020/07/14 Python
Python爬虫之Selenium库的使用方法
2021/01/03 Python
css3实现超炫风车特效
2014/11/12 HTML / CSS
彪马法国官网:PUMA法国
2019/12/15 全球购物
如何用Java实现列出某个目录下的所有子目录
2015/07/20 面试题
2014年高三毕业生自我评价
2014/01/11 职场文书
领导视察欢迎词
2014/01/15 职场文书
抽样调查项目计划书
2014/04/24 职场文书
新郎新娘答谢词
2015/01/04 职场文书
幼儿园母亲节活动总结
2015/02/10 职场文书
2015年银行员工工作总结
2015/04/24 职场文书
2015年度个人业务工作总结
2015/04/27 职场文书
合同审查法律意见书
2015/06/04 职场文书
幼儿园师德师风心得体会
2016/01/12 职场文书
OpenStack虚拟机快照和增量备份实现方法
2022/04/04 Servers