【问题标题】:Random walk on 10x10 Array10x10 阵列上的随机游走
【发布时间】:2011-07-29 08:59:30
【问题描述】:

我在找出解决这个问题的算法时遇到了问题,尝试了几天没有成功,这是我试图获得的图片:

http://i.stack.imgur.com/X70nX.png

这是我的代码尝试了许多不同的解决方案,但总是卡在同一点:(对不起混合语言,重要的部分是英文)

ps 我不应该使用函数来解决这个问题,只有循环和数组。

编辑 经过多次修复后,它可以行走,但很少崩溃 有什么想法吗?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void){

char box[10][10];
int i,j;
int move,row,col;
char letter='A';
srand(time(NULL)); 

printf("\n\tSTART\n\n");

for(i=0;i < 10 ;i++)/* righe */
{
 for(j=0;j < 10;j++) /* colonne */
 {
  box[i][j] = '.'; /* assegno . a tutti gli elementi dell array */
  if(j == 9)
   printf("%c%c\n", box[i][j]); /* giustifico ogni 10 elementi dell array j(0-9) */
   else 
   printf("%c%c", box[i][j]);
  }
}


/* LETS START */ 

printf("\n\n    Inizia il gioco\n\n");

/* random place to start */

row = rand() % 9;
col = rand() % 9;
box[row][col]= 'A';


while(letter <= 'Z')
{
 if(box[row+1][col] == '.' || box[row-1][col] == '.' || box[row][col+1] == '.' || box[row][col-1] == '.' )
 {
 move=rand() % 4;
 switch(move){
              case 0: /* Going UP */
                    if((row != 0) && (box[row-1][col] == '.'))
                    {
                            box[row-1][col]=++letter;
                            box[row--][col];
                    }else{
                          move=rand() % 4;
                          }
              case 1:/* Going Down */
                   if((row != 9) && (box[row+1][col] == '.'))
                   {
                           box[row+1][col]=++letter;
                           box[row++][col];
                   }else{
                         move=rand() % 4;
                         }
              case 2: /*Going Left */
                   if((col != 0) && (box[row][col-1] == '.'))
                   {
                           box[row][col-1]=++letter;
                           box[row][col--];
                   }else{
                         move=rand() % 4;
                         }
              case 3: /* Going Right */
                   if((col != 9) && (box[row][col+1] == '.') )
                   {
                           box[row][col+1]=++letter;
                           box[row][col++];
                   }else{
                         move=rand() % 4;
                         }
              }
 }else{
        printf("\n\nBloccato a %c\n\n", letter);
        break;
 }
}


 /* FINE */

for(i=0;i<10;i++)/* righe */
{
 for(j=0;j<10;j++) /* colonne */
 {
   if(j == 9)
     printf("%c%c\n", box[i][j]); /* giustifico ogni 10 elementi dell array j(0-9) */
    else 
     printf("%c%c", box[i][j]);
 }  
}
return 0;
}

【问题讨论】:

  • 卡在哪里了?你看到什么样的输出?
  • 不知道有一个 :) 抱歉,对于那些关心的人来说,这不是一项任务,只是测试我解决问题的能力非常低 :)
  • 我得到了这样的东西imgur.com/39TP5我的助行器不会走路:/
  • 您使用= 的测试(在ifs 中)是错误的。比较是用== 完成的。

标签: c loops multidimensional-array


【解决方案1】:

您需要在循环内更新rowcol。 否则,您将始终尝试从“A”的位置步行。

...一旦所有 4 个方向都被填满,你就会陷入无限循环

. . . . . . .乙。 . . E A C。 . . D. .

即使您在循环内更新rowcol(并纠正== 错误),您也必须处理一个问题:假设第一个点(“A”)是左上角并且下一个随机方向是东、南、南、西和北。 ... 怎么办? :)

甲乙。 F C 。 ED。 . . .

【讨论】:

  • 循环终止正常,但如果一个字母应该去的第一个空格不可用,则不会使用该字母。
  • 循环因您的测试错误而终止:if (box[row][col] == '.') ... 注意==,而不是=
  • 我怎么错过了 == 我读了很多遍,看起来很正常,真丢人。我也在试图弄清楚如何在循环中更新行和列,但我不知道在哪里看
  • @pmg 它应该终止,但我试图弄清楚如何写这个:D 我绝对没有经验,我对这个问题发疯了
  • 类似box[row][++col]=letter; ?
【解决方案2】:

当您发现无法朝某个方向前进时,“重新滚动”随机数不是一个好主意,因为如果运气不好,您会得到相同的数字两次(甚至 3 次或 4 次或更多次)-所以即使你生成了 4 个随机数并且它们都失败了,这并不意味着你被卡住了。

您可以通过生成一个数字并从它开始尝试所有 4 个可能的方向来解决此问题:

如果随机数生成器返回 0:检查 0、1、2、3

如果随机数生成器返回 1:检查 1, 2, 3, 0

如果随机数生成器返回 2:检查 2, 3, 0, 1

如果随机数生成器返回 3:检查 3, 0, 1, 2

由以下代码实现:

desired_move = rand();
success = 0;
for (i = 0; i < 4 && !success; ++i)
{
    move = (desired_move + i) % 4;
    switch (move)
    {
    case 0: // Go up
        if (row > 0 && box[row - 1][col] == '.')
        {
            row = row - 1;
            success = 1;
        }
        break;
    case 1: // Go down
        ...
    }
}
if (!success) // Tried all 4 directions but failed! You are stuck!
{
    goto START_OVER; // or whatever else
}

请注意,这个算法不是很随机:如果你不能上去,你下楼的机会比向右或向左要大。如果要修复它,可以选择 4 个方向的随机排列,而不是依次检查方向:

const int permutation_table[24][4] = {
    {0, 1, 2, 3},
    {0, 1, 3, 2},
    {0, 2, 1, 3},
    ...
    {3, 2, 1, 0}
};
index = rand() % 24;
for (i = 0; i < 4; ++i)
{
    move = permutation_table[index][i];
    switch (move) {
    ... // As above
    }
}

【讨论】:

  • 感谢您的建议,我将在重新开始时尝试实施这种解决方案:) 并尝试在明天之前完成它
【解决方案3】:

当你在 for 循环中时。

  1. 画出可能的方向

int direction = rand()%4;
  1. 如果绘制的方向无效(不在数组中或不是“.”),则检查所有可能的方向

int i=-1;
while( ++i < 4 )
{
    switch(direction) 
    {
        case 0:
            if( row-1 >= 0 && box[row-1][col] == '.' ) {
                --row;
                i = -1;    
            }
            break;
        case 1:
            if( col+1 < 10 && box[row][col+1] == '.' ) {
                ++col;
                i = -1;    
            }
            break;
        case 2:
            if( row+1 < 10 && box[row+1][col] == '.' ) {
                ++row;
                i = -1;
            }
            break;
        case 3:
            if( col-1 >= 0 && box[row][col-1] == '.' ) {
                --col;
                i = -1;
            }
            break;
    }

    if( i != -1 ) {
        direction = (direction+1)%4;
    }
    else {
        break;
    }
}
  1. 如果没有有效的移动,则结束 for 循环>

if( i == 4 ) {
    break;
}
  1. 否则向表格单元格写入一个字母并更新行/列位置。

box[row][col] = letter;

而且...这就是我猜的全部。这是贪心算法,所以你不需要任何优化(至少我没有看到任何运动要求。

【讨论】:

  • 感谢您的帮助,用类似的方法更新了代码,但正如我在上面所写的,算法现在可以正常工作,但很少崩溃,而且它什么时候不会开始步行任何猜测?
  • “崩溃”是什么意思?程序没有结束,返回错误或内存错误(例如分段错误?)
  • 程序一直运行到“walk”算法,然后停止等待输入并闪烁“_”不知道这意味着什么错误,这里很新:)
【解决方案4】:

如果您尝试朝着无效的方向前进,那么您似乎正在打破您的 switch 语句,但无论如何您都会增加您的计数器。如果发生这种情况,请尝试检查另一个随机方向。

【讨论】:

  • ok 在 Else 中添加了另一个 move=rand() % 4; 但仍在寻找一个条件来检查周围元素是否被采用
  • 删除else{ move=rand() % 4; } 块和break; 每个案例。检查this link,例如“失败案例”
【解决方案5】:

它到底在哪里坏了?

从我一眼就能看出,你有机会It_that_walks从女巫那里得到位置,它不能去任何地方:

A B C D .
. I J E .
. H G F .

J 之后在哪里?

不需要&amp;&amp; (box[row][col-1]= '.')

总之,错了(赋值而不是比较),应该是:&amp;&amp; (box[row][col-1]== '.')(但你不需要全部一起)

【讨论】:

  • 好的,删除了&amp;&amp; (box[row][col-1]== '.'),因为它没有必要,但我不知道如何检查周围的元素是否被占用
猜你喜欢
  • 1970-01-01
  • 2021-02-09
  • 2021-06-21
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 2015-06-16
相关资源
最近更新 更多