飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 7011|回复: 13

[原创] CrackMe V2.6 设计思路+源码

[复制链接]
  • TA的每日心情
    慵懒
    2019-4-26 10:19
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    发表于 2009-12-31 09:53:11 | 显示全部楼层 |阅读模式
    CrackMe V2.6的注册算法源自文曲星上的一个小游戏《华容道》。先来简单的介绍下这个游戏吧O(∩_∩)O~。

            华容道游戏取自著名的三国故事,曹操在赤壁大战中被刘备和孙权的“苦肉计”、“火烧连营”打败,**退逃到华容道,又遇上诸葛亮的伏兵,关羽为了报答曹操对他的恩情,明逼实让,终于帮助曹操逃出了华容道。
      游戏就是依照“曹瞒兵败走华容,正与关公狭路逢。只为当初恩义重,放开金锁走蛟龙”这一故事情节,通过移动各个棋子,帮助曹操从初始位置移到棋盘最下方中部,从出口逃走。不允许跨越棋子,还要设法用最少的步数把曹操移到出口。曹操逃出华容道的最大障碍是关羽,关羽立马华容道,一夫当关,万夫莫开。
           
            成功的条件:
           

    1.
    首先定义一个全变数组变量Block,摆好位置,进行初始化,最终成功的条件应该是曹操跑出,也即4个9在数组的位置Block[4][2],Block[4][3],Block[5][2],Block5][3]。我这里为了简单,自己定义了一个初始化的局面,大家也可以由用户名和注册码进行运算后得出一个开局,这样就避免了开局的单一性。
    1. var
    2.   //初始化华容道
    3.   //0,1,2,3分别代表兵,卒,勇,丁
    4.   //4,5,6,7分别代表张飞,赵云,马超,黄忠,8代表关羽,9代表曹操 ,10代表空格子
    5.   Block : array[1..5,1..4] of Integer =  ((0,9,9,1),
    6.                                           (2,9,9,3),
    7.                                           (4,8,8,5),
    8.                                           (4,6,7,5),
    9.                                          (10,6,7,10));
    10.                                          
    复制代码
    2.
    下面就是每个人物的移动了,先确定移动的方向:


    3.
    游戏的设置都好了后,下面就应该是设计让人物开始移动了,怎么移动呢?移动有两个要素:一是谁移动,即对象,二是移动的方向。我们可以让用户名和注册码来决定移动的人物和移动的方向。
    1. procedure TForm1.Button1Click(Sender: TObject);
    2. var
    3.   UserName    : string;
    4.   RegCode     : string;
    5.   DirectionSN : string;   //移动方向序列
    6.   BlockSN     : string;   //移动的格子序列
    7.   strTemp     : string;   //临时字符串
    8.   LenUN, i    : Integer;
    9. begin
    10.   UserName := Edit1.Text;
    11.   RegCode  := Edit2.Text;
    12.   LenUN    := Length(UserName);
    13.   if (UserName <> '') and (RegCode <> '') then
    14.   begin
    15.     //取出注册码中的前68位
    16.     while LenUN < 98 do
    17.     begin
    18.       UserName := UserName + UserName;
    19.       LenUN := Length(UserName);
    20.     end;
    21.     UserName := LeftStr(UserName, 98);
    22.     //得到移动序列
    23.     strTemp := '';
    24.     for i := 1 to 98 do
    25.     begin
    26.       strTemp := strTemp + IntToStr(Abs(byte(UserName[i]) - byte(RegCode[i]))) ;
    27.     end;
    28.     //得到移动的格子序列
    29.     BlockSN := '';
    30.     for i := 0 to 48 do
    31.     begin
    32.       BlockSN := BlockSN + strTemp[2*i+1];
    33.     end;
    34.     //得到移动方向序列
    35.     DirectionSN := '';
    36.     for i := 1 to 49 do
    37.     begin
    38.       DirectionSN := DirectionSN + strTemp[2*i];
    39.     end;
    40.     //游戏开始
    41.     for i := 1 to 49 do
    42.     begin
    43.       MoveBlock(StrToInt(BlockSN[i]), StrToInt(DirectionSN[i]));
    44.     end;
    45.     if (Block[4][2]= Block[4][3]) and (Block[5][2]= Block[4][3]) and (Block[5][3]= Block[4][3]) and (Block[4][2] = 9)  then
    46.     begin
    47.       try
    48.         i := i div reg;
    49.       except
    50.         MessageBox(0,'注册成功!','提示',0);
    51.       end;
    52.       strTemp := IntToStr(reg) + IntToStr(i);
    53.     end;
    54.   end;
    55.   
    复制代码
    我们作为CM的编写者,必须要知道这个游戏的解决方案是什么,也就是必须要知道每一步该怎么走,我这里简单起见,强制了走法,必须是49步走完游戏,否则就挂了,每一步都是用一个函数MoveBlock来实现。走完49步后,就要判断是不是曹操逃跑了,也即(Block[4][2]= Block[4][3]) and (Block[5][2]= Block[4][3]) and (Block[5][3]= Block[4][3]) and (Block[4][2] = 9)。
      
    4.我们来看下MoveBlock函数的具体实现过程:
    1. //移动格子,参数BlockN是要移动的数字,Direction是移动的方向
    2. //0,1,2,3分别代表
    3. //0:↑
    4. //1:→
    5. //2:↓
    6. //3:←
    7. procedure MoveBlock(BlockN : Integer; Direction : Integer);
    8. var
    9.   x,y,x1,x2,y1,y2,x3,y3,x4,y4,i,j : Integer;
    10. label
    11.   lb1;
    12. begin
    13.   x := 0;
    14.   y := 0;
    15.   ////在矩阵中找到要移动的格子的位置x,y
    16.   for i := 1 to 5 do
    17.   begin
    18.     for j := 1 to 4  do
    19.     begin
    20.       if Block[i][j] = BlockN then
    21.       begin
    22.         x := j;
    23.         y := i;
    24.         goto lb1;
    25.       end;
    26.     end;
    27.   end;
    28.   lb1:
    29.   try
    30.     case BlockN of
    31.       0..3 :  //选中的格子是兵,卒,勇,丁的其中一个
    32.       begin
    33.         case Direction of
    34.           0 :
    35.             begin
    36.               x1 := x;   y1 := y-1;
    37.             end;
    38.           1 :
    39.             begin
    40.               x1 := x+1; y1 := y;
    41.             end;
    42.           2 :
    43.             begin
    44.               x1 := x;   y1 := y+1;
    45.             end;
    46.           3 :
    47.             begin
    48.               x1 := x-1; y1 := y;
    49.             end;
    50.         else
    51.           reg := reg + 1;
    52.         end;
    53.         //判断下即将移动的位置是不是空的,是空的才能移,否则就挂!
    54.         if Block[y1][x1] <> 10 then
    55.           reg := reg + 1
    56.         else
    57.         begin
    58.           Block[y][x] := 10;  //原来的位置就变成空格子了
    59.           Block[y1][x1] := BlockN;

    60.         end;
    61.       end;

    62.       4..7 :  //选中的格子是张飞,赵云,马超,黄忠的其中一个
    63.       begin
    64.         case Direction of
    65.           0:
    66.             begin
    67.               x1 := x;
    68.               x2 := x;
    69.               y1 := y-1;
    70.               y2 := y1+1;
    71.               if Block[y1][x1] <> 10 then
    72.                 reg := reg+1;
    73.             end;
    74.           1:
    75.             begin
    76.               x1 := x+1;
    77.               x2 := x+1;
    78.               y1 := y;
    79.               y2 := y+1;
    80.               if (Block[y1][x1] <> 10) and (Block[y2][x2] <> 10)then
    81.                 reg := reg+1;
    82.             end;
    83.           2:
    84.             begin
    85.               x1 := x;
    86.               x2 := x;
    87.               y1 := y+2;
    88.               y2 := y1-1;
    89.               if Block[y1][x1] <> 10 then
    90.                 reg := reg+1;
    91.             end;
    92.           3:
    93.             begin
    94.               x1 := x-1;
    95.               x2 := x-1;
    96.               y1 := y;
    97.               y2 := y+1;
    98.               if (Block[y1][x1] <> 10) and (Block[y2][x2] <> 10)then
    99.                 reg := reg+1;
    100.             end;
    101.         else
    102.           reg := reg+1;
    103.         end;
    104.         Block[y][x]   := 10;
    105.         Block[y+1][x]  := 10;
    106.         Block[y1][x1] := BlockN;
    107.         Block[y2][x2] := BlockN;
    108.       end;

    109.       8 :  //选中的格子是关羽
    110.       begin
    111.         case Direction of
    112.           0:
    113.             begin
    114.               x1 := x;
    115.               x2 := x1+1;
    116.               y1 := y-1;
    117.               y2 := y1;
    118.               if (Block[y1][x1] <> 10) and (Block[y2][x2] <> 10)then
    119.                 reg := reg+1;
    120.             end;
    121.           1:
    122.             begin
    123.               x1 := x+2;
    124.               x2 := x1-1;
    125.               y1 := y;
    126.               y2 := y1;
    127.               if Block[y1][x1] <> 10 then
    128.                 reg := reg+1;
    129.             end;
    130.           2:
    131.             begin
    132.               x1 := x;
    133.               x2 := x1+1;
    134.               y1 := y+1;
    135.               y2 := y1;
    136.               if (Block[y1][x1] <> 10) and (Block[y2][x2] <> 10)then
    137.                 reg := reg+1;
    138.             end;
    139.           3:
    140.             begin
    141.               x1 := x-1;
    142.               x2 := x1+1;
    143.               y1 := y;
    144.               y2 := y1;
    145.               if Block[y1][x1] <> 10 then
    146.                 reg := reg+1;
    147.             end
    148.         else
    149.           reg := reg+1;
    150.         end;
    151.         Block[y][x] := 10;
    152.         Block[y][x+1]:= 10;
    153.         Block[y1][x1] := BlockN;
    154.         Block[y2][x2] := BlockN;
    155.       end;
    156.       9 :  //选中的格子是曹操
    157.       begin
    158.         case Direction of
    159.           0:
    160.             begin
    161.               x1 := x;
    162.               x2 := x1+1;
    163.               x3 := x1;
    164.               x4 := x3+1;
    165.               y1 := y-1;
    166.               y2 := y1;
    167.               y3 := y1+1;
    168.               y4 := y3;
    169.               if (Block[y1][x1] <> 10) and (Block[y2][x2] <> 10)then
    170.                 reg := reg+1;
    171.             end;
    172.           1:
    173.             begin
    174.               x1 := x+1;
    175.               x2 := x1+1;
    176.               x3 := x1;
    177.               x4 := x3+1;
    178.               y1 := y;
    179.               y2 := y1;
    180.               y3 := y1+1;
    181.               y4 := y3;
    182.               if (Block[y2][x2] <> 10) and (Block[y4][x4] <> 10)then
    183.                 reg := reg+1;
    184.             end;
    185.           2:
    186.             begin
    187.               x1 := x;
    188.               x2 := x1+1;
    189.               x3 := x1;
    190.               x4 := x3+1;
    191.               y1 := y+1;
    192.               y2 := y1;
    193.               y3 := y1+1;
    194.               y4 := y3;
    195.               if (Block[y3][x3] <> 10) and (Block[y4][x4] <> 10)then
    196.                 reg := reg+1;
    197.             end;
    198.           3:
    199.             begin
    200.               x1 := x-1;
    201.               x2 := x1+1;
    202.               x3 := x1;
    203.               x4 := x3+1;
    204.               y1 := y;
    205.               y2 := y1;
    206.               y3 := y1+1;
    207.               y4 := y3;
    208.               if (Block[y1][x1] <> 10) and (Block[y3][x3] <> 10)then
    209.                 reg := reg+1;
    210.             end
    211.         else
    212.           reg := reg+1;
    213.         end;
    214.         Block[y][x] := 10;
    215.         Block[y][x+1] := 10;
    216.         Block[y+1][x]:= 10;
    217.         Block[y+1][x+1] := 10;
    218.         Block[y1][x1] := BlockN;
    219.         Block[y2][x2] := BlockN;
    220.         Block[y3][x3] := BlockN;
    221.         Block[y4][x4] := BlockN;
    222.       end;

    223.       10 : //选中格子是空格子
    224.       begin
    225.         reg := reg + 1;
    226.       end;
    227.     end;
    228.   except
    229.     MessageBox(0,'请重新启动程序!','提示',0);
    230.     ExitProcess(0);
    231.   end;
    232. end;
    复制代码
    简单解释下其中的思路,首先遍历数组元素,发现要移动的数字,那么就定位出该格子的位置x,y。由于游戏里面的人物占用的格子的数目是不一样的,导致了人物在移动的时候处理也会不同,其次,选中人物后,根据移动方向来确定该怎么移动,里面涉及到临界问题的处理,比方说这个人物在周边的时候,不能移动到整个游戏格局的外面去,再比方说右边已经有人占着在,就不能再往右边移动了。我在处理的时候偷了个懒,我不管是不是有人站着也不管是不是移到外面去了,统统认为是异常发生了,那么我就可以采用异常处理机制来处理,设置一个变量reg,初始化为0,如果移动到外面或移动到有人的位置,reg则加1,最后将reg作为除数,除数为0的时候才弹出正确的注册成功提示,否则就失败。另外还有一点要注意的是坐标问题,x,y分别是横坐标和纵坐标,而i,j是数组的行和列,很容易就对应错了。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?加入我们

    x

    评分

    参与人数 1威望 +80 飘云币 +80 收起 理由
    Nisy + 80 + 80 PYG有你更精彩!

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2020-7-16 11:27
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2009-12-31 10:00:47 | 显示全部楼层
    /:good

    太强大 了
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-12-31 10:24:21 | 显示全部楼层
    /:good 写得真不错啊,大侠求合体~
    PYG19周年生日快乐!
  • TA的每日心情

    2017-7-19 15:45
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2009-12-31 10:34:49 | 显示全部楼层
    /:good 学习
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2015-8-23 23:49
  • 签到天数: 27 天

    [LV.4]偶尔看看III

    发表于 2009-12-31 11:30:31 | 显示全部楼层
    强悍的锋芒兄弟!/:09
    捉放曹,呵呵!
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-12-31 15:56:46 | 显示全部楼层
    锋芒兄强啊!
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-12-31 16:01:15 | 显示全部楼层
    写得很好 , 赞一个 /:good
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2010-1-1 05:18:25 | 显示全部楼层
    请教:对于任意的用户名,是否一定有解(有注册码,能生成keygen)?
    PYG19周年生日快乐!
  • TA的每日心情
    慵懒
    2019-4-26 10:19
  • 签到天数: 14 天

    [LV.3]偶尔看看II

     楼主| 发表于 2010-1-1 09:12:17 | 显示全部楼层
    楼上的兄弟们,我是菜鸟,哪是什么大侠/:018
    原帖由 齐东野人 于 2010-1-1 05:18 发表
    请教:对于任意的用户名,是否一定有解(有注册码,能生成keygen)?

    有的,因为强制了走法和步数,当然你也可以用用户名和注册码来随即产生一个游戏局面,这样会更好~
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2010-1-1 13:41:55 | 显示全部楼层
    无语,只能膜拜了
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表