编写程序,生成一种贯穿10×10字符数组(初始时全为字符'.')的“随机步法”。程序必须随机地从一个元素 “走到”另一个元素,每次都向上、向下、向左或向右移动一个元素位置。已访问过的元素按访问顺序用字母A~Z进行标记。下面是一个输出示例:
提示:利用srand函数和rand函数(见程序deal.c)产生随机数,然后查看此数除以4的余数。余数一共有4种可能的值(0、1、2和3),指示下一次移动的4种可能方向。在执行移动操作之前,需要检查两个条件:一是不能走到数组外面,二是不能走到已有字母标记的位置。只要有一个条件不满足,就得尝试换一个方向移动。如果4个方向都堵住了,程序就必须终止了。
#include <stdio.h> // 指令
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
char chess[10][10] = {{".........."},{".........."},{".........."},{".........."},{".........."},{".........."},{".........."},{".........."},{".........."},{".........."},};
const char alphabet[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
int check[4] = {0};
int random = 4, x = 0, y = 0, m, n, sum = 0;
srand((unsigned) time(NULL));
random = rand() % 4;
for (size_t i = 0; i < 100; i++)
{
printf("%d %d \n", x, y);
if (i == 0)
{
chess[x][y] = alphabet[i % 26];
continue;
}
do
{
// 必须要在前面赋值,此时赋值说明对应random无效
if (random < 4)
{
check[random] = 1;
}
do
{
m = x;
n = y;
// 必须要在前面赋值,此时赋值说明对应random无效
if (random < 4)
{
check[random] = 1;
}
// 产生初始值 0 1 2 3
random = rand() % 4;
if (random == 0)
{
m = m - 1;
} else if (random == 1) {
n = n - 1;
} else if (random == 2) {
m = m + 1;
} else if (random == 3) {
n = n + 1;
}
} while (m < 0 || m > 9 || n < 0 || n >9);
for (size_t i = 0; i < 4; i++)
{
printf("this check %d \n", check[i]);
sum = sum + check[i];
}
// printf("%d this sum\n", sum);
// 如果四个方向都不能移动则break,跳出当前循环
if (sum == 4) break;
// 初始化
sum = 0;
// 若为点则说明无字母,可以继续赋值,若不为点,则有只母,继续找位置
} while (chess[m][n] != '.');
// printf("%d this sum\n", sum);
if (sum == 4) break;
// 只有在确定进行了移动时才赋值
x = m;
y = n;
// 初始化为 0
for (size_t i = 0; i < 4; i++)
{
check[i] = 0;
}
// sum和random使用完毕,进行初始化,此处和上面的sum初始化都是必须的,因为break会导致前面的初始化无效
sum = 0;
random = 4;
// 取出对应的字母
chess[x][y] = alphabet[i % 26];
}
for (size_t i = 0; i < 10; i++)
{
for (size_t a = 0; a < 10; a++)
{
// 对小写字母转化为大写并打印
putchar(toupper(chess[i][a]));
}
printf("\n");
}
}