Write a Hanno tower game with the Curses function
content:
The origin of the Hanno Tag Game CURSES describes the implementation of the implementation of the implementation of the implementation of the data structure column to implement the implementation of the implementation of the mobile disk.
related information:
(1) NewT program design guide (2) More related articles
Curses is to adapt to a wide range of different types of terminals on the network, while a set of functions in Unix specially developed to deal with the display of the movement and screen on UNIX. This article will tell you about Curses programming skills and provide you with a routine of Hanno game.
Hannota game Hanno Tita is an ancient game: it has three wooden columns and differentiated disks, which can be set into the wooden column. The numbers of the wooden column are 1, 2, and 3, respectively, and the 2 column puts the plates on the 1 column to the 3 column. The rule of the mobile is this: You can only move the top on the top of the column each time; no disk is put on a small disk than it.
Now we use the Curses function to implement this game on the terminal. The origin of CURSES specially developed a set of functions in UNIX, which specializes in UNIX, which is specifically used to handle display on UNIX. Curses was first developed by Berkle University. The main reason for this function library was to improve compatibility for different terminals. Programs developed using Curses are unrelated to the terminal, which is a considerable thing for programs on the network. Curses store all the data in a database, with these records, Curses programs can know which terminal encountered. The CURSES function introduces some of the commonly used Curses functions. The Window * INITSCR (VOID) INITSCR () function is usually the first call function of the CURSES program to determine the terminal type and initialize the CURSES data structure, and the terminal is also refreshed once to clear the screen, prepare for future operations. If an error occurs when an error occurs, an error message is output in the standard error output and exits correctly, and returns a variable that belongs to the Window type. INT Endwin (Void) Each CURSES program should be called an endwin () function when exiting or temporarily disengaged from Curses mode. Calling this function will restore the original state of the TTY terminal, move the cursor to the lower left corner of the screen, reset the terminal as the correct non-virtual mode. Bool HAS_COLORS (Void) HAS_COLORS () routine does not require parameters. Returns true if the terminal can generate color; otherwise returns false. The programmer determines whether the terminal can use color by calling it. INT USE_DEFAULT_COLORS routine is an extension of the Curses library. It tells the Curses library to set the terminal to the default foreground / background, the default time is white, the background is black. Successful settings returns OK, otherwise returns ERR, Both are integer values. INT init_pair (Short Pair, short f, short b) init_pair () routine is used to change a color pair definition. Color pair is a concept of curses, it uses a integer value to sign a pair of foreground / background colors. This routine has three parameters: color logs, which ranges from 1 to Color_Pairs-1; F (Foreground) specifies foreground color; B (Background) specifies background colors. Curses predefined colors are:
Color_Black-Black Color_White-White Color_red-Red Color_Green-Green Color_Yellow-Yellow Color_Blue-Blue Color_MAGENTA-Mango Color_CYAN-Green If you are too monotonous, you can use init_color () from definition. INT Echo (void) is used to return the character IECHO (Void) entered from the keyboard. INT NOECHO (Void) does not display the character INT beep (Void) entered from the keyboard to issue a sound warning to the terminal, and the successful execution returns OK, otherwise returns ERR INT AttrSet (int att att attrs) AttRset routine sets the current window to the properties specified by the parameter AtTRS, which is commonly used: a_underline-- 加 A_REVERSE - Bright white A_BLINK - flashing A_BOLD - High-level A_MORMAL - Standard mode, Also used to restore int Refresh (void) When any operation or modification is performed on the terminal, the desired effect is only in which Refresh () can be displayed. INT MVPrintw (int y, int x, char * fmt [, arg] ...) mvwprintw () is used to output a formatted string, format usage and printf () the same. INT MVADDNSTR (int y, int x, const char * str, int N) outputs a string in the screen specified location, and is only lacking formatted output than the above routine. INT MVADDCH (INT Y, INT X, ChTYPE CH) outputs a character in the screen specified location. INT CLRToEOL (Void) Removes all character int out (void) from the cursor to the end of the current row to copy blank on the screens of the screen to make the screen to be cleared. In fact, the functions provided by Curses are not 200, but there is no need to grasp all functions, and all the complex functions can be combined with some basic functions. There is too much in the Curses function, but there is a counter-effect, and it will increase your own trouble. With the above-mentioned foundation, substantive work now. The defined data structure compares the three columns numbered 1, 2 and 3, found that they have the same and different: When a plate is placed on all columns, if the number of each column is ignored, it will be difficult to distinguish. These columns are all the same, so if one data structure can describe one of the columns, this data structure is suitable for the remaining columns; can be known from the game rule, one disk can only be on one column, each pillar Different from different disks, the disc on the column should be the attribute of the column, because it can distinguish it from other columns. According to the above analysis, the data structure for describing the column is as follows:
Struct peg {size_t length [maxTILES]; / * Online, the size of the storage disk, the size of the disk should be different * / int count; / * record the total number of discs on the column * /}; define data structure It is the first step, it is also important. The implementation of the column is to draw the opening of the article on the terminal. It is not difficult to use the Curses function. Picture of horizontal straight lines:
Set the foreground / background color pair, from the horizontal straight start to the horizontal line end cycle to perform the mvaddch () output space, you get a horizontal color strip. The algorithm that draws vertically straight line is basically the same as the above algorithm, except from the vertical straight end to the vertical line end cycle. Realization of three columns:
For (line
For (peg = 0; PEG Any disk is not allowed to be on a small disk than it, that is, its length is less than the length of the topmost of the endpoint. PEGS [from]. Dength [pegs [from] .count - 1]> pegs [to] .length [pegs [to] .count - 1] The input should be effective, including from and TO are the number of the column, From 1 to 3; from FROM is not equal to TO, this is meaningless. In line with the above requirements, it is considered to be effective, then the movement of the disk is then realized. The movement of the disk is actually a data structure that changes the status of the marker. First, to change the startup state: pegs [from] .count minus one, due to the LENGTH array is set, when count is reduced, the top of the column is automatically discarded; then, add the target disk to the end point On the column, ie PEGS [to] .length [pegs [to] .count] = pegs [from]. Dength [pegs [from] .count]; pegs [to] .count ; again to redraw a screen according to the data structure. Give a complete program as follows: / ************************************************** * Normal operation: Hanoi -n Return exit_failure;} autoflag = true; break; case 'h': case '?': case ':': usage (); exit (0);} initscr (); if (HAS_COLORS ()) {INT i; int BG = color_black; start_color (); if (use_default_colors () == OK) BG = -1; for (i = 0; i <9; i ) init_pair (i 1, bg, tilecolour [i]);} CBREAK (); / * LINES and COLS are Curses internal variables for storing the number of rows of the current terminal and the number of columns * / if (Lines <24 | COLS <80) / * standard terminals of 24 lines * / { Endwin (); fprintf (stderr, "Current less than 24x80 / n"); Return EXIT_FAILURE;} IF (Autoflag) {CURS_SET (0); Leaveok (stdscr, true);} initTILES (NTILES); DisplayTILES (); if ( AutoFlag) {DO {noecho (); Automove (0, 2, ntiles);} while (! Solved (ntiles)); Sleep (2);} else {echo (); for (;;) {IF (getmove & Fromcol, & Tocol) Break; IF (InvalidMove (fromcol, Tocol) {mvaddstr (statusline, 0, "mobile invalid !!"); refresh (); beep (); Sleep (2); continue;} makemove (fromcol , Tocol); if (ntiles)) {mvintw (statusline, 0, "Congratulations !! Congratulations !! You use% D to win", nmoves); refresh (); SLEEP (5); break;}} } endwin (); return exit_success;} static int invalidmove T from, int to) {IF (from> = npegs) Return True; if (from <0) Return True; if (to> = npegs) Return True; if (to <0) return true; if (from == TO) RETURN TRUE; if (! PEGS [from] .count) Return True; if (PEGS [to] .count && pegs [from] .length [pegs [from] .count - 1]> pegs [to] .length [PEGS [to] .count - 1]) Return true; return false;} static void inittiles (int NTILES) {Int size, slotno; for (size = ntiles * 2 1, slotno = 0; size> = 3; Size - = 2) PEGS [0] .length [slotno ] = size; pegs [0] .count = ntiles; pegs [1] .count = 0; PEGS [2] .count = 0; } static void displaytiles (void) {Int line, peg, slotno; char tilebuf [buffs]; ERASE (); init_pair (20, color_magenta, color_black); AttRset (Color_Pair (20) | a_bold); mvaddstr (1, 25, "Hanno Tag Game"); AttRset (A_NORMAL); MVPrintW (18, 30, "Current Drawn:"); Init_Pair (21, Color_red, Color_Black); AttRset (Color_Pair (21) | A_BOLD); MVPrintw (18, 41, "% D", nmoves); attrset (a_normal); attst (a_reverse); mvaddstr (Baseline, 8, "); for (line = Topline; line 0 ' 1); refresh (); Napms (500); Move (statusline, 0); clrtoeol (); refresh (); return false;} static void makemove (int from, int to) {PEGS [from]. Count -; pegs [to] .length [pegs [to] .count] = pegs [from]. Dength [pegs [from] .count]; pegs [to] .count ; nmoves ; displayTILES ();} static void Automove (int from, int to, int num) {if (num == 1) {Makemove (from, to); Napms (500); Return;} Automove (from, Other (from, to), NUM - 1) Makemove (from, to); Napms (500); Automove (Other (from, to), TO, NUM - 1);} static int solid (int NumTILES) {INT i; for (i = 1; i Exit <1> - <3> Mobile"); attst (a_normal); mvaddstr (statusline, 0, "Next: From"); CLRTOEOL (); refresh (); * From = getch (); if (* from == 'q') || (* from == 'q')) Return True; * from - = ('0' 1); addstr ("arrival) Clrtoeol (); refresh (); * to = getch (); if ((* to == 'q') || (* to == 'q')) Return True; * to - = ('