打印有变化规律的一组数字正方形。

尽量使用扩展性高的代码,图案如下:
/*
01--02--03--04--05--06--07--08
|
28--29--30--31--32--33--34 09
| | |
27 48--49--50--51--52 35 10
| | | | |
26 47 60--61--62 53 36 11
| | | | | | |
25 46 59 64--63 54 37 12
| | | | | |
24 45 58--57--56--55 38 13
| | | |
23 44--43--42--41--40--39 14
| |
22--21--20--19--18--17--16--15
//
01--02 06--07 15--16 28--29
/ / / / / / /
03 05 08 14 17 27 30 43
| / / / / / / / |
04 09 13 18 26 31 42 44
/ / / / / / /
10 12 19 25 32 41 45 54
| / / / / / / / |
11 20 24 33 40 46 53 55
/ / / / / / /
21 23 34 39 47 52 56 61
| / / / / / / / |
22 35 38 48 51 57 60 62
/ / / / / / /
36--37 49--50 58--59 63--64
//
01--02 04 07 11 16 22 29
/> / / / / / /
03 05 08 12 17 23 30 37
/> / / / / / /
06 09 13 18 24 31 38 44
/> / / / / / /
10 14 19 25 32 39 45 50
/> / / / / / /
15 20 26 33 40 46 51 55
/> / / / / / /
21 27 34 41 47 52 56 59
/> / / / / / /
28 35 42 48 53 57 60 62
/> /> /> /> /> /> /
36 43 49 54 58 61 63--64
//
01 09 23 35 45 53 59 63
/ / / / / / />
16 02 10 24 36 46 54 60
/ / / / / / />
29 17 03 11 25 37 47 55
/ / / / / / />
40 30 18 04 12 26 38 48
/ / / / / / />
49 41 31 19 05 13 27 39
/ / / / / / />
56 50 42 32 20 06 14 28
/ / / / / / />
61 57 51 43 33 21 07 15
/> /> /> /> /> /> />
64 62 58 52 44 34 22 08
//
64--63--62--61--60--59--58--57
|
37--38--39--40--41--42--43 56
| | |
36--35--34--33--32--31 44 55
| | |
17--18--19--20--21 30 45 54
| | | | |
16--15--14--13 22 29 46 53
| | | | |
05--06--07 12 23 28 47 52
| | | | | | |
04--03 08 11 24 27 48 51
| | | | | | |
01--02 09--10 25--26 49--50
//
01--02--03--04--05--06--07--08
|
16--15--14--13--12--11--10--09
|
17--18--19--20--21--22--23--24
|
32--31--30--29--28--27--26--25
|
33--34--35--36--37--38--39--40
|
48--47--46--45--44--43--42--41
|
49--50--51--52--53--54--55--56
|
64--63--62--61--60--59--58--57
*/

解决这个问题,我们可以想象成一个物体在正方形中移动
移动的方式有:
1、向一个方向一直移动直到碰到边缘或者碰到其他物体;
2、向一个方向移动一次就够了;
3、移动方向的优先级,比如优先往上移动,再向左移动;
4、探测方式移动,如果碰到其他物体就继续向同方向探测,直到有空位;
5、旋转试移动,优先级高的方向移动成功后就放弃优先级低的移动方向。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Text.RegularExpressions;
  5. namespace BoxGame
  6. {
  7.     class Program
  8.     {
  9.         /// <summary>
  10.         /// 方向
  11.         /// </summary>
  12.         public enum Direction
  13.         {
  14.             North,
  15.             South,
  16.             West,
  17.             East,
  18.             Southwest,
  19.             Southeast,
  20.             Northeast,
  21.             Northwest
  22.         }
  23.         /// <summary>
  24.         /// 移动指令
  25.         /// </summary>
  26.         public class MoveDictate
  27.         {
  28.             /// <summary>
  29.             /// 移动方向表,按优先排列顺序
  30.             /// </summary>
  31.             public List<Direction> directions = new List<Direction>();
  32.             /// <summary>
  33.             /// 是否跳出指令
  34.             /// </summary>
  35.             public bool isBreak;
  36.             /// <summary>
  37.             /// 是否为分析模式
  38.             /// </summary>
  39.             public bool isTry;
  40.             /// <summary>
  41.             /// 是否旋转模式
  42.             /// </summary>
  43.             public bool isEddy;
  44.             /// <summary>
  45.             /// 分析坐标
  46.             /// </summary>
  47.             public Point point;
  48.             /// <summary>
  49.             /// 最多界限
  50.             /// </summary>
  51.             public int max = int.MaxValue;
  52.             /// <summary>
  53.             /// 解析字符串
  54.             /// </summary>
  55.             /// <param name="s">字符串</param>
  56.             /// <returns>返回移动指令</returns>
  57.             public static MoveDictate Parse(string s)
  58.             {
  59.                 MoveDictate result = new MoveDictate();
  60.                 result.isBreak = s.IndexOf('跳') >= 0;
  61.                 result.isTry = s.IndexOf('探') >= 0;
  62.                 result.isEddy = s.IndexOf('旋') >= 0;
  63.                 Match m = Regex.Match(s, @"/[(?<x>.*?),(?<y>.*?)/]");
  64.                 if (m.Success)
  65.                 {
  66.                     int x = result.point.X;
  67.                     int y = result.point.Y;
  68.                     int.TryParse(m.Result("${x}"), out x);
  69.                     int.TryParse(m.Result("${y}"), out y);
  70.                     result.point = new Point(x, y);
  71.                 }
  72.                 foreach (char c in s)
  73.                 {
  74.                     int i = "↑↓←→↖↗↙↘".IndexOf(c);
  75.                     if (i >= 0)
  76.                         result.directions.Add((Direction)i);
  77.                 }
  78.                 return result;
  79.             }
  80.         }
  81.         /// <summary>
  82.         /// 盒子游戏
  83.         /// </summary>
  84.         public class BoxGame
  85.         {
  86.             /// <summary>
  87.             /// 边大小
  88.             /// </summary>
  89.             int size;
  90.             /// <summary>
  91.             /// 指令序号
  92.             /// </summary>
  93.             int dictate;
  94.             /// <summary>
  95.             /// 是否逆向填写
  96.             /// </summary>
  97.             bool isReverse;
  98.             /// <summary>
  99.             /// 当前坐标
  100.             /// </summary>
  101.             Point current = new Point(0, 0);
  102.             /// <summary>
  103.             /// 数字矩形
  104.             /// </summary>
  105.             int[,] numbers;
  106.             /// <summary>
  107.             /// 方向偏移
  108.             /// </summary>
  109.             Point[] offsets = new Point[]{
  110.                 new Point(0, -1),
  111.                 new Point(0, +1),
  112.                 new Point(-1, 0),
  113.                 new Point(+1, 0),
  114.                 new Point(-1, -1),
  115.                 new Point(+1, -1),
  116.                 new Point(-1, +1),
  117.                 new Point(+1, +1)};
  118.             /// <summary>
  119.             /// 移动指令集
  120.             /// </summary>
  121.             List<MoveDictate> moveDictates = new List<MoveDictate>();
  122.             /// <summary>
  123.             /// 移动
  124.             /// </summary>
  125.             /// <param name="dest">目标点</param>
  126.             /// <returns>返回移动是否成功</returns>
  127.             bool Move(MoveDictate moveDictate, ref Point dest)
  128.             {
  129.                 bool isBrack = false;
  130.                 do
  131.                 {
  132.                     isBrack = true;
  133.                     for (int i = 0; i < moveDictate.directions.Count; i++)
  134.                     {
  135.                         if (moveDictate.isEddy && i > moveDictate.max) break;
  136.                         int d = (int)moveDictate.directions[i];
  137.                         Point temp = moveDictate.isTry ? moveDictate.point : dest;
  138.                         temp.Offset(offsets[d].X, offsets[d].Y);
  139.                         if (Rectangle.FromLTRB(0, 0, size, size).Contains(temp))
  140.                         {
  141.                             if (numbers[temp.X, temp.Y] == 0)
  142.                             {
  143.                                 dest = temp;
  144.                                 if (moveDictate.isEddy) moveDictate.max = i;
  145.                                 return true;
  146.                             }
  147.                             if (moveDictate.isTry)
  148.                             {
  149.                                 moveDictate.point = temp;
  150.                                 isBrack = false;
  151.                                 break;
  152.                             }
  153.                         }
  154.                     }
  155.                 } while (!isBrack);
  156.                 return false;
  157.             }
  158.             /// <summary>
  159.             /// 播放
  160.             /// </summary>
  161.             /// <param name="size">宽度</param>
  162.             /// <param name="dictates">指令字符串</param>
  163.             public void Play(int size, string s)
  164.             {
  165.                 this.size = size;
  166.                 s = s.Replace("边", (size - 1).ToString());
  167.                 isReverse = s.IndexOf('逆') >= 0;
  168.                 MatchCollection mc = Regex.Matches(s, @"/{(?<dictate>.*?)/}");
  169.                 foreach (Match match in mc)
  170.                     moveDictates.Add(MoveDictate.Parse(match.Result("${dictate}")));
  171.                 Match m = Regex.Match(Regex.Replace(s, @"/{.*?/}"""), @"/[(?<x>.*?),(?<y>.*?)/]");
  172.                 if (m.Success)
  173.                 {
  174.                     int x = current.X;
  175.                     int y = current.Y;
  176.                     int.TryParse(m.Result("${x}"), out x);
  177.                     int.TryParse(m.Result("${y}"), out y);
  178.                     current = new Point(x, y);
  179.                 }
  180.                 numbers = new int[size, size];
  181.                 numbers[current.X, current.Y] = isReverse ? size * size : 1;
  182.                 for (int i = 2; i <= size * size; i++)
  183.                 {
  184.                     Point next = current;
  185.                     for (int j = 0; j < moveDictates.Count; j++)
  186.                     {
  187.                         if (Move(moveDictates[dictate], ref next))
  188.                         {
  189.                             if (moveDictates[dictate].isBreak)
  190.                             {
  191.                                 if (moveDictates[dictate].isEddy)
  192.                                     moveDictates[dictate].max = int.MaxValue;
  193.                                 dictate = (dictate + 1) % moveDictates.Count;
  194.                             }
  195.                             current = next;
  196.                             break;
  197.                         }
  198.                         else
  199.                         {
  200.                             if (moveDictates[dictate].isEddy)
  201.                                 moveDictates[dictate].max = int.MaxValue;
  202.                             dictate = (dictate + 1) % moveDictates.Count;
  203.                         }
  204.                     }
  205.                     numbers[current.X, current.Y] = isReverse ? size * size - i + 1 : i;
  206.                 }
  207.                 for (int j = 0; j < size; j++)
  208.                 {
  209.                     for (int i = 0; i < size; i++)
  210.                         Console.Write("{0}{1:D2}", i > 0 ? " " : "", numbers[i, j]);
  211.                     Console.WriteLine();
  212.                     Console.WriteLine();
  213.                 }
  214.             }
  215.         }
  216.         static void Main(string[] args)
  217.         {
  218.             int n = 8;
  219.             new BoxGame().Play(n, "{→↓}{←↑}"); // 1号图
  220.             Console.WriteLine("-------");
  221.             new BoxGame().Play(n, "{→跳}{↙}{↓跳}{↗}"); // 2号图
  222.             Console.WriteLine("-------"); 
  223.             new BoxGame().Play(n, "{↙}{[0,0]→↓探跳}"); // 3号图
  224.             Console.WriteLine("-------"); 
  225.             new BoxGame().Play(n, "{↘}{[0,0]→探跳}{↘}{[0,0]↓探跳}"); // 4号图
  226.             Console.WriteLine("-------"); 
  227.             new BoxGame().Play(n, "[0,边]{→跳}{←↑旋}{↑跳}{↓→旋}"); // 5号图
  228.             Console.WriteLine("-------"); 
  229.             new BoxGame().Play(n, "{→←↓}"); // 6号图
  230.             Console.ReadKey();
  231.         }
  232.     }
  233. }
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值