飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 1637|回复: 0

[小试锋芒申请加入]CrackMe V2.3 设计思路+源码 (数独)

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

    [LV.3]偶尔看看II

    发表于 2009-12-30 10:59:18 | 显示全部楼层 |阅读模式
    CM2.3里面用到的一个数学模型就是数独游戏,简单介绍下数独游戏吧,O(∩_∩)O~

    数独的历史
            数独前身为“九宫格”,最早起源于中国。数千年前,我们的祖先就发明了洛书,其特点较之现在的数独更为复杂,要求纵向、横向、斜向上的三个数字之和等于15,而非简单的九个数字不能重复。儒家典籍《易经》中的“九宫图”也源于此,故称“洛书九宫图”。而“九宫”之名也因《易经》在中华文化发展史上的重要地位而保存、沿用至今。


    数独游戏规则
      在9阶方阵中,包含了81个小格(九列九行),其中又再分成九个小正方形(称为宫),每宫有九小格。
      游戏刚开始时,盘面上有些小格已经填了数字(称为初盘),游戏者要在空白的小格中填入1到9的数字,使得最后每行、每列、每宫都不出现重复的数字,而且每一个游戏都只有一个唯一的解答(称为终盘)。



    我的设计思路其实很简单:
    1.构造一个9*9的全局数组,当然前提是你必须确保这个的数组有解:

    1. var
    2.   MyArr : array[1..9,1..9] of Byte =    ((0,0,9,0,6,0,0,0,0),
    3.                                          (3,5,0,0,0,0,0,0,6),
    4.                                          (7,6,2,0,3,8,0,0,0),
    5.                                          (0,0,0,0,0,2,6,9,0),
    6.                                          (4,3,0,0,9,0,0,8,5),
    7.                                          (0,2,6,3,0,0,0,0,0),
    8.                                          (0,0,0,9,5,0,4,3,1),
    9.                                          (6,0,0,0,0,0,0,2,9),
    10.                                          (0,0,0,0,2,0,5,0,0));
    复制代码
    其中0表示要填入的数字,非0表示初盘。

    2.通过用户名和注册码的简单运算得到即将要填入的数字,按顺序依次填入到数组中:

    1. //用户名不足50位就一直重复为止
    2.   while LenUN < 50 do
    3.   begin
    4.     UserName := UserName + UserName;
    5.     LenUN := Length(UserName);
    6.   end;
    7.   UserName := LeftStr(UserName, 50);
    8.   //下面是计算出要填进去的50个数字
    9.   for i:= 1 to 50 do
    10.   begin
    11.     tb[i] := abs(ord(UserName[i])-ord(RegCode[i]));
    12.   end;
    13.   //下面是把50个数字按顺序填入到数独里
    14.   k := 1;
    15.   for i:=1 to 9 do
    16.   begin
    17.     for j:= 1 to 9 do
    18.     begin
    19.       if  MyArr[i][j] = 0 then
    20.       begin
    21.         MyArr[i][j] := TB[k];
    22.         k := k+1;
    23.       end;
    24.     end;
    25.   end;
    复制代码
    3.检测填入的数字是否是1~9,每行、每列、每宫是否出现重复的数字。如:

    1. //下面的循环是检测每一行的数字是不是1-9,并且是不重复的
    2.   for i := 1 to 9 do
    3.   begin
    4.     a1:= 1; a2:=1; a3:=1; a4:=1; a5:=1; a6:=1; a7:=1; a8:=1; a9:=1;
    5.     for j:=1 to 9 do
    6.     begin
    7.       case MyArr[i][j] of
    8.        1: a1:= a1-1;
    9.        2: a2:= a2-1;
    10.        3: a3:= a3-1;
    11.        4: a4:= a4-1;
    12.        5: a5:= a5-1;
    13.        6: a6:= a6-1;
    14.        7: a7:= a7-1;
    15.        8: a8:= a8-1;
    16.        9: a9:= a9-1;
    17.       else
    18.        reg := reg+1;
    19.       end;
    20.     end;
    21.     if (a1 <> 0 )  then  reg1 := reg1+1;
    22.     if (a2 <> 0 )  then  reg1 := reg1+1;
    23.     if (a3 <> 0 )  then  reg1 := reg1+1;
    24.     if (a4 <> 0 )  then  reg1 := reg1+1;
    25.     if (a5 <> 0 )  then  reg1 := reg1+1;
    26.     if (a6 <> 0 )  then  reg1 := reg1+1;
    27.     if (a7 <> 0 )  then  reg1 := reg1+1;
    28.     if (a8 <> 0 )  then  reg1 := reg1+1;
    29.     if (a9 <> 0 )  then  reg1 := reg1+1;
    30.   end;
    31.   
    复制代码
    4.如果全部满足条件,则成功,否则失败。

    本帖子中包含更多资源

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

    x
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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