我正在开发一个Word Search益智游戏,我正在努力用字母生成网格。目前,我能够生成网格,但性能非常慢(对于正常使用而言太慢,在生成网格之前可能需要30-40秒)。
为了使单词适合网格,我使用的是递归函数,它试图拟合给定列表中的最后一个单词,然后是它之前的单词,等等,如果它不合适,则回溯到前一个单词并改变它的位置,然后再试一次。我想我做得不对,因为它一直来回走。
我尝试使用加权概率作为方向,因此生成是以“更聪明”的方式进行的,但我还没有得到任何结果。
我的问题: 如何优化此代码以使其更高效和可靠?我接受任何建议,即使它让我做了很多改变(例如,如果有一个迭代解决方案而不是递归的解决方案,或者我在函数中没有正确推理......)。
这是功能:
function tryWord(grid, wordList, index, gridLength){
var valid = false;
var clear = false;
if(index==(wordList.length-1)){
/* Clear grid for current index */
for(var j=0; j<gridLength.x; j++){
grid[index][j] = [];
for (var k=0; k<gridLength.y; k++){
grid[index][j][k] = '';
}
}
var nbIterations = 0;
// Try current word
while(valid == false){
// Impossible to resolve this grid
if(nbIterations>500){
return false;
}
nbIterations++;
var initX = Math.floor(Math.random() * gridLength.x); // x coord of first letter of the word
var initY = Math.floor(Math.random() * gridLength.y); // y coord of first letter of the word
var direction = Math.floor(Math.random() * 8); // direction of the word (0=top-left; 1=top; 2=top-right; 3=right; 4=bottom-right; 5=bottom; 6=bottom-left; 7=left)
valid = checkValidWord(wordList[index].length, initX, initY, direction, gridLength);
}
clear = checkClearWord(wordList[index], initX, initY, direction, grid[index]);
if(!clear){
return false;
}
var x = initX;
var y = initY;
for(var j=0; j<wordList[index].length; j++){
grid[index][x][y] = wordList[index].charAt(j);
switch(direction){
case 0:
x--;
y--;
break;
case 1:
y--;
break;
case 2:
x++;
y--;
break;
case 3:
x++;
break;
case 4:
x++;
y++;
break;
case 5:
y++;
break;
case 6:
x--;
y++;
break;
case 7:
x--;
break;
default:
break;
}
}
return grid;
}
else if(index!=(wordList.length-1)){
var emptyGrid = true;
for(var p=0; p<grid[index].length; p++){
for(var q=0; q<grid[index][p].length; q++){
if(grid[index][p][q]!=''){
emptyGrid = false;
}
}
}
if(emptyGrid || $scope.nbIterations>50){
$scope.nbIterations=0;
grid = tryWord(grid, wordList, index+1, gridLength);
}
/* Prepare grid for current index */
grid[index] = grid[index+1];
if(grid!=false){
// Try current word
while(valid == false){
var initX = Math.floor(Math.random() * gridLength.x); // x coord of first letter of the word
var initY = Math.floor(Math.random() * gridLength.y); // y coord of first letter of the word
var direction = Math.floor(Math.random() * 8); // direction of the word (0=top-left; 1=top; 2=top-right; 3=right; 4=bottom-right; 5=bottom; 6=bottom-left; 7=left)
valid = checkValidWord(wordList[index].length, initX, initY, direction, gridLength); // Check that word fits in the grid
}
clear = checkClearWord(wordList[index], initX, initY, direction, grid[index]);
// If word is obstructed by other words
if(!clear){
$scope.nbIterations++;
return tryWord(grid, wordList, index, gridLength); // Try again
}
else{
var x = initX;
var y = initY;
for(var j=0; j<wordList[index].length; j++){
grid[index][x][y] = wordList[index].charAt(j);
switch(direction){
case 0:
x--;
y--;
break;
case 1:
y--;
break;
case 2:
x++;
y--;
break;
case 3:
x++;
break;
case 4:
x++;
y++;
break;
case 5:
y++;
break;
case 6:
x--;
y++;
break;
case 7:
x--;
break;
default:
break;
}
}
return grid;
}
}
else{
return false;
}
}
}
该功能的参数:
grid
:在开头,只是一个填充''字符串的10x11x11数组。wordList
:要放入网格的一系列单词index
:0第一次调用函数时,它用于检查我们在wordList中的深度gridLength
:一个数组:{x:11,y:11},给出网格长度关于该功能的更多准确性:
checkValidWord
检查到达给定方向的给定单词是否适合具有给定大小的网格。返回true或false。checkClearWord
检查进入给定方向的给定单词是否适合网格中的其他单词(无阻塞等)。返回true或false。tryWord
应该输出大小为[wordList.length; 11; 11]的三维数组。然后我使用grid [0]作为游戏的2维网格。