📄 maze.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)maze.c 1.1 92/07/30 SMI";#endif#include <sunwindow/window_hs.h>#include <sunwindow/cms.h>#include <suntool/gfxsw.h>#include <stdio.h>#define COLOR_MAP_SIZE 4#define LOGOSIZE 7#define MIN_MAZE_SIZE 3/* The following limits are adequate for displays up to 2048x2048 */#define MAX_MAZE_SIZE_X 205#define MAX_MAZE_SIZE_Y 205#define LOCK_COUNT_1 50#define LOCK_COUNT_2 100#define MOVE_LIST_SIZE (MAX_MAZE_SIZE_X * MAX_MAZE_SIZE_Y)#define WALL_TOP 0x8000#define WALL_RIGHT 0x4000#define WALL_BOTTOM 0x2000#define WALL_LEFT 0x1000#define DOOR_IN_TOP 0x800#define DOOR_IN_RIGHT 0x400#define DOOR_IN_BOTTOM 0x200#define DOOR_IN_LEFT 0x100#define DOOR_IN_ANY 0xF00#define DOOR_OUT_TOP 0x80#define DOOR_OUT_RIGHT 0x40#define DOOR_OUT_BOTTOM 0x20#define DOOR_OUT_LEFT 0x10#define START_SQUARE 0x2#define END_SQUARE 0x1#define SQ_SIZE_X 10#define SQ_SIZE_Y 10#define NUM_RANDOM 100static u_char rmap[COLOR_MAP_SIZE], gmap[COLOR_MAP_SIZE], bmap[COLOR_MAP_SIZE];static long int randnum[NUM_RANDOM];static struct gfxsubwindow *gfx;static struct rect pwrect;static u_short maze[MAX_MAZE_SIZE_X][MAX_MAZE_SIZE_Y];static struct { u_char x; u_char y; u_char dir; } move_list[MOVE_LIST_SIZE], save_path[MOVE_LIST_SIZE], path[MOVE_LIST_SIZE];static int maze_size_x, maze_size_y, border_x, border_y;static int sqnum, cur_sq_x, cur_sq_y, path_length;static int start_x, start_y, start_dir, end_x, end_y, end_dir;static int maze_restart_flag, lockcount, colorwindows, random_index;static int logo_x, logo_y, global_restart;static u_short icon_data[256] = {#include <images/lockscreen.icon>};mpr_static(icon_mpr, 64, 64, 1, icon_data);/* main module */main(argc,argv) int argc; char **argv;{ make_color_map(); initialize_window(); clear_window(); srandom(getpid()); while (1) { set_maze_sizes(argc, argv); if (global_restart) { global_restart = 0; continue; } initialize_maze(); if (global_restart) { global_restart = 0; continue; } clear_window(); if (global_restart) { global_restart = 0; continue; } draw_maze_border(); if (global_restart) { global_restart = 0; continue; } create_maze(); if (global_restart) { global_restart = 0; continue; } sleep(1); solve_maze(); if (global_restart) { global_restart = 0; continue; } sleep(1); }} /* end of main() */get_random(modulo) int modulo;{ return ((random()>>10) % modulo);} /* end of get_random */make_color_map() /* make the colormap */{ register int i; rmap[0] = 0; gmap[0] = 0; bmap[0] = 0; rmap[1] = 255; gmap[1] = 255; bmap[1] = 255; rmap[2] = 255; gmap[2] = 0; bmap[2] = 0; rmap[3] = 90; gmap[3] = 150; bmap[3] = 255;} /* end of make_colormap() */initialize_window() /* take over and initialize window */{ char cmsname[CMS_NAMESIZE]; gfx = gfxsw_init(0,0); sprintf(cmsname, "maze%d", COLOR_MAP_SIZE); pw_setcmsname(gfx->gfx_pixwin, cmsname); colorwindows = gfx->gfx_pixwin->pw_pixrect->pr_depth > 1; pw_putcolormap(gfx->gfx_pixwin, 0, colorwindows ? COLOR_MAP_SIZE : 2, rmap, gmap, bmap); pw_exposed(gfx->gfx_pixwin); win_getrect(gfx->gfx_pixwin->pw_clipdata->pwcd_windowfd, &pwrect);} /* end of initialize_window() */clear_window() /* blank the window */{ pw_rop(gfx->gfx_pixwin, 0, 0, gfx->gfx_pixwin->pw_clipdata->pwcd_prmulti->pr_size.x, gfx->gfx_pixwin->pw_clipdata->pwcd_prmulti->pr_size.y, PIX_CLR, 0, 0, 0);} /* end of clear_window() */ set_maze_sizes(argc, argv) int argc; char **argv;{ border_x = 20; border_y = 20; maze_size_x = ( gfx->gfx_pixwin->pw_clipdata->pwcd_prmulti->pr_size.x - border_x) / SQ_SIZE_X; maze_size_y = ( gfx->gfx_pixwin->pw_clipdata->pwcd_prmulti->pr_size.y - border_y ) / SQ_SIZE_Y; if ( maze_size_x < 3 || SQ_SIZE_Y < 3) { fprintf(stderr, "maze too small, exitting\n"); exit (1); } border_x = ( gfx->gfx_pixwin->pw_clipdata->pwcd_prmulti->pr_size.x - maze_size_x * SQ_SIZE_X)/2; border_y = ( gfx->gfx_pixwin->pw_clipdata->pwcd_prmulti->pr_size.y - maze_size_y * SQ_SIZE_Y)/2;} /* end of set_maze_sizes */initialize_maze() /* draw the surrounding wall and start/end squares */{ register int i, j, wall; /* initialize all squares */ for ( i=0; i<maze_size_x; i++) { for ( j=0; j<maze_size_y; j++) { maze[i][j] = 0; } } /* top wall */ for ( i=0; i<maze_size_x; i++ ) { maze[i][0] |= WALL_TOP; } /* right wall */ for ( j=0; j<maze_size_y; j++ ) { maze[maze_size_x-1][j] |= WALL_RIGHT; } /* bottom wall */ for ( i=0; i<maze_size_x; i++ ) { maze[i][maze_size_y-1] |= WALL_BOTTOM; } /* left wall */ for ( j=0; j<maze_size_y; j++ ) { maze[0][j] |= WALL_LEFT; } /* set start square */ wall = get_random(4); switch (wall) { case 0: i = get_random(maze_size_x); j = 0; break; case 1: i = maze_size_x - 1; j = get_random(maze_size_y); break; case 2: i = get_random(maze_size_x); j = maze_size_y - 1; break; case 3: i = 0; j = get_random(maze_size_y); break; } maze[i][j] |= START_SQUARE; maze[i][j] |= ( DOOR_IN_TOP >> wall ); maze[i][j] &= ~( WALL_TOP >> wall ); cur_sq_x = i; cur_sq_y = j; start_x = i; start_y = j; start_dir = wall; sqnum = 0; /* set end square */ wall = (wall + 2)%4; switch (wall) { case 0: i = get_random(maze_size_x); j = 0; break; case 1: i = maze_size_x - 1; j = get_random(maze_size_y); break; case 2: i = get_random(maze_size_x); j = maze_size_y - 1; break; case 3: i = 0; j = get_random(maze_size_y); break; } maze[i][j] |= END_SQUARE; maze[i][j] |= ( DOOR_OUT_TOP >> wall ); maze[i][j] &= ~( WALL_TOP >> wall ); end_x = i; end_y = j; end_dir = wall; /* set logo */ if ( (maze_size_x > 15) && (maze_size_y > 15) ) { logo_x = get_random(maze_size_x - LOGOSIZE - 6) + 3; logo_y = get_random(maze_size_y - LOGOSIZE - 6) + 3; for (i=0; i<LOGOSIZE; i++) { for (j=0; j<LOGOSIZE; j++) { maze[logo_x + i][logo_y + j] |= DOOR_IN_TOP; } } } else logo_y = logo_x = -1;}create_maze() /* create a maze layout given the intiialized maze */{ register int i, newdoor; lockcount = LOCK_COUNT_1; pw_lock(gfx->gfx_pixwin, &pwrect); do { move_list[sqnum].x = cur_sq_x; move_list[sqnum].y = cur_sq_y; move_list[sqnum].dir = newdoor; while ( ( newdoor = choose_door() ) == -1 ) { /* pick a door */ if ( backup() == -1 ) { /* no more doors ... backup */ maze_unlock(gfx->gfx_pixwin); return; /* done ... return */ } } if (global_restart) return; /* mark the out door */ maze[cur_sq_x][cur_sq_y] |= ( DOOR_OUT_TOP >> newdoor ); switch (newdoor) { case 0: cur_sq_y--; break; case 1: cur_sq_x++; break; case 2: cur_sq_y++; break; case 3: cur_sq_x--; break; } sqnum++; /* mark the in door */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -