Indicate the source for reprinting. Http://www.cnblogs.com/dave_cn/
During this time, things were quite busy, and it was hard to take some time to find some game trainer. Here, it was ugly.
I tested it in Ubuntu 10.04 and it can run normally.
The Code uses the ncurses library. Compile the ncurses library, for example, CC-wall-O2-O mine. C-lncurses.
First, let's take a look at the page and try again with a dizzy look! :
Code:
# Include <stdio. h> # include <stdlib. h> # include <string. h> # include <sys/types. h> # include <sys/Wait. h> # include <sys/select. h> # include <time. h> # include <signal. h> # include <unistd. h> # include <ncurses. h>/* minefield range */# define minearea_width 9 # define minearea_length 9/* number of mines */# define mine_number 10: * 1. initial status * 2. identified as thunder (that is, the usual flag) * 3. exclude (if there are n mines in the surrounding area, it is displayed as N, 0 is displayed as null, and-1 is used to represent the thunder) */# define square_init 0 # define Square_flag 1 # define square_clean 2 # define square_zero 0 # define square_mine-1/* display graphics */# define graph_init '. '# define graph_mine' @ '# define graph_null'' # define graph_flag 'F' # define newline addch ('\ n') # DEFINE _ w (y) (y * 2 + 3) # DEFINE _ L (x) (x * 3 + 1)/* set the cursor */# define set_cursor (Y, X) mvchgat (_ w (Y), _ L (x), 2, a_reverse, 0, null) # define clean_cursor (Y, x) mvchgat (_ w (Y ), _ l (x), 2, a_normal, 0, NUL L) # define wprint_number (Y, X, v) \ mvprintw (Y, X, "% d", v) # define wprint_char (Y, X, c) \ mvaddch (Y, X, C)/* cursor position */INT g_cur_y = 0; int g_cur_x = 0; struct square_t {int type; int mine ;}; /* timer process function */INT timer_p (); void sig_refresh_time (int signum); int init_mine (struct square_t square [minearea_width] [minearea_length]); int check_yx (INT y, int X); int game_loop (struct square_t square [Mi Nearea_width] [minearea_length]); int evaluate (struct square_t square [minearea_width] [minearea_length], int cur_y, int cur_x);/* window functions */INT win_init (INT width, int length, int mine_num); int win_refresh (struct square_t square [minearea_width] [minearea_length], int width, int length, int mines); int win_refresh_remine_mines (INT mines ); int win_refresh_secs (INT SECs); int win_mv_curso R (INT delta_y, int delta_x, int width, int length); int win_destroy (); int win_bang (); int win_win (); int win_game_over (); int main () {int pid_timer; int pid_main; Switch (pid_timer = fork () {Case 0:/* timer process, used as a timer */timer_p (); _ exit (0 ); case-1: perror ("fork () error! "); Return-1; default:/* main process */break;} pid_main = getpid ();/* SIGUSR1 signal used to refresh the display time */If (signal (SIGUSR1, sig_refresh_time) = sig_err) Return-1; struct square_t square [minearea_width] [minearea_length]; If (init_mine (square) =-1) Return-1; win_init (minearea_width, minearea_length, mine_number);/* Main Loop */game_loop (square); win_game_over ();/* the Timer sub-process must be terminated before the main process ends */kill (pid_timer, Sig Kill); int key =-1; do {key = getch () ;}while (key! = 'Y' & Key! = 'Y'); wait (null); win_destroy (); Return 0;}/* initialize minefield information */INT init_mine (struct square_t square [minearea_width] [minearea_length]) {If (square = NULL) Return-1; printf ("waiting... \ n "); int n, m; For (n = 0; n <9; ++ N) {for (m = 0; m <9; ++ m) {square [N] [M]. type = 0; Square [N] [M]. mine = 0 ;}} int I; int y, X; srandom (INT) Time (null); for (I = 0; I <mine_number; ++ I) {Y = random () % minearea_wi DTH; X = random () % minearea_length; If (square [y] [X]. mine = square_mine) {-- I;} else {square [y] [X]. mine = square_mine; If (check_yx (Y-1, x) = 0 & square [Y-1] [X]. mine! = Square_mine) + + square [Y-1] [X]. mine; If (check_yx (Y + 1, x) = 0 & square [Y + 1] [X]. mine! = Square_mine) + + square [Y + 1] [X]. Mine; If (check_yx (Y, x-1) = 0 & square [y] [x-1]. Mine! = Square_mine) + + square [y] [x-1]. mine; If (check_yx (Y, x + 1) = 0 & square [y] [x + 1]. mine! = Square_mine) + + square [y] [x + 1]. Mine; If (check_yx (Y-1, x-1) = 0 & square [Y-1] [x-1]. Mine! = Square_mine) + + square [Y-1] [x-1]. mine; If (check_yx (Y + 1, x-1) = 0 & square [Y + 1] [x-1]. mine! = Square_mine) + + square [Y + 1] [x-1]. mine; If (check_yx (Y-1, x + 1) = 0 & square [Y-1] [x + 1]. mine! = Square_mine) + + square [Y-1] [x + 1]. mine; If (check_yx (Y + 1, x + 1) = 0 & square [Y + 1] [x + 1]. mine! = Square_mine) ++ square [Y + 1] [x + 1]. mine;} return 0;} int check_yx (INT y, int X) {If (Y> = 0 & Y <minearea_width & x> = 0 & x <minearea_length) {return 0 ;}return-1 ;} /* Main Loop */INT game_loop (struct square_t square [minearea_width] [minearea_length]) {fd_set RfD; fd_zero (& RFD); fd_set (0, & RFD ); static int sweeped_mines = 0;/* number of mines correctly identified */int ret; int input; int remain_mines = mine_number; while (1) {If (ret = select (1, & RfD, null) <= 0) {// return-1; // when the program is interrupted, select may return-1 continue;} switch (input = getch () {/* w, S,, D direction key */case 'W': Case 'W': win_mv_cursor (-1, 0, minearea_width, minearea_length); break; Case's ': win_mv_cursor (+ 1, 0, minearea_width, minearea_length); break; Case 'A': win_mv_cursor (0,-1, minearea_width, minearea_length); break; Case 'D': win_mv_cursor (0, + 1, minearea_width, minearea_length); break;/* flag */case 'J': Case 'J ': if (square [g_cur_y] [g_cur_x]. type = square_init) {square [g_cur_y] [g_cur_x]. type = square_flag; -- remain_mines; If (square [g_cur_y] [g_cur_x]. mine = square_mine) ++ sweeped_mines;} else if (square [g_cur_y] [g_cur_x]. type = square_flag) {square [g_cur_y] [g_cur_x]. type = square_init; ++ Rem Ain_mines; If (square [g_cur_y] [g_cur_x]. mine = square_mine) -- keys;} else break; If (Keys = mine_number) {win_win (); goto game_over;} win_refresh (square, minearea_width, minearea_length, remain_mines ); break;/* Open the square */case 'K': Case 'K': If (square [g_cur_y] [g_cur_x]. type = square_clean) break; else if (square [g_cur_y] [g_cur_x]. mine = square_mine) {win_bang (); int n, m; For (n = 0; n <minearea_width; ++ N) {for (m = 0; m <minearea_length; ++ m) {square [N] [M]. type = square_clean;} win_refresh (square, minearea_width, minearea_length, remain_mines); goto game_over;} square [g_cur_y] [g_cur_x]. type = square_clean; If (square [g_cur_y] [g_cur_x]. mine = square_zero) clean_zero_squares (square, g_cur_y, g_cur_x); win_refresh (square, minearea_width, minearea_length, re Main_mines); break;/* exit */case 'q': Case 'q': goto game_over; default: Break ;}} game_over: Return 0 ;} /* If the square to be opened is 0, all the surrounding blocks */INT clean_zero_squares (struct square_t square [minearea_width] [minearea_length], int cur_y, int cur_x) are automatically opened) {If (check_yx (cur_y-1, cur_x) = 0 & square [cur_y-1] [cur_x]. mine = square_zero & square [cur_y-1] [cur_x]. type! = Square_clean) {square [cur_y-1] [cur_x]. type = square_clean; clean_zero_squares (square, cur_y-1, cur_x);} If (check_yx (cur_y + 1, cur_x) = 0 & square [cur_y + 1] [cur_x]. mine = square_zero & square [cur_y + 1] [cur_x]. type! = Square_clean) {square [cur_y + 1] [cur_x]. type = square_clean; clean_zero_squares (square, cur_y + 1, cur_x);} If (check_yx (cur_y, cur_x-1) = 0 & square [cur_y] [cur_x-1]. mine = square_zero & square [cur_y] [cur_x-1]. type! = Square_clean) {square [cur_y] [cur_x-1]. type = square_clean; clean_zero_squares (square, cur_y, cur_x-1);} If (check_yx (cur_y, cur_x + 1) = 0 & square [cur_y] [cur_x + 1]. mine = square_zero & square [cur_y] [cur_x + 1]. type! = Square_clean) {square [cur_y] [cur_x + 1]. type = square_clean; clean_zero_squares (square, cur_y, cur_x + 1);} return 0 ;} /*************************************** **************************************// * initialize the display interface */INT win_init (INT width, int length, int mine_num) {initscr (); raw (); noecho (); keypad (stdscr, true); curs_set (0); refresh (); win_refresh_remine_mines (mine_number ); win_refresh_secs (0); In T frame_width = width * 2 + 1; int frame_length = length * 3 + 1; char * line = NULL; line = (char *) malloc (frame_length + 1) * sizeof (char); memset (line, '-', frame_length); * (LINE + frame_length) = '\ 0'; mvprintw (2, 0, line ); newline; int I, j; For (j = 0; j <frame_width-2; ++ J) {addch ('|'); for (I = 0; I <length * 2 + 1-2; ++ I) {If (J % 2 = 0) {if (I % 2 = 0) {addch (graph_init ); addch ('') ;}Else {addch ('|') ;}} else {if (I % 2 = 0) {addch ('-'); addch ('-');} else {addch ('+') ;}} addch ('|'); newline;} printw (line); newline; /* Set cursor position */set_cursor (g_cur_y, g_cur_x); refresh (); Return 0 ;} /* refresh the display page */INT win_refresh (struct square_t square [minearea_width] [minearea_length], int width, int length, int mines) {If (square = NULL) return-1; win_refresh_remine_mi NES (Mines); Int J, I; for (j = 0; j <width; ++ J) {for (I = 0; I <length; ++ I) {Switch (square [J] [I]. type) {Case square_init: wprint_char (_ w (J), _ L (I), graph_init); break; Case square_flag: wprint_char (_ w (J ), _ l (I), graph_flag); break; Case square_clean: Switch (square [J] [I]. mine) {Case square_mine: wprint_char (_ w (J), _ L (I), graph_mine); break; Case square_zero: wprint_char (_ w (J ), _ l (I), grap H_null); break; default: wprint_number (_ w (J), _ L (I), square [J] [I]. mine); break;} break; default: break; }}} refresh (); Return 0;} int win_refresh_remine_mines (INT mines) {mvprintw (0, 0, "mines: % d ", mines); mvprintw (1, 0, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "); Refresh (); Return 0;} int win_refresh_secs (INT SECs) {mvprintw (0, 15," seconds: % d ", SECs); refresh (); return 0;} int win_mv_cursor (INT delta_y, int delta_x, int width, int length) {clean_cursor (g_cur_y, g_cur_x ); if (g_cur_y + delta_y <width & g_cur_y + delta_y> = 0) g_cur_y + = delta_y; If (g_cur_x + delta_x <length & g_cur_x + delta_x> = 0) g_cur_x + = delta_x; set_cursor (g_cur_y, g_cur_x ); Refresh (); Return 0;} int win_destroy () {endwin (); Return 0;} int win_bang () {mvprintw (0, 0, "Bang !!!! "); Refresh (); Return 0;} int win_win () {mvprintw (0, 0," win !!!! "); Refresh (); Return 0;} int win_game_over () {mvprintw (1, 0," Game over! "); Mvprintw (1, 0," press 'y' or 'y' to end. "); refresh (); Return 0 ;} /*************************************** * ***********************************/int timer_p () {/* send a signal to the main process every second */do {sleep (1); kill (getppid (), SIGUSR1);} while (1); Return 0 ;} void sig_refresh_time (int signum) {static int secs = 0; win_refresh_secs (++ SECs );}
Here is an executable file compiled by myself (Ubuntu 10.4 ):
/Files/dave_cn/mine.zip
-- End --