这是我对此问题的代码:
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define N 10
int main()
{
int i,move,move_count,row,col;
char ch = 'A',a[N][N];
for(row = 0; row < N; row++)
for(col = 0; col < N; col++)
a[row][col] = '.';
srand(time(NULL));
row = rand()%10;
col = rand()%10;
a[row][col] = ch;
for(i = 0; i < 26; i++)
{
move = rand() % 4;
move_count = 0;
if(move == 0 && move_count < 4) //down
{
if(row+1 < 10 && a[row+1][col] == '.')
{
ch = ch + 1;
a[row+1][col] = ch;
row += 1;
}
else
{
move = 2;
move_count++;
}
}
if(move == 2 && move_count < 4) //up
{
if(row-1 > 0 && a[row - 1][col] == '.')
{
ch = ch + 1;
a[row-1][col] = ch;
row -= 1;
}
else
{
move = 1;
move_count++;
}
}
if(move == 1 && move_count < 4) //left
{
if(col-1 > 0 && a[row][col-1] =='.')
{
ch = ch + 1;
a[row][col-1] = ch;
col -= 1;
}
else
{
move = 3;
move_count++;
}
}
if(move == 3 && move_count < 4) //right
{
if(col+1 < 10 && a[row][col+1] == '.')
{
ch = ch + 1;
a[row][col+1] = ch;
col += 1;
}
else
{
move = 0;
move_count++;
}
}
if(move_count == 4)
break;
}
for(row = 0; row < N; row++)
{
for(col = 0; col < N; col++)
printf("%c",a[row][col]);
printf("\n");
}
getch();
}
在执行时,有时它会在没有违反条件(b)
的情况下提前终止。以下是一些提前终止的屏幕截图;
可以在第一个o / p中轻松看到,它在V
处终止,而在第二个终点在Y
,但在这两种情况下都可以进一步移动。
知道怎么摆脱这个吗?
EDITED
经过无尽的努力,我已经纠正了这段代码(并且没有使用内循环!)。感谢 Thomas Padron-McCarthy
&amp; Ilmari Karonen
为teir提供建议
编辑代码:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define N 10
int main()
{
int i,move,move_count,row,col,seed=4;
char ch = 'A',a[N][N];
for(row = 0; row < N; row++)
for(col = 0; col < N; col++)
a[row][col] = '.';
srand((unsigned)seed);
//srand(time(NULL));
row = 0;//rand()%10;
col = 0;//rand()%10;
a[row][col] = ch;
for(i = 0; i < 26;)
{
move = rand() % 4;
if(move == 0) //down
{
if(row+1 < N && a[row+1][col] == '.')
{
a[++row][col] = ++ch;
i++;
}
}
else if(move == 2) //up
{
if(row-1 >= 0 && a[row - 1][col] == '.')
{
a[--row][col] = ++ch;
i++;
}
}
else if(move == 1) //left
{
if(col-1 >= 0 && a[row][col-1] =='.')
{
a[row][--col] = ++ch;
i++;
}
}
else if(move == 3) //right
{
if(col+1 < N && a[row][col+1] == '.')
{
a[row][++col] = ++ch;
i++;
}
}
if((a[row+1][col]!='.'||row==9) && (a[row - 1][col]!='.'||row==0) &&
(a[row][col-1]!='.'||col==0 )&& (a[row][col+1]!='.'||col==9) || i==25)
break;
}
for(row = 0; row < N; row++)
{
for(col = 0; col < N; col++)
printf("%c ",a[row][col]);
printf("\n");
}
return 0;
}
答案 0 :(得分:3)
您for(i = 0; i < 26; i++)
没有内部循环。
这意味着您将有26次尝试而不是26次移动。
你需要一个内部循环,它会尝试进入随机方向,只有在检查了所有4个方向时才会退出。
注意:计算尝试次数(move_count
)不起作用,因为rand
可以多次为您提供相同的方向。
答案 1 :(得分:1)
您的问题是,如果原始方向被阻挡,您正在递增移动方向,但递增过程最多只能达到3;之后它不会回转到0。因此,如果您选择的原始随机方向为2,并且方向2和3都被阻止,则您永远不会尝试方向0和1.
两个明显的解决方案(也保证了有效方向的均匀随机选择,与您的方法不同,偏向于数字上的第一个非阻塞方向)是:
首先检查至少有一个有效的移动方向,如果是,请不断选择随机方向,直到找到有效方向,或
首先列出所有有效的移动方向,然后从中选择一个随机元素。
第二种方法稍微(但并不多)实现起来更复杂,但它也应该更快,至少在已经填充了许多相邻方块的情况下。
答案 2 :(得分:1)
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define N 10
int main(void){
int i, row, col;
char ch = 'A',a[N][N];
for(row = 0; row < N; row++)
for(col = 0; col < N; col++)
a[row][col] = '.';
srand(time(NULL));
row = rand()%10;
col = rand()%10;
a[row][col] = ch;
for(i = 1; i < 26; i++){//already put 'A'
enum { down, left, up, right };//0,1,2,3
int move[] = {0,1,2,3};//Candidate in the moving direction
int move_count, n;
n = rand() % 4;//start direction
move_count = 0;
while(move_count<4){
int gone = 0;
n = (n + move_count) % 4;
switch(move[n]){
case down:
if(row+1 < 10 && a[row+1][col] == '.'){
a[++row][col] = ++ch;
gone = 1;//I was able to go forward.
}
break;
case up:
if(row-1 > 0 && a[row - 1][col] == '.'){
a[--row][col] = ++ch;
gone = 1;
}
break;
case left:
if(col-1 > 0 && a[row][col-1] =='.'){
a[row][--col] = ++ch;
gone = 1;
}
break;
case right:
if(col+1 < 10 && a[row][col+1] == '.'){
a[row][++col] = ++ch;
gone = 1;
}
break;
}
if(gone) break;
++move_count;//Number of times that I tried for a destination
}
if(move_count == 4){
printf("No longer able to move\n");//need backtrack
break;//give up!
}
}
for(row = 0; row < N; row++){
for(col = 0; col < N; col++)
printf("%c",a[row][col]);
printf("\n");
}
return 0;
}