一个乱序的拼图不一定能复原的。 要保证他能复原,需要在打乱的程序中做些文章。//cx,cy是这个拼图要分割成多少块。 //把cx-1,cy-1处的图块挖去,产生一个空地,用kx,ky记录这个空地. int kx = cx - 1; int ky = cy - 1; //至少要打乱i这么多次.10这个数随意,但必须是偶数. int i = cx * cy * 10 + cx + cy; //这个循环条件比较诡异,一会再解释. while (i > 0 || i + x + y & 1) { x = Dice(cx);//Dice是产生0 ~ cx-1的随机数 y = Dice(cy); //都相同,那就是没换,继续Dice. if (x == kx && y == ky) continue; //把x,y处的图块挪到kx,ky z[kx][ky] = z[x][y]; //这样x,y处就空了. kx = x; ky = y; //还要打乱多少次? i--; }如果循环条件是简单的while (i > 0)那这个拼图不一定能复原. 这个循环运行i次以后,i>0这个条件不满足了,循环是否继续下去要看i + x + y & 1 什麽原理我自己都忘记了,我想想.稍等
i + x + y = cx * cy * 10 + cx + cy - 交换过的次数 + x + y 其中cx * cy * 10不影响表达式的奇偶性,可以忽略.就成了 cx + x + cy + y - 交换过的次数有一个理论,叫做黑白格理论(好像是?). 把一个拼图,放到类似国际象棋盘的格子里,并按照图块所在的格子的颜色,给图块做标记. 统计黑白错乱的图块,黑色的在白格,白色的在黑格之和,这个数的奇偶性就是拼图能否复原的关键. 玩拼图时,每次移动一块,整个盘面的奇偶性就会改变.再次移动,奇偶性变回来. 如果交换的次数是偶数,并且奇偶性最终没有改变,这样的盘面是合理的. 如果交换的次数是奇数,并且奇偶性最终有改变,这样的盘面也是合理的. 反之就是不合理的. 我的循环继续的条件就是奇偶性为偶.这个表达式省略了很多东西,可以推导出来的. 怎么推导的比较麻烦,有兴趣的自己研究去.
循序渐进,可以先使用tc实现,然后在vc中实现(非mfc),然后使用mfc实现
一步一个脚印
要保证他能复原,需要在打乱的程序中做些文章。//cx,cy是这个拼图要分割成多少块。
//把cx-1,cy-1处的图块挖去,产生一个空地,用kx,ky记录这个空地.
int kx = cx - 1;
int ky = cy - 1;
//至少要打乱i这么多次.10这个数随意,但必须是偶数.
int i = cx * cy * 10 + cx + cy;
//这个循环条件比较诡异,一会再解释.
while (i > 0 || i + x + y & 1)
{
x = Dice(cx);//Dice是产生0 ~ cx-1的随机数
y = Dice(cy);
//都相同,那就是没换,继续Dice.
if (x == kx && y == ky)
continue;
//把x,y处的图块挪到kx,ky
z[kx][ky] = z[x][y];
//这样x,y处就空了.
kx = x;
ky = y;
//还要打乱多少次?
i--;
}如果循环条件是简单的while (i > 0)那这个拼图不一定能复原.
这个循环运行i次以后,i>0这个条件不满足了,循环是否继续下去要看i + x + y & 1
什麽原理我自己都忘记了,我想想.稍等
其中cx * cy * 10不影响表达式的奇偶性,可以忽略.就成了
cx + x + cy + y - 交换过的次数有一个理论,叫做黑白格理论(好像是?).
把一个拼图,放到类似国际象棋盘的格子里,并按照图块所在的格子的颜色,给图块做标记.
统计黑白错乱的图块,黑色的在白格,白色的在黑格之和,这个数的奇偶性就是拼图能否复原的关键.
玩拼图时,每次移动一块,整个盘面的奇偶性就会改变.再次移动,奇偶性变回来.
如果交换的次数是偶数,并且奇偶性最终没有改变,这样的盘面是合理的.
如果交换的次数是奇数,并且奇偶性最终有改变,这样的盘面也是合理的.
反之就是不合理的.
我的循环继续的条件就是奇偶性为偶.这个表达式省略了很多东西,可以推导出来的.
怎么推导的比较麻烦,有兴趣的自己研究去.