提前终止“随机漫步”计划

时间:2013-06-20 15:46:18

标签: c arrays

enter image description here

enter image description here

这是我对此问题的代码:

#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  enter image description here

可以在第一个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;

}

3 个答案:

答案 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;
}