老鼠走迷宫

/* 老鼠走迷宫 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "sl.h"(见基于链表的堆栈实现)
/* 空间字符 */
#define SPACE_MOUSE   '*' /* 老鼠 */
#define SPACE_WAY     ' ' /* 通路 */
#define SPACE_WALL    '|' /* 墙壁 */
#define SPACE_PASS    '.' /* 足迹 */
#define SPACE_IMPASSE 'X' /* 死路 */
/* 行进方向 */
#define DIR_RIGHT 0 /* 向右 */
#define DIR_DOWN  1 /* 向下 */
#define DIR_LEFT  2 /* 向左 */
#define DIR_UP    3 /* 向上 */
/* 老鼠字符 */
const char* g_mouse = ">V<^";
/* 老鼠 */
typedef struct Mouse {
	int   x;     /* 水平坐标 */
	int   y;     /* 垂直坐标 */
	int   dir;   /* 行进方向 */
	int   total; /* 总步数 */
	int   valid; /* 有效步 */
	STACK brain; /* 大脑 */
}	MOUSE;
/* 老鼠初始化 */
void mouse_init (MOUSE* mouse, int x, int y,
	int dir) {
	mouse->x = x;
	mouse->y = y;
	mouse->dir = dir;
	mouse->total = 0;
	mouse->valid = 0;
	stack_init (&mouse->brain);
}
/* 老鼠终结化 */
void mouse_deinit (MOUSE* mouse) {
	stack_deinit (&mouse->brain);
}
/* 老鼠记忆 */
void mouse_remember (MOUSE* mouse, int dir) {
	stack_push (&mouse->brain, dir);
}
/* 老鼠回忆 */
int mouse_recall (MOUSE* mouse) {
	return stack_pop (&mouse->brain);
}
/* 老鼠前进 */
void mouse_go (MOUSE* mouse, int dir) {
	switch (dir) {
		case DIR_RIGHT:
			++mouse->x;
			break;
		case DIR_DOWN:
			++mouse->y;
			break;
		case DIR_LEFT:
			--mouse->x;
			break;
		case DIR_UP:
			--mouse->y;
			break;
	}
	mouse_remember (mouse, mouse->dir = dir);
	++mouse->total;
	++mouse->valid;
}
/* 老鼠后退 */
void mouse_back (MOUSE* mouse) {
	switch (mouse_recall (mouse)) {
		case DIR_RIGHT:
			--mouse->x;
			mouse->dir = DIR_LEFT;
			break;
		case DIR_DOWN:
			--mouse->y;
			mouse->dir = DIR_UP;
			break;
		case DIR_LEFT:
			++mouse->x;
			mouse->dir = DIR_RIGHT;
			break;
		case DIR_UP:
			++mouse->y;
			mouse->dir = DIR_DOWN;
			break;
	}
	++mouse->total;
	--mouse->valid;
}
/* 迷宫 */
typedef struct Maze {
	int   cx;    /* 宽度 */
	int   cy;    /* 高度 */
	char* space; /* 空间 */
	MOUSE mouse; /* 老鼠 */
}	MAZE;
/* 迷宫初始化 */
void maze_init (MAZE* maze, int cx, int cy) {
	maze->cx = cx;
	maze->cy = cy;
	maze->space = malloc (cx * cy * sizeof (char));
	mouse_init (&maze->mouse, 0, 1, DIR_RIGHT);
	srand (time (NULL));
	char (*space)[cx] = (char (*)[cx])maze->space;
	int y, x;
	for (y = 0; y < cy; ++y)
		for (x = 0; x < cx; ++x)
			if (x == maze->mouse.x &&
				y == maze->mouse.y)
				space[y][x] = SPACE_MOUSE;
			else
			if ((y == 1 && x < 4) ||
				(y == cy - 2 && x > cx - 5))
				space[y][x] = SPACE_WAY;
			else
			if (y == 0 || y == cy - 1 ||
				x == 0 || x == cx - 1)
				space[y][x] = SPACE_WALL;
			else
				space[y][x] = rand () % 4 ?
					SPACE_WAY : SPACE_WALL;
}
/* 迷宫终结化 */
void maze_deinit (MAZE* maze) {
	free (maze->space);
	mouse_deinit (&maze->mouse);
}
/* 显示迷宫 */
void maze_show (MAZE* maze) {
	char (*space)[maze->cx] =
		(char (*)[maze->cx])maze->space;
	int y, x;
	for (y = 0; y < maze->cy; ++y) {
		for (x = 0; x < maze->cx; ++x) {
			switch (space[y][x]) {
				case SPACE_MOUSE:
					printf ("\033[;;31m");
					break;
				case SPACE_WALL:
					printf ("\033[;;34m");
					break;
				case SPACE_PASS:
					printf ("\033[;;32m");
					break;
				case SPACE_IMPASSE:
					printf ("\033[;;35m");
					break;
			}
			printf ("%c\033[0m",
				space[y][x] == SPACE_MOUSE ?
				g_mouse[maze->mouse.dir] :
				space[y][x]);
		}
		printf ("\n");
	}
	printf ("共走%d步,其中%d步有效。\n",
		maze->mouse.total, maze->mouse.valid);
}
/* 从标准输入读取一个字符,不回显不回车 */
int getch (void) {
	struct termios old;
	ioctl (STDIN_FILENO, TCGETS, &old);
	struct termios new = old;
	new.c_lflag &= ~(ECHO | ICANON);
	ioctl (STDIN_FILENO, TCSETS, &new);
	int ch = getchar ();
	ioctl (STDIN_FILENO, TCSETS, &old);
	return ch;
}
/* 是否退出 */
int maze_quit (void) {
	printf ("按<Q>键退出,按其它键继续...");
	int ch = getch ();
	printf ("\n");
	return strchr ("Qq", ch) != NULL;
}
/* 下一步 */
int maze_step (MAZE* maze) {
	char (*space)[maze->cx] =
		(char (*)[maze->cx])maze->space;
	int y = maze->mouse.y;
	int x = maze->mouse.x;
	space[y][x] = SPACE_PASS;
	if (x + 1 <= maze->cx - 1 &&
		space[y][x + 1] == SPACE_WAY)
		mouse_go (&maze->mouse, DIR_RIGHT);
	else
	if (y + 1 <= maze->cy - 1 &&
		space[y + 1][x] == SPACE_WAY)
		mouse_go (&maze->mouse, DIR_DOWN);
	else
	if (x - 1 >= 0 && space[y][x - 1] == SPACE_WAY)
		mouse_go (&maze->mouse, DIR_LEFT);
	else
	if (y - 1 >= 0 && space[y - 1][x] == SPACE_WAY)
		mouse_go (&maze->mouse, DIR_UP);
	else {
		space[y][x] = SPACE_IMPASSE;
		mouse_back (&maze->mouse);
	}
	y = maze->mouse.y;
	x = maze->mouse.x;
	space[y][x] = SPACE_MOUSE;
	maze_show (maze);
	if (y == maze->cy - 2 && x == maze->cx - 1) {
		printf ("我成功了!哈哈哈哈:)\n");
		return 0;
	}
	if (y == 1 && x == 0) {
		printf ("我要死了!呜呜呜呜:(\n");
		return 0;
	}
	return 1;
}
/* 运行 */
void maze_run (MAZE* maze) {
	for (maze_show (maze); ! maze_quit () &&
		maze_step (maze););
}
/* 主函数 */
int main (int argc, char* argv[]) {
	if (argc < 3) {
		printf ("用法:%s <迷宫宽度> <迷宫高度>\n",
			argv[0]);
		return -1;
	}
	MAZE maze;
	maze_init (&maze, atoi (argv[1]),
		atoi (argv[2]));
	maze_run (&maze);
	maze_deinit (&maze);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值