ICODING-实验三-随机步法

题目:

随机步法(Random Walk)

编写程序,生成一种贯穿10×10字符数组(初始时全为字符’.')的“随机步法”。程序必须随机地从一个元素“走到”另一个元素,每次都向上、向下、向左或向右移动一个元素位置。已访问过的元素按访问顺序用字母A到Z进行标记。

下面是一个输出示例:

A . . . . . . . . .
B C D . . . . . . .
. F E . . . . . . .
H G . . . . . . . .
I . . . . . . . . .
J . . . . . . . Z .
K . . R S T U V Y .
L M P Q . . . W X .
. N O . . . . . . .
利用srand函数和rand函数产生随机数,然后查看次数除以4的余数。余数一共有4种可能的值(0、1、2和3),指示下一次移动的4种可能方向。在执行移动之前,需要检查两项内容:一是不能走到数组外面,二是不能走到已有字母标记的位置。只要一个条件不满足,就得尝试换一个方向移动。如果4个方向都堵住了,程序就必须终止了。下面是提前结束的一个示例:

A B G H I . . . . .
. C F O J K . . . .
. D E N M L . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
因为Y的4个方向都堵住了,所以没有地方可以放置下一步的Z了。

先放代码

/* 随机步法 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <string.h>

//全局变量,存储二位字符数组
char map[10][10];

//判断是否越界,越界返回true
bool isOutOfBound(int x, int y)
{
    if(x < 0 || x > 9 || y < 0 || y > 9) return true;
    else return false;
}

//判断这一步位置是否已经有字母,有则返回true
bool isPut(int x, int y)
{
    if(map[x][y] != '.') return true;
    else return false;
}

int main()
{
    //设置随机数种子
    srand((unsigned int)time(NULL));

    //初始化地图(10×10)字符数组
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0;j < 10; j++)
        {
            map[i][j] = '.';
        }
    }

    //记录当前该填入的是哪个字母
    char c = 'A';
    //设置起始位置并填入A;设置空置位判断下一步是否可以填入字母
    int x = 0, y = 0;
    int new_x = x, new_y = y;
    map[x][y] = c++;
    //记录当前位置四个方向的可行性 flag为4时证明四个方向均无法通过
    int flag = 0;
    //记录当前位置的四个方向是否已经访问过 1表示已经访问过
    int visited[4];
    memset(visited, 0, sizeof(visited));


    
    while(c <= 'Z' && flag < 4)
    {
        //生成随机数代表移动方向 0向上 1向右 2向下 3向左
        int num = rand() % 4;
        switch (num)
        {
        case 0:
            if(visited[0] == 1) continue;
            visited[0] = 1;
            new_y--;
            break;
        
        case 1:
            if(visited[1] == 1) continue;
            visited[1] = 1;
            new_x++;
            break;

        case 2:
            if(visited[2] == 1) continue;
            visited[2] = 1;
            new_y++;
            break;

        case 3:
            if(visited[3] == 1) continue;
            visited[3] = 1;
            new_x--;
            break;
        }

        flag++;
        //判断是否可以填入字母
        if(isOutOfBound(new_x, new_y) || isPut(new_x, new_y))
        {
            //不能填入则复原x,y
            new_x = x;
            new_y = y;
            continue;
        }

        x = new_x;
        y = new_y;
        map[x][y] = c++;
        flag = 0;
        memset(visited, 0, sizeof(visited));
    }

    //循环结束,打印数组
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 10; j++)
        {
            printf("%c", map[i][j]);
        }
        printf("\n");
    }
    return 0;
}

代码用全局变量二维数组存储信息,用isOutOfBound和IsPut函数判断下一步位置是否可以放置字母。rand()函数可以以固定种子生成随机数,为了实现真正的随机数,用当前时间为种子,用srand()函数改变种子即可。

开始前初始化map数组,之后从(0, 0)位置开始随机前进。用new_x和new_y两个变量临时记录下一步的位置,便于当下一步位置无法放置字母时进行位置回退。若下一步位置不合理,则返回switch case重新生成随机数再进行尝试。这里一定要重新生成随机数而非令num = (num + 1) % 4,否则就不是真正的随机步法!! 但重新尝试仍有可能走到原先的方向,故用visited数组记录当前位置的四个方向是否被访问过。

每次成功访问,用flag进行记录。初始值为0,当flag为4时证明四个方向均已经访问过,即路被堵死,此时结束循环并打印数组。所以每次成功访问要记得把flag重新置0。同时visited数组也要清零。

循环结束后打印数组即可。

答案仅供参考,不要盲目copy哦~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值