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']
"""

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

(0)

相关推荐

  • python使用pygame框架实现推箱子游戏

    本代码来源于 <Python和Pygame游戏开发指南>中的 Star Pusher 游戏,供大家参考,具体内容如下 # Star Pusher (a Sokoban clone) # By Al Sweigart al@inventwithpython.com # http://inventwithpython.com/pygame # Released under a "Simplified BSD" license import random, sys, copy,

  • python实现推箱子游戏

    本文实例为大家分享了python实现推箱子游戏的具体代码,供大家参考,具体内容如下 题目描述: 最短路径为: uurrDDDDuuuulldRurDDDrddLLrruLuuulldRurDDDrdL u表示向上,d表示向下,l表示向左,r表示向右. 大写表示人推着箱子一起动,小写表示人自己走. 代码用BFS实现.状态要分推着箱子一起走和人单独走,这两种状态转移是不同的. 由于代码中注释较详细,这里不过多解释. 代码: # -*- coding: utf-8 -*- # @Time : 2017

  • Python使用tkinter模块实现推箱子游戏

    前段时间用C语言做了个字符版的推箱子,着实是比较简陋.正好最近用到了Python,然后想着用Python做一个图形界面的推箱子.这回可没有C那么简单,首先Python的图形界面我是没怎么用过,在网上找了一大堆教材,最后选择了tkinter,没什么特别的原因,只是因为网上说的多. 接下来就来和大家分享一下,主要分享两点,第一就是这个程序的实现过程,第二点就是我在编写过程中的一些思考. 一.介绍 开发语言:Python 3.7 开发工具:PyCharm 2019.2.4 日期:2019年10月2日

  • Java实现推箱子游戏

    本文实例为大家分享了Java实现推箱子游戏的具体代码,供大家参考,具体内容如下 package Test1; //用于调用Test2包 import Test2.*; import java.awt.*; import javax.swing.*; public class APP extends JFrame{ public static void main(String[] args) { // TODO Auto-generated method stub APP a = new APP(

  • Java实现简单推箱子游戏

    本文实例为大家分享了Java实现简单推箱子游戏的具体代码,供大家参考,具体内容如下 *编写一个简易的推箱子游戏,使用10*8的二维字符数据表示游戏画面,H表示墙壁; &表示玩家角色: o表示箱子,表示目的地.玩家可以通过输入a.d.w. s字符控制角色 移动,当箱子推到目的地时显示游戏结束,运行结果如图所示. package test; import java.util.Random; import java.util.Scanner; public class test3 { public s

  • C++基于easyx图形库实现推箱子游戏

    本文实例为大家分享了C++实现推箱子游戏的具体代码,供大家参考,具体内容如下 头文件: #include<stdio.h> #include<stdlib.h> //#include<Windows.h> #include<conio.h> #include<graphics.h> #include<stdbool.h> //播放音乐需要的头文件 #include <mmsystem.h> #pragma comment(

  • JavaScript编写推箱子游戏

    推箱子游戏是老游戏了, 网上有各种各样的版本, 说下推箱子游戏的简单实现,以及我找到的一些参考视频和实例: 如下是效果图: 这个拖箱子游戏做了移动端的适配, 我使用了zepto的touch模块, 通过手指滑动屏幕就可以控制乌龟走不同的方向: 因为推箱子这个游戏比较简单, 直接用了过程式的方式写代码, 模块也就是两个View 和 Model, 剩下就是用户的事件Controller, 用户每一次按下键盘的方向键都会改变数据模型的数据,然后重新生成游戏的静态html, 然后用innerHTML方式插

  • 用C语言编写推箱子游戏

    本文实例为大家分享了C语言推箱子游戏的具体实现代码,供大家参考,具体内容如下 #include <stdio.h> #include <stdlib.h> #include<string.h> #include <conio.h> //行和列 #define ROW 10 #define COL 11 /* run this program using the console pauser or add your own getch, system(&quo

  • C语言推箱子游戏实现代码

    推箱子游戏的运行规则:在街道上上小人推动箱子移动,直到把箱子移动到目的地. 思路分析: 小人及箱子的移动就是小人或者箱子和路的交换: 1 定义二维字符数组,存储地图 2 显示地图,提示游戏玩法 3 记录小人及箱子位置,并定义字符变量接收用户输入方向 4 循环判断语句 1).小人的下一步是否为路,如果为路,则移动并记录小人新位置信息 2).小人的下一步如果不是路,在判断是否为箱子,如果是箱子,在判断箱子的下一个位置是否是路,如果是路,则移动箱子和小人 3). 刷新地图 4) .判断箱子的位置,如果

  • C语言实现简单推箱子游戏

    使用C语言实现超简单的推箱子游戏,供大家参考,具体内容如下/p> 感谢您打开了这篇文章,下面我将讲述一下推箱子是如何实现的. 另外附赠适配该程序简单好用 专属推箱子地图编辑器 让您在16 * 16大地图的条件下也能轻松编辑地图. 链接:地图编辑器 本程序在没有检测到地图文件的情况下也能独自运行!代码中储存了推箱子游戏第一关的标准地图,让您在没有地图文件的情况下也能熟悉整个程序的流程! 当然,拥有地图文件会也会获得更好的游戏体验,请自行编辑. 废话不多说! 下面进入技术环节: C语言版 多功能推箱

  • C语言实现推箱子游戏的地图编辑器

    推箱子地图编辑器,供大家参考,具体内容如下 由于我在写推箱子的时候苦于没有地图可以试验程序运行效果,而且去搜了好长时间都没有找到一个储存16*16地图版本的推箱子关卡数据信息的文件. 于是想到了写了一个地图编辑器用来自己设计地图的想法. 原本以为这个伟大的创意只有我才想的出来,结果搜索后才发现还有很多人有着与我相同的想法. 但,其他人写的编辑器大部分都不是C语言版本的,而这一个是C语言版本的. 另外说明一下,该编辑器的想法完全是我个人想法写出来的,不敢保证编辑习惯符合别人的习惯. 但本着,能够实

随机推荐