扫雷
来源:互联网 发布:linux nginx访问403 编辑:程序博客网 时间:2024/06/06 20:21
代码
/* * 玩法:wsad方向,z设置旗帜,空格挖雷,q退出 */#include <stdlib.h>#include <string.h>#include <curses.h>#include <signal.h>#include <sys/time.h>#define ROW_SMALL 10#define COL_SMALL 10#define ROW_LARGE 20#define COL_LARGE 20#define MODE_SMALL 1#define MODE_LARGE 2#define MINE_SMALL 10#define MINE_LARGE 20#define MINE 1#define FLAG 2#define PRESSED 1#define RELEASED 2#define WIN 1#define LOSE 2#define CHAR_BLANK ' '#define CHAR_MINE '*'#define CHAR_FLAG '?'#define CHAR_ROW_SMALL_1 "------------"#define CHAR_ROW_SMALL_2 "| |"#define CHAR_ROW_LARGE_1 "----------------------"#define CHAR_ROW_LARGE_2 "| |"int win();void game_over_splash();void human_over(int flag);void clear_cursor();void draw_cursor();void move_up();void move_down();void move_left();void move_right();void play();int boom();void set_flag(int state);void generate_mine();void select_mode();void draw_map();void draw_time();void draw_flag();int in_map(int y, int x);void show_num(int y, int x);void timer(int sig);void game_over();void init();void init_game();int set_ticker(int n_msec);struct weiyi { int x, y;};int mode;int flag_cnt, flag_success;unsigned long cur_time, min_time_small, min_time_large;int cursor_x, cursor_y;int old_x, old_y;int map_small[ROW_SMALL][COL_SMALL];int map_large[ROW_LARGE][COL_LARGE];int visited[ROW_LARGE][COL_LARGE];struct weiyi around[9] = { -1,-1, 0,-1, 1,-1, -1,0, 0,0, 1,0, -1,1, 0,1, 1,1};int main(){ init(); play(); return 0;}void play(){ int ch; while (1) { ch = getch(); switch (ch) { case 'W': case 'w': move_up(); break; case 'S': case 's': move_down(); break; case 'A': case 'a': move_left(); break; case 'D': case 'd': move_right(); break; case ' ': attroff(A_STANDOUT); show_num(cursor_y, cursor_x); memset(visited, 0, sizeof(int)*ROW_LARGE*COL_LARGE); draw_cursor(); break; case 'Z': case 'z': if ((old_x != cursor_x) || (old_y != cursor_y)) { set_flag(PRESSED); } else { set_flag(RELEASED); old_x = cursor_x; old_y = cursor_y; } break; case 'Q': case 'q': init_game(); break; default: break; } }}int boom(){ if (MODE_SMALL == mode) { if (MINE == map_small[cursor_y-1][cursor_x-1]) return 1; return 0; } else if (MODE_LARGE == mode) { if (MINE == map_large[cursor_y-1][cursor_x-1]) return 1; return 0; }}void set_flag(int state){ move(cursor_y, cursor_x); if (PRESSED == state) { flag_cnt ++; addch(CHAR_FLAG); } else if (RELEASED == state) { flag_cnt --; addch(CHAR_BLANK); } refresh(); draw_flag(); if (MODE_SMALL == mode) { if ((PRESSED == state) && (map_small[cursor_y-1][cursor_x-1])) flag_success ++; else if ((PRESSED == state) && (map_small[cursor_y-1][cursor_x-1])) flag_success --; } else if (MODE_LARGE == mode) { if ((PRESSED == state) && (map_large[cursor_y-1][cursor_x-1])) flag_success ++; else if ((PRESSED == state) && (map_large[cursor_y-1][cursor_x-1])) flag_success --; } if (win()) { human_over(WIN); }}int in_map(int y, int x){ if (y < 1) return 0; if (x < 1) return 0; if (MODE_SMALL == mode) { if (y > ROW_SMALL) return 0; if (x > COL_SMALL) return 0; } else if (MODE_LARGE == mode) { if (y > ROW_LARGE) return 0; if (x > COL_LARGE) return 0; } return 1;}int win(){ if (MODE_SMALL == mode) return ((MINE_SMALL == flag_success) && (MINE_SMALL == flag_cnt)); else if (MODE_LARGE == mode) return ((MINE_LARGE == flag_success) && (MINE_LARGE == flag_cnt));}void game_over_splash(){ int i, j; if (MODE_SMALL == mode) { for (i = 0; i < ROW_SMALL; i ++) { for (j = 0; j < COL_SMALL; j ++) { if (map_small[i][j]) { move(i+1, j+1); addch(CHAR_MINE); } } } } else if (MODE_LARGE == mode) { for (i = 0; i < ROW_LARGE; i ++) { for (j = 0; j < COL_LARGE; j ++) { if (map_large[i][j]) { move(i+1, j+1); addch(CHAR_MINE); } } } } refresh();}void show_num(int y, int x){ int i, cnt = 0; int x0, y0; if (boom()) { game_over_splash(); human_over(LOSE); return; // note! } if (win()) { human_over(WIN); } for (i = 0; i < 9; i ++) { x0 = x + around[i].x; y0 = y + around[i].y; if (in_map(y0, x0)) { if ((MODE_SMALL == mode) && (map_small[y0-1][x0-1] == MINE)) { cnt ++; } else if ((MODE_LARGE == mode) && (map_large[y0-1][x0-1] == MINE)) { cnt ++; } } } move(y, x); addch('0'+cnt); refresh(); visited[y-1][x-1] = 1; if (0 == cnt) { for (i = 0; i < 9; i ++) { x0 = x + around[i].x; y0 = y + around[i].y; if (in_map(y0, x0) && !visited[y0-1][x0-1]) { show_num(y0, x0); } } }}void clear_cursor(){ char ch; move(cursor_y, cursor_x); attroff(A_STANDOUT); ch = (char)inch(); addch(ch); refresh();}void draw_cursor(){ char ch; move(cursor_y, cursor_x); ch = (char)inch(); attron(A_STANDOUT); addch(ch); refresh();}void move_up(){ clear_cursor(); if (cursor_y > 1) cursor_y --; draw_cursor();}void move_down(){ clear_cursor(); if (MODE_SMALL == mode) { if (cursor_y < ROW_SMALL) cursor_y ++; } else if (MODE_LARGE == mode) { if (cursor_y < ROW_LARGE) cursor_y ++; } draw_cursor();}void move_left(){ clear_cursor(); if (cursor_x > 1) cursor_x --; draw_cursor();}void move_right(){ clear_cursor(); if (MODE_SMALL == mode) { if (cursor_x < COL_SMALL) cursor_x ++; } else if (MODE_LARGE == mode) { if (cursor_x < COL_LARGE) cursor_x ++; } draw_cursor();}void timer(int sig){ static int cnt = 0; if (cnt >= 1) { cnt = 0; cur_time ++; draw_time(); } else { cnt ++; }}void draw_flag(){ attroff(A_STANDOUT); if (MODE_SMALL == mode) { move(5, COL_SMALL+3); printw("flag number : %d", flag_cnt); } else if (MODE_LARGE == mode) { move(5, COL_LARGE+3); printw("flag number : %d", flag_cnt); } refresh(); attron(A_STANDOUT);}void draw_time(){ attroff(A_STANDOUT); if (MODE_SMALL == mode) { move(0, COL_SMALL+3); printw("time : %d hours %d minutes %d seconds", cur_time/3600, cur_time%3600/60, cur_time%3600%60); move(2, COL_SMALL+3); printw("record : %d hours %d minutes %d seconds", min_time_small/3600, min_time_small%3600/60, min_time_small%3600%60); } else if (MODE_LARGE == mode) { move(0, COL_LARGE+3); printw("time : %d hours %d minutes %d seconds", cur_time/3600, cur_time%3600/60, cur_time%3600%60); move(2, COL_LARGE+3); printw("record : %d hours %d minutes %d seconds", min_time_large/3600, min_time_large%3600/60, min_time_large%3600%60); } refresh(); attron(A_STANDOUT);}void draw_map(){ int i; clear(); if (MODE_SMALL == mode) { move(0, 0); printw(CHAR_ROW_SMALL_1); for (i = 1; i <= ROW_SMALL; i ++) { move(i, 0); printw(CHAR_ROW_SMALL_2); } move(i, 0); printw(CHAR_ROW_SMALL_1); } else if (MODE_LARGE == mode) { move(0, 0); printw(CHAR_ROW_LARGE_1); for (i = 1; i <= ROW_LARGE; i ++) { move(i, 0); printw(CHAR_ROW_LARGE_2); } move(i, 0); printw(CHAR_ROW_LARGE_1); } refresh();}void select_mode(){ int ch, flag; clear(); move(0, 10); printw("Select Mode"); move(3, 10); printw("1. Small (1)"); move(5, 10); printw("2. Large (2)"); move(7, 10); printw("3. Quit (3)"); flag = 1; while(flag) { ch = getch(); switch (ch) { case '1': mode = MODE_SMALL; flag = 0; break; case '2': mode = MODE_LARGE; flag = 0; break; case '3': game_over(); flag = 0; break; default: break; } }}void human_over(int flag){ set_ticker(0); clear_cursor(); if (MODE_SMALL == mode) { move(ROW_SMALL+3, 0); if (WIN == flag) { if (cur_time < min_time_small) { printw("New Time Record : \ %d hours %d minutes %d seconds", cur_time/3600, cur_time%3600/60, cur_time%3600%60); min_time_small = cur_time; } else { printw("You Win!"); } } else if (LOSE == flag) { printw("You Lose!"); } } else if (MODE_LARGE == mode) { move(ROW_LARGE+3, 0); if (WIN == flag) { if (cur_time < min_time_large) { printw("New Time Record : \ %d hours %d minutes %d seconds", cur_time/3600, cur_time%3600/60, cur_time%3600%60); min_time_large = cur_time; } else { printw("You Win!"); } } else if (LOSE == flag) { printw("You Lose!"); } } refresh(); sleep(3); init_game();}void game_over(){ endwin(); exit(0);}void generate_mine(){ int i, j, k; if (MODE_SMALL == mode) { for (k = 0; k < MINE_SMALL; ) { i = rand() % ROW_SMALL; j = rand() % COL_SMALL; if (map_small[i][j] != MINE) { map_small[i][j] = MINE; k ++; } else { continue; } } } else if (MODE_LARGE == mode) { for (k = 0; k < MINE_LARGE; ) { i = rand() % ROW_LARGE; j = rand() % COL_LARGE; if (map_large[i][j] != MINE) { map_large[i][j] = MINE; k ++; } else { continue; } } }}void init(){ initscr(); clear(); cbreak(); noecho(); curs_set(0); srand(time(0)); signal(SIGALRM, timer); min_time_large = min_time_small = ~0; init_game();}void init_game(){ set_ticker(0); attroff(A_STANDOUT); select_mode(); if (MODE_SMALL == mode) memset(map_small, 0, sizeof(int)*ROW_SMALL*COL_SMALL); else if (MODE_LARGE == mode) memset(map_large, 0, sizeof(int)*ROW_LARGE*COL_LARGE); draw_map(); generate_mine(); cursor_x = (MODE_SMALL == mode) ? COL_SMALL/2+1 : COL_LARGE/2+1; cursor_y = (MODE_SMALL == mode) ? ROW_SMALL/2+1 : ROW_LARGE/2+1; old_x = cursor_x; old_y = cursor_y; draw_cursor(); cur_time = 0; flag_cnt = 0; flag_success = 0; set_ticker(500); draw_time(); draw_flag();}int set_ticker(int n_msec){ struct itimerval timeset; long n_sec, n_usec; n_sec = n_msec / 500; n_usec = (n_msec % 500) * 1000L; timeset.it_interval.tv_sec = n_sec; timeset.it_interval.tv_usec = n_usec; timeset.it_value.tv_sec = n_sec; timeset.it_value.tv_usec = n_usec; return setitimer(ITIMER_REAL, ×et, NULL);}
结果
视频
c语言小游戏
0 0