拼图游戏常用算法
1、随机数组生成
//随机矩阵
/**
*
* @param {Object} arr 要混洗的范围
* @param {Object} count 得到数组的大小
*/
function getRandomArrayElements(arr, count) {
//拷贝所有数组元素到shuffled中
var shuffled = arr.slice(0),
i = arr.length,
min = i - count,
temp, index;
//如果i小于长度
while(i-- > min) {
//产生一个随机数,下标为取值范围为索引加1之间的数
index = Math.floor((i + 1) * Math.random());
//进行数据交换
temp = shuffled[index];
shuffled[index] = shuffled[i];
shuffled[i] = temp;
}
//返回交换后的数组
return shuffled.slice(min);
}
//函数测试
var puzzle = [1, 2, 3, 4, 5, 6, 7, 8, 0];
//数组混洗
var arr = getRandomArrayElements(puzzle,puzzle.length);
console.log(arr)
测试结果:
2、拼图可解计算
有两种方式可以判断拼图是否可解:
(1)判断整个序列是奇排列还是偶排列,再判断0的位置是奇位置还是偶位置,如果前两者的奇偶性相同则有解。
(2)序列里面排除空白块0,判断序列是奇排列还是偶排列。如果是偶排列,则可以完成。
(3)偶排列任意交换两个数形成奇排列,奇排列任意交换两个数形成偶排列。
什么是逆序?
当数列中较小的数字位置在较大数字的后方时,就是逆序。
逆序数:
例如:
1 2 3 5 4,逆序数有1对,54
5 4 3 2 1,逆序数有10对,54,53,52,51,43,42,41,32,31,21
//拼图的奇偶性
/**
*
* @param {Object} arr 拼图数组
* @param {Object} size 数组大小
*/
function CalcParity(arr, size) {
var count = 0;
//计算排列的奇偶性
for(var i = 0; i < size - 1; i++) {
for(var j = i + 1; j < size; j++) {
//找到0所在的位置
if(arr[i] > arr[j]) {
count++;
}
}
}
//排列奇偶性
console.log("逆序数为:" + count)
//计算0的位置
for(var i = 0; i < size; i++) {
//找出0所在的位置
if(arr[i] == 0) {
break;
}
}
console.log("0位置:" + i)
if(count % 2 != i % 2) //奇偶性不同则无解
{
//无解
console.log("无解")
return false;
} else {
console.log("可解")
return true;
}
}
//函数测试
var puzzle = [1, 2, 3, 4, 5, 6, 7, 8, 0]; //可解
//数组混淆
var arr = getRandomArrayElements(puzzle,puzzle.length);
CalcParity(arr, arr.length);
测试结果:
注:有解无解函数只可判定3X3,4x4无法判定。