python实现推箱子游戏


Posted in Python onMarch 25, 2020

本文实例为大家分享了python实现推箱子游戏的具体代码,供大家参考,具体内容如下

题目描述:

python实现推箱子游戏

最短路径为:

uurrDDDDuuuulldRurDDDrddLLrruLuuulldRurDDDrdL

u表示向上,d表示向下,l表示向左,r表示向右。

大写表示人推着箱子一起动,小写表示人自己走。

代码用BFS实现。状态要分推着箱子一起走和人单独走,这两种状态转移是不同的。

由于代码中注释较详细,这里不过多解释。

代码:

# -*- coding: utf-8 -*-
# @Time : 2017/8/10 上午9:42
# @Author : Qi MO
# @File : BFS.py
# @Software: PyCharm Community Edition
 
level_file_path = '../数据/level_file.txt'
 
class GameShortest:
 def __init__(self,line, col=10):
  """
  给一个图,长度为100的字符串表示。
  0空地 1墙 2箱子起始位置 3箱子终点位置 4人的起始位置
  :param line: 地图,用字符串表示。如代码最后的每一行表示每一关的地图。
  :param col: 地图的长宽,由于设定为10*10,默认为10
  """
 
  self.line = line
  # sta和en 表示开始的状态,结束的状态
  # sta只有2,4,0 2表示箱子开始位置,4表示人的位置,0表示其他。
  # en只有1,3,0 1表示墙,3表示箱子结束位置,0表示其他。
  # 现在只需要把sta状态中的2位置移动到en的3的位置即满足条件
  self.sta = ''
  self.en = ''
  self.col = col
  # px, py表示4的位置
  self.px,self.py = -1,-1
  # paths记录最短路径(可能有多条)
  self.paths = []
  # len记录最短路径长度 如
  self.len = -1
 
  self.pre()
  self.BFS()
  print(self.paths)
 
 def pre(self):
  """
  1.获得sta开始状态和en结束状态
  2.获得人的起始位置px,py
  代码最后的第一关的地图可视化为
  1111111111
  1111111111
  1110001111
  1110221111
  1114201111
  1111100111
  1111300111
  1113300111
  1111111111
  1111111111
  :return:
  """
  mp = []
  for pos in range(0, 100, 10):
   mp.append(self.line[pos:pos + 10])
  # print(self.line)
  # for x in mp:
  #  print(x)
 
  for pos, enum in enumerate(self.line):
   cx, cy = pos // 10, pos % 10
   if enum == '4':
    self.px, self.py = cx, cy
  # 现在只需要把sta开始的状态中的2位置移动到en的3的位置即满足条件
  staDic = {'0': '0', '1': '0', '2': '2', '3': '0', '4': '4'}
  enDic = {'0': '0', '1': '1', '2': '0', '3': '3', '4': '0'}
  for x in self.line:
   self.sta += staDic[x]
   self.en += enDic[x]
  # print(self.sta)
  # print(self.en)
 
 def is_ok(self,sta):
  """
  sta状态中的2位置移动到en的3的位置。
  :param sta:
  :return:
  """
  for s,e in zip(sta,self.en):
   if e == '3' and s != '2':
    return False
  return True
 
 def BFS(self):
  """
  BFS获得最短路径保存到paths中
  :return:
  """
  # 4个方向,小写代表只是人移动,大写表示人推着箱子一起移动
  dirs = [[-1,0,'u','U'],[1,0,'d','D'],[0,1,'r','R'],[0,-1,'l','L']]
  # 把开始的状态进入队列(list模拟),状态包括字符串表示的当前状态、当前的路径、当前人的位置
  states = [[self.sta,'',self.px,self.py]]
  # 访问数组(dict模拟),访问过的状态(字符串)不再访问
  visi = {}
  visi[self.sta] = 1
 
  s_len = 1000
  while len(states)>0:
   sta, path, px, py = states[0]
   # 4状态的位置
   ppos = px*self.col + py
   states = states[1:]
   if len(path)>s_len:
    break
   # 保存最短路径到paths中
   if self.is_ok(sta):
    if self.len == -1 or len(path) == self.len:
     self.paths.append(path)
     self.len = len(path)
    continue
 
   for dir in dirs:
    cx, cy = px + dir[0], py + dir[1]
    # 4挨着的状态的位置
    pos = cx*self.col+cy
    nx, ny = px + 2*dir[0], py + 2*dir[1]
    # 4挨着挨着的状态的位置
    npos = nx*self.col+ny
    if not (nx>=0 and nx<self.col and ny>=0 and ny<self.col):
     continue
    # python中字符串不可更改,于是把字符串变成list更改状态后再转换为字符串
    if sta[pos] == '2' and sta[npos] == '0' and self.en[npos] != '1':
    # 人和箱子一起推动,sta中连着的状态为4 2 0,en中第三个不能为1。推完之后sta变为0 4 2
     digits = [int(x) for x in sta]
     digits[ppos],digits[pos],digits[npos] = 0,4,2
     new_sta = ''.join(str(x) for x in digits)
     if new_sta not in visi:
      visi[new_sta] = 1
      states.append([new_sta, path+dir[3], cx, cy])
    elif sta[pos] == '0' and self.en[pos] !='1':
    # 人动箱子不动,sta中连着的状态为4 0,en中第二个不能为1。
     digits = [int(x) for x in sta]
     digits[ppos], digits[pos] = 0, 4
     new_sta = ''.join(str(x) for x in digits)
     if new_sta not in visi:
      visi[new_sta] = 1
      states.append([new_sta, path + dir[2], cx, cy])
 
if __name__ == '__main__':
 f = open(level_file_path, encoding='utf-8')
 cnt = 0
 while(1):
  line = f.readline()
  line = line.strip('\n')
  if len(line)==0 :
   break
  gs = GameShortest(line)
 
"""
level_file.txt中内容:
1111111111111111111111100011111110221111111420111111111001111111300111111330011111111111111111111111
1111111111104000000110000200111001101011100100101110010010111001011001110030000111111111111111111111
1111111111111111111111111111111110311111140020001110230020111111311111111111111111111111111111111111
1111111111111111111111100011111110221111111013311111102301111110040111111111111111111111111111111111
1111111111111111111111111111111100000111112111001113030020111400100011111111111111111111111111111111
1111111111111111111111111111111110011111100000011111001220111140300311111111111111111111111111111111
1111111111110040001110000000111001110011110011001111020130111100002011111311111111111111111111111111
1111111111111111111111111111111100111111100320001110131210111000000411111111111111111111111111111111
1111111111111111111111111111111100000111100111011110002020111000133411111111111111111111111111111111
1111111111111111111111100111111110004111111101011111312100111132001011113000201111111111111111111111
1111111111111111111111000001111131103111110402011111001201111100100111111111111111111111111111111111
1111111111111111111111100001111113112011110234001111001000111100001111111111111111111111111111111111
1111111111111111111111111001111110204111111020011111300101111130000111111111111111111111111111111111
1111111111111111111111143001111100000111110010211111001203111111101011111110001111111111111111111111
1111111111111111111111111111111100001111110202111111033420111111130011111111111111111111111111111111
1111111111111111111111110001111100230111114032301111110120111111000111111111111111111111111111111111
1111111111111111111111110031111102010111110020011111031401111100001111111111111111111111111111111111
1111111111111111111111111104111113110011110330201111021200111100001111111111111111111111111111111111
1111111111111111111111000111111100330111110011211111100100111112000411111001111111111111111111111111
1111111111111111111111100001111103032111110024001111111010111111100011111111111111111111111111111111
每一关的最短路径:
['uurrDDDDuuuulldRurDDDrddLLrruLuuulldRurDDDrdL']
['drrRRurDDDDDrdLLL']
['rrdrUrrrdLLulDullldR']
['lluRRdrUllluuurrDDuulldRurD']
['urrrrdrruulullllDurrrrdrddllullLrrrdrruLLL']
['uurrrrDulllddrrRuulDrdL']
['drrdddrdLLLuLDlUUUluRRRRurDDD']
['uullLLddrrUdlllluuRurDrRddrruuLLL']
['lUlLLdlluururrrrDDrdLullldlluRRRRllluurrrrdD']
['ddrddLLulLdlUrrrdrruuluulldDuurrddrddllLLrruLL']
['luurrrdrdLLLrrrddlUruuulllldDrddlUUrrRdrU']
['ddlluluRuurrrDrddlluLrdrruLLddlluU']
['dddlluluuRDrruulDrdLLulDrDLurrrddlLL']
['drrdDrrddllUUUUruLdrDldR', 'drrdDrrddllUUUUrDldRuuuL']
['drruLLLuulldRurDurDD']
['urRdddrrUULLulldRururrD']
['uLrddlluluuRDrrruullDldRRdrUU']
['dddlUllllddrUUddrrUruLLrrruulDrdLL']
['llldlUUUluurDrrrDDrdLLLulUluRRlddrddlUUUluR']
['ulldRurDrrddllUUluurrDLLdrddrruuLrddlluU']
"""

更多关于python游戏的精彩文章请点击查看以下专题:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python中对list去重的多种方法
Sep 18 Python
PHP魔术方法__ISSET、__UNSET使用实例
Nov 25 Python
详解Django中的form库的使用
Jul 18 Python
浅谈python 四种数值类型(int,long,float,complex)
Jun 08 Python
python爬虫框架scrapy实现模拟登录操作示例
Aug 02 Python
Python中文件的写入读取以及附加文字方法
Jan 23 Python
Pyqt5如何让QMessageBox按钮显示中文示例代码
Apr 11 Python
python 实现将文件或文件夹用相对路径打包为 tar.gz 文件的方法
Jun 10 Python
Python Django简单实现session登录注销过程详解
Aug 06 Python
pytorch 利用lstm做mnist手写数字识别分类的实例
Jan 10 Python
Pycharm如何运行.py文件的方法步骤
Mar 03 Python
利用Matlab绘制各类特殊图形的实例代码
Jul 16 Python
详解python中的Turtle函数库
Nov 19 #Python
python绘制简单彩虹图
Nov 19 #Python
python微信好友数据分析详解
Nov 19 #Python
python生成九宫格图片
Nov 19 #Python
python实现简易动态时钟
Nov 19 #Python
python使用Turtle库绘制动态钟表
Nov 19 #Python
python+PyQT实现系统桌面时钟
Jun 16 #Python
You might like
收音机的保养
2021/03/01 无线电
浅析php插件 HTMLPurifier HTML解析器
2013/07/01 PHP
php缩小png图片不损失透明色的解决方法
2013/12/25 PHP
php实现按指定大小等比缩放生成上传图片缩略图的方法
2014/12/15 PHP
PHP获取ip对应地区和使用网络类型的方法
2015/03/11 PHP
php实现基于openssl的加密解密方法
2016/09/30 PHP
PHP7基于curl实现的上传图片功能
2018/05/11 PHP
thinkPHP框架实现的无限回复评论功能示例
2018/06/09 PHP
一些mootools的学习资源
2010/02/07 Javascript
JavaScript 继承使用分析
2011/05/12 Javascript
JSP跨iframe如何传递参数实现代码
2013/09/21 Javascript
js showModalDialog参数的使用详解
2014/01/07 Javascript
JS实现倒计时和文字滚动的效果实例
2014/10/29 Javascript
JavaScript的History API使搜索引擎抓取AJAX内容
2015/12/07 Javascript
JavaScript仿支付宝密码输入框
2015/12/29 Javascript
全面解析Bootstrap中tab(选项卡)的使用方法
2016/06/06 Javascript
jQuery自定义插件详解及实例代码
2016/12/29 Javascript
JavaScript中document.referrer的用法详解
2017/07/04 Javascript
vue2.x集成百度UEditor富文本编辑器的方法
2018/09/21 Javascript
微信小程序日历插件代码实例
2019/12/04 Javascript
微信小程序中data-key属性之数据传输(经验总结)
2020/08/22 Javascript
[01:21]DOTA2 新英雄 森海飞霞
2020/12/18 DOTA
Python实现的文本简单可逆加密算法示例
2017/05/18 Python
情人节快乐! python绘制漂亮玫瑰
2020/08/18 Python
Python实现去除图片中指定颜色的像素功能示例
2019/04/13 Python
使用Python制作简单的小程序IP查看器功能
2019/04/16 Python
利用纯CSS3实现文字向右循环闪过效果实例(可用于移动端)
2017/06/15 HTML / CSS
css3实现可拖动的魔方3d效果
2019/05/07 HTML / CSS
小学教师自我鉴定
2013/11/07 职场文书
车队司机自我鉴定
2014/03/02 职场文书
中学生社会实践活动总结
2014/07/03 职场文书
贫困证明模板(3篇)
2014/09/16 职场文书
党的群众路线教育实践活动心得体会(教师)
2014/10/31 职场文书
python scipy 稀疏矩阵的使用说明
2021/05/26 Python
单身狗福利?Python爬取某婚恋网征婚数据
2021/06/03 Python
分享MySQL常用 内核 Debug 几种常见方法
2022/03/17 MySQL