Character interface game in Linux

Source: Internet
Author: User
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 --

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.