[M3] pushbox.c [推箱子程序]

看板Maple (BBS架站)作者時間22年前 (2002/09/03 20:17), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
/* ----------------------------------------------------------------------- 原始聲明 --------------------------------------------------------- orign program name: worker.c Chinese name: 推箱子 this program is a GNU free software first written by period.bbs@smth.org and cityhunter.bbs@smth.org, Nov 11, 1998(?) rewitten by zhch.bbs@bbs.nju.edu.cn, Nov 27, 2000 new: so/pushbox.c rewriten by hightman.bbs@bbs.hightman.net Aug 28, 2002 ------------------------------------------------------------------------- */ #include "bbs.h" #ifdef HAVE_TTY_GAME #define MAP_DATA_PATH "game/pushbox.map" #define MAX_MAP_NUM 50 #define MAX_MAP_WIDTH 20 #define MAX_MAP_HEIGHT 16 #define KEY_BACKSPACE 8 #define MAX_MOVE_TIMES 1000 #define move2(y, x) move(y+3, x*2+2) static int map_data[MAX_MAP_NUM][MAX_MAP_HEIGHT][MAX_MAP_WIDTH]; static int map_now[MAX_MAP_HEIGHT][MAX_MAP_WIDTH]; static int map_total = 1; static char *xstring[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K" , "L", "M", "N", "O", "P", "Q", "R", "S", "T", NULL}; static char *ystring[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", NULL}; static int stage; static int now_y, now_x; struct history { int max; char y0[MAX_MOVE_TIMES * 2]; char x0[MAX_MOVE_TIMES * 2]; char y1[MAX_MOVE_TIMES * 2]; char x1[MAX_MOVE_TIMES * 2]; } my_history; static char * map_char(n) int n; { if(n&8) return "■"; if(n&4) return "□"; if(n&2) return "⊙"; if(n&1) return "﹒"; return " "; } static int map_init() { FILE *fp; int map_y = 0, map_x = 0; char buf[80]; fp = fopen(MAP_DATA_PATH, "r"); if (fp == NULL) return 0; map_x = 0; while (fgets(buf, 80, fp)) { if (!str_ncmp(buf, "--", 2)) { map_y = 0; map_total++; } if (map_total > MAX_MAP_NUM) break; for (map_x = 0; map_x < MAX_MAP_HEIGHT; map_x++) { if (!str_ncmp(buf + map_x*2, map_char(1), 2)) map_data[map_total-1][map_y][map_x] = 1; else if (!str_ncmp(buf + map_x*2, map_char(2), 2)) map_data[map_total-1][map_y][map_x] = 2; else if (!str_ncmp(buf + map_x*2, map_char(4), 2)) map_data[map_total-1][map_y][map_x] = 4; else if (!str_ncmp(buf + map_x*2, map_char(8), 2)) map_data[map_total-1][map_y][map_x] = 8; else map_data[map_total-1][map_y][map_x] = 0; } if (map_y < MAX_MAP_HEIGHT) map_y++; } fclose(fp); return 1; } static int map_show() { int m, n; move(2, 0); clrtobot(); outs(" "); for (m = 0; m <MAX_MAP_WIDTH; m++) prints("%-2s", xstring[m]); for (n = 0; n < MAX_MAP_HEIGHT; n++) { outs("\n"); prints("%2s", ystring[n]); for (m = 0; m < MAX_MAP_WIDTH; m++) { if (map_now[n][m] == 5) prints("\033[1;32m%s\033[0m", map_char(map_now[n][m])); else outs(map_char(map_now[n][m])); } } move(MAX_MAP_HEIGHT + 2, 0); prints("歡迎光臨 %s - 推箱子游戲", str_site); outs("\n\033[0;34;46m 按鍵說明 \033[47m \033[31m(↑↓←→)\033[30m移動 \033 [31m(^C ^D)\033[30m退出 \033[31m(BackSpace)\033[30m悔推 \033[31m(Tab)\033[30m重 開 \033[31m(^L)\033[30m刷新屏幕\033[m"); move2(now_y, now_x); } static int map_show_line(y) int y; { int i; move2(y, 0); clrtoeol(); for (i = 0; i < MAX_MAP_WIDTH; i++) { if (map_now[y][i] == 5) prints("\033[1;32m%s\033[0m", map_char(map_now[y][i])); else outs(map_char(map_now[y][i])); } } static int check_if_win() { int m, n; for (n=0; n < MAX_MAP_HEIGHT; n++) { for (m = 0; m < MAX_MAP_WIDTH; m++) { if (map_now[n][m]==1 || map_now[n][m]==3) return 0; } } return 1; } static int find_y_x(int *y, int *x) { int m, n; for (n=0; n < MAX_MAP_HEIGHT; n++) { for (m=0; m < MAX_MAP_WIDTH; m++) { if (map_now[n][m] & 2) { *x = m; *y = n; return 1; } } } return 0; } static void map_move(int y0, int x0, int y1, int x1) { int b0, f0, b1; b0 = map_now[y0][x0] & 1; f0 = map_now[y0][x0] & 6; b1 = map_now[y1][x1] & 1; map_now[y1][x1] = f0 | b1; map_now[y0][x0] = b0; map_show_line(y0); map_show_line(y1); move(1, 0); clrtoeol(); prints("第 \033[1;32m%d\033[m 關 第 \033[1;31m%d\033[m 步 From: (%s,%s) To: (%s,%s) 您已獲得獎金: %d", stage, my_history.max, xstring[x0], ystring[y0], xstring[x1], ystring[y1]); } static int select_stage() { char stage_str[4]; int stage; ll_new(); for (stage = 0; stage < map_total; stage++) { sprintf(stage_str, "%d", stage); ll_add(stage_str); } if (!vget(1, 0, "請問要玩第几關? (輸入空格鍵列出所有關號)", stage_str, 4, G ET_LIST)) { vmsg("錯誤的關號!"); return -1; } stage = atoi(stage_str); return stage; } int p_pushbox() { int c, m, n, i, dx, dy; if (map_init() == 0) { vmsg("載入地圖數據時發重錯誤,請洽談sysop"); return 0; } stage = 0; utmp_mode(M_PUSH); clear(); vs_bar("推 箱 子"); move(1, 0); outs("歡迎光臨 \033[1;32m推箱子\033[m 游戲\n\n規則很簡單: 只需把所有的 '□' 都推到 '﹒' 上面去(會變成\033[1;32m綠色\033[m)就過關了。\n\n站長提醒:玩起來難 度可是相當大的,不要輕視喔~\n"); stage = select_stage(); if (stage < 0) return; start: clear(); vs_bar("推 箱 子"); move(1, 0); prints("第 \033[1;32m%d\033[m 關", stage); start2: for (n=0; n < MAX_MAP_HEIGHT; n++) { for(m=0; m < MAX_MAP_WIDTH; m++) map_now[n][m] = map_data[stage][n][m]; } if (!find_y_x(&now_y, &now_x)) { vmsg("這張地圖似乎不對勁!"); return -1; } map_show(); bzero(&my_history, sizeof(my_history)); while (1) { c = vkey(); if (my_history.max > MAX_MOVE_TIMES) { char buf[256]; sprintf(buf, "您用了 %d 步還沒有成功!Game Over!~", MAX_MOVE_TIMES); vmsg(buf); } dx = dy = 0; switch (c) { case KEY_BACKSPACE : case KEY_DEL : if (my_history.max > 0) { my_history.max--; i = my_history.max; map_move(my_history.y1[i], my_history.x1[i], my_history.y0[i], my_h istory.x0[i]); find_y_x(&now_y, &now_x); move2(now_y, now_x); } break; case KEY_UP : dy = -1; break; case KEY_DOWN : dy = 1; break; case KEY_LEFT : dx = -1; break; case KEY_RIGHT : dx = 1; break; case KEY_TAB : goto start2; break; case Ctrl('D') : case Ctrl('C') : goto over; break; case Ctrl('L') : map_show(); break; } if (dx == 0 && dy == 0) continue; m = map_now[now_y + dy][now_x + dx]; n = map_now[now_y + dy*2][now_x + dx*2]; if ((m & 4) && (n < 2)) { map_move(now_y+dy, now_x+dx, now_y+dy*2, now_x+dx*2); i = my_history.max; my_history.y0[i] = now_y+dy; my_history.x0[i] = now_x+dx; my_history.y1[i] = now_y+dy*2; my_history.x1[i] = now_x+dx*2; my_history.max++; } else if (m < 2) { map_move(now_y, now_x, now_y+dy, now_x+dx); i = my_history.max; my_history.y0[i] = now_y; my_history.x0[i] = now_x; my_history.y1[i] = now_y+dy; my_history.x1[i] = now_x+dx; my_history.max++; } if (check_if_win()) { break; } find_y_x(&now_y, &now_x); move2(now_y, now_x); } vmsg("祝賀您!成功過關 ... "); stage++; goto start; over: return; } -- ※ Origin: 明月水軒 <bbs.hightman.net> ◆ From: 10.12.123.160
文章代碼(AID): #zTAX600 (Maple)
文章代碼(AID): #zTAX600 (Maple)