骑士漫游问题的一个方法,设定每个放个的可访问性,对于每次访问,优先访问可访问性比较低的(比较难以到达的方格)。
这种方式可以保证在大多数情况的漫游是完全的漫游,却无法保证每一次都是完全漫游。
而且,这种方式只记录一种漫游方式,不会回溯,也就无法输出所有可能的漫游路径(如果要输出所有的漫游记录,需要回溯)
实现如下:
#include <stdio.h>
#include <stdlib.h>
#define ROW 8
#define COL 8
int horizon[ROW] = { 2, 1, -1, -2, -2, -1, 1, 2 },
vertical[COL] = {-1, -2, -2, -1, 1, 2, 2, 1};
int valid(int, int, int [][COL]);
void init(int[][COL]);
void print(int[][COL]);
void caculateAccess(int[][COL]);
int getMaxAccess(int[][COL]);
int main(){
int currentRow,// 当前访问的row
currentCol,//当前访问的column
moveType = 0, //移动类型 0-7
moveNum = 0,//移动编号 1-64
accessNum, //记录下一个移动的最小的access
finish = 0,//是否访问完毕
tryRow, //0-7种移动方式依次测试
tryCol,
minRow,//最小access的row
minCol,//最小access的col
minAccess,
board[ROW][COL] ,
access[ROW][COL] ;
srand(time(NULL));
init(board);//记录骑士漫游的路径
caculateAccess(access);
minAccess = getMaxAccess( access ) + 1;
print(access);
currentRow = rand() % ROW;
currentCol = rand() % COL;
board[ currentRow ][currentCol] = ++ moveNum;
/* 访问64步 */
while( !finish ){
accessNum = minAccess;
for( moveType = 0; moveType <= 7; moveType ++){
tryRow = currentRow + vertical[ moveType ];
tryCol = currentCol + horizon[ moveType ];
if( valid(tryRow, tryCol, board)){
if( access[tryRow][tryCol] < accessNum){
accessNum = access[tryRow][tryCol];
minRow = tryRow;
minCol = tryCol;
}
--access[ tryRow ][ tryCol ];//访问当前方格后,8个位置的access都要更改
}
}
/* no move anymore */
if(accessNum == minAccess){
finish = 1;
}else{
currentRow = minRow;
currentCol = minCol;
board[ currentRow ][currentCol] = ++ moveNum;
}
}
printf("---move board is:---\n");
print(board);
printf("---move Num is: %d\n",moveNum);
}
int valid(int row, int column, int a[][COL]){
return (row >= 0 && row <= (ROW - 1))
&&
(column >=0 && column <= (COL - 1))
&&
(a[row][column] == 0);
}
void init(int a[][COL]){
int i, j;
for(i = 0; i < ROW; i++){
for(j = 0; j < COL; j++){
a[i][j] = 0;
}
}
}
void print(int a[][COL]){
int i, j;
printf("---------------------------\n");
for(i = 0; i < ROW ; i++){
for(j = 0; j < COL; j++){
printf("%3d ",a[i][j]);
}
printf("\n");
}
printf("---------------------------\n");
}
void caculateAccess(int a[][COL]){
init(a);
int i , j, tryRow, tryCol, moveType;
for(i = 0; i < ROW; i++){
for(j = 0;j < COL;j++){
for( moveType = 0; moveType <=7; moveType ++){
tryRow = i + vertical[ moveType ];;
tryCol = j + horizon[ moveType ];
if(tryRow >=0 && tryRow < ROW && tryCol >=0 && tryCol < COL){
a[tryRow][tryCol] ++;
}
}
}
}
}
int getMaxAccess( int a[][COL] ){
int max = 0, i, j;
for(i = 0; i < ROW; i++){
for(j = 0; j < COL; j++){
if(max < a[i][j]){
max = a[i][j];
}
}
}
return max;
}