使用 C# 开发智能手机软件:推箱子(三)

这是“ 使用 C# 开发智能手机软件:推箱子 ”系列文章的第三篇。在这篇文章中,介绍 Common/Block.cs 源程序文件。
  1  namespace  Skyiv.Ben.PushBox.Common
  2  {
  3     ///   <summary>
  4     ///  基本单元格: 地 槽 墙 砖 箱子 工人
  5     ///   </summary>
  6     static   class  Block
  7    {
  8       public   const   byte  Land  =   0 //  地
  9       public   const   byte  Slot  =   1 //  槽
 10       public   const   byte  Wall  =   2 //  墙
 11       public   const   byte  Brick  =   3 //  砖: 等同于墙,一般放在墙的外围
 12       public   const   byte  Box0  =   4 //  箱子放在地上
 13       public   const   byte  Box1  =   5 //  箱子放在槽上
 14       public   const   byte  Man0  =   6 //  工人站在地上
 15       public   const   byte  Man1  =   7 //  工人站在槽上
 16 
 17       const   string  mask  =   " -+#%xX() " //  (*.bxa)文件用,依次代表以上各项
 18 
 19       public   static   string  GetPenName( byte  block)
 20      {
 21         return   " 地槽墙砖箱箱人人 " [block  &   0x07 ].ToString();
 22      }
 23 
 24       public   static   char  GetChar( ushort  block)
 25      {
 26         return  mask[block  &   0x07 ];
 27      }
 28 
 29       public   static   byte  GetByte( char  block)
 30      {
 31         return  ( byte )mask.IndexOf(block);
 32      }
 33 
 34       public   static   bool  IsOk( ushort  block)
 35      {
 36         return  block  <=  Man1;
 37      }
 38 
 39       public   static   void  CleanAllMark( ushort [,] bb)
 40      {
 41         for  ( int  i  =   0 ; i  <  bb.GetLength( 0 ); i ++ )
 42           for  ( int  j  =   0 ; j  <  bb.GetLength( 1 ); j ++ )
 43            bb[i, j]  &=   0x07 ;
 44      }
 45 
 46       public   static   void  Mark( ref   ushort  block,  int  value)
 47      {
 48        block  |=  ( ushort )(value  <<   3 );
 49      }
 50 
 51       public   static   int  Value( ushort  block)
 52      {
 53         return  block  >>   3 ;
 54      }
 55 
 56       public   static   void  Update( ref   ushort  block,  byte  pen)
 57      {
 58         if  (IsSlot(block)  &&  pen  ==  Block.Man0) pen  =  Block.Man1;
 59         if  (IsSlot(block)  &&  pen  ==  Block.Box0) pen  =  Block.Box1;
 60        block  =  pen;
 61      }
 62 
 63       public   static   void  ManIn( ref   ushort  block)
 64      {
 65        block  +=  (Man0  -  Land);
 66      }
 67 
 68       public   static   void  ManOut( ref   ushort  block)
 69      {
 70        block  -=  (Man0  -  Land);
 71      }
 72 
 73       public   static   void  BoxIn( ref   ushort  block)
 74      {
 75        block  +=  (Box0  -  Land);
 76      }
 77 
 78       public   static   void  BoxOut( ref   ushort  block)
 79      {
 80        block  -=  (Box0  -  Land);
 81      }
 82 
 83       public   static   bool  IsSlot( ushort  block)
 84      {
 85         return  block  ==  Slot  ||  block  ==  Box1  ||  block  ==  Man1;
 86      }
 87 
 88       public   static   bool  IsBlank( ushort  block)
 89      {
 90         return  block  ==  Land  ||  block  ==  Slot;
 91      }
 92 
 93       public   static   bool  IsBox( ushort  block)
 94      {
 95         return  block  ==  Box0  ||  block  ==  Box1;
 96      }
 97 
 98       public   static   bool  IsMan( ushort  block)
 99      {
100         return  block  ==  Man0  ||  block  ==  Man1;
101      }
102    }
103  }
104 
    静态类 Block 用来表示基本单元格: 空地、槽(箱子最终要存放的目的地)、墙、砖(在本程序中等同于“墙”,一般放在墙的外围,使图形看起来漂亮些)、箱子、工人。其中“箱子”和“工人”都可以位于“空地”或“槽”上,所以总共有八种状态,用 0 到 7 表示,总共只需要三个二进位,可以放入一个字节中。在数据文件(*.bxb)中,每个基本单元格就是用一个字节储存的,这在以后介绍的 Common/DataFile.cs 源程序文件中会看到。 但是为什么静态类 Block 的大多数方法的参数都是 ushort 类型呢? 这是为了寻找工人最短移动路线算法的需要,看了下一篇介绍 Common/FindPath.cs 源程序文件的文章就会明白了。
    这个类还是比较简单的,现简要说明如下:
    GetPenName 方法返回在设计关卡时所用画笔的名称。
    Update 方法用来在设计关卡时更新地图中的基本单元格。
    GetChar 方法返回将数据文件(data/*.bxb)导出为文本文件(text/*.bxa)所用的字符。
    GetByte 方法返回将文本文件(text/*.bxa)导入为数据文件(data/*.bxb)所用的字节。
    IsOk 方法判断表示基本单元格的字节是否合法,也用在数据导入时。
    Mark 方法在寻找工人最短移动路线算法中用来标记已经搜索过的基本单元格。
    CleanAllMark 方法在上述算法结束时用来清除地图中的所有基本单元格的标记。
    Value 方法返回上述算法搜索过程中所作的标记。
    ManIn、ManOut、BoxIn、BoxOut 方法用来更新推箱子过程中地图各基本单元格的状态。
    IsSlot、IsBlank、IsBox、IsMan 方法用来判断各基本单元格的类型。
     补充:寻找工人最短移动路线的算法已经作了改进,地图使用 byte 存储就行了,所以静态类 Block 中的所有“ushort”都要修改为“byte”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我是一个语言模型AI,无法提供源代码。但我可以给您提供一些基本思路和伪代码,希望能对您有所帮助。 1. 地图的表示 我们可以使用二维数组来表示地图,其中0代表空地,1代表墙,2代表箱子,3代表目标点,4代表人物。例如: int[,] map = new int[5, 5]{ {1,1,1,1,1}, {1,0,0,3,1}, {1,0,2,3,1}, {1,0,0,0,1}, {1,1,1,1,1} }; 2. 移动算法 在进行移动前,我们需要先进行判断,判断人物是否可以向某个方向移动。例如向上移动,我们需要判断上方是否是空地或者目标点,如果是,则可以移动,否则不能移动。如果移动后人物与箱子重叠,则需要再次进行判断,判断箱子是否可以向相同方向移动。移动箱子的条件与移动人物的条件类似。 3. AI算法 我们可以使用搜索算法来实现AI。例如,我们可以使用深度优先搜索算法来搜索所有可能的移动方案,找到最短的移动路径。在搜索的过程中,我们需要记录每个状态的步数和路径,以便找到最短路径。 伪代码如下: function DFS(state, depth, path): if state is win_state: return path if depth > max_depth: return None for direction in directions: new_state = move(state, direction) if new_state is not None and new_state not in visited: visited.add(new_state) new_path = path + [direction] result = DFS(new_state, depth + 1, new_path) if result is not None: return result visited.remove(new_state) 以上是一些基本思路和伪代码,具体实现还需要根据具体情况进行调整和优化。希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值