In this program, the image cannot be displayed due to window size adjustment. The signal function is used to control the signal of the incoming layer...
I wanted to re-display the winning or losing results in a new window, but later I found it was not easy to use. It would be better to write a graphic interface that is both convenient and beautiful, the reason why I used the curses library is that I mainly wanted to focus on the core part of iwuziqi AI and some network socket functions and multithreading, so the image part was omitted, it is expected that after most of the expected functions are completed, I will re-port the game to QT or GTK using C ++.
My first version is 1.0, which is the second version: 2.0.
/* This file is WuZiGame source code http://www.baidu.com application launcher, compatible with GNU/Linux and most other POSIX systems Copyright (C) 2013-2014 Sam Brown version 2.0 This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Sam Brown E-mail: zzulion@gamil.com */ #include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <signal.h>#include <ncurses.h>typedef struct stack{int y, x;}stack;struct {int top, left;int y, x;int board[15][15];int white_or_black;stack S[521];int s_top;int flag;}g;void draw_border( void );bool start( void );void draw_grid( void );void handle_signal( int signum );void handle_win( int signum );void show_cursor(void);void redraw_all( void );void move_step( void ); void draw_piece( void ); void regret( void );int win( int cal );void redraw_win( int flag );//WINDOW *create_newwin( int height, int width, int starty, int startx );//void destroy_win( WINDOW *local_win );void black_win( void );void white_win( void ); int main(){int key;again:if( !start() ){fprintf( stderr, "Error starting up ncurses!\n");return 1;}signal( SIGWINCH, (void (*)(int))handle_signal );memset( g.board, 0, sizeof(g.board) );g.y = 7; g.x = 7;g.white_or_black = 0;g.s_top = 0;redraw_all( );while( 1 ) { refresh(); key = getch(); switch( key ) { case KEY_LEFT: /* move left */ --g.x;if( g.x >= 0 && g.x <= 14 && g.y >= 0 && g.y <= 14 )move_step();else++g.x;break; case KEY_RIGHT: /* move right */ ++g.x;if( g.x >= 0 && g.x <= 14 && g.y >= 0 && g.y <= 14 )move_step();else--g.x; break; case KEY_UP: /* move up */ --g.y; if( g.x >= 0 && g.x <= 14 && g.y >= 0 && g.y <= 14 )move_step(); else++g.y; break; case KEY_DOWN: /* move down */ ++g.y;if( g.x >= 0 && g.x <= 14 && g.y >= 0 && g.y <= 14 )move_step(); else--g.y; break; case 32: /* draw the piece by press space */ if( g.x >= 0 && g.x <= 14 && g.y >= 0 && g.y <= 14 && !g.board[g.y][g.x] ) { g.flag = 0; draw_piece( ); g.flag = win( 0 ); } if( g.flag == 1 || g.flag == 2 ) {if( g.flag == 1 ){black_win();endwin();goto again;}if( g.flag == 2 ){white_win();endwin();goto again;} } break; case 'q': /* press q to quit */ endwin(); exit( 0 ); break; case 'n': /* new game, return to begin */ endwin(); goto again; case 'r': /* regret the piece you put */ regret( ); break; // case 't': // goto test; } }return 0;}void regret( void ){if( g.s_top == 0 )return ;else{g.y = g.S[(g.s_top)-1].y;g.x = g.S[(g.s_top)-1].x;move_step();g.board[g.y][g.x] = 0;printw( "." );move_step();}g.s_top--;}void draw_piece( void ){ char ch1 = 'X', ch2 = 'O'; if( (g.white_or_black++)%2 ) { g.S[g.s_top].y = g.y; g.S[g.s_top].x = g.x; g.s_top++; addch( ch1 ); move_step(); g.board[g.y][g.x] = 1; } else { g.S[g.s_top].y = g.y; g.S[g.s_top].x = g.x; g.s_top++; addch( ch2 ); move_step(); g.board[g.y][g.x] = 2; } }void move_step( void ) { show_cursor();} void redraw_all(){endwin();refresh();clear();draw_border();draw_grid();show_cursor();refresh();}void show_cursor(void){ // restore cursor's location move(g.top + g.y, g.left +2*(g.x) );}void draw_border( void ){int maxy, maxx, i;getmaxyx( stdscr, maxy, maxx );if( has_colors() )attron( COLOR_PAIR(1) );for( i = 0; i <= maxx; i++ ){mvaddstr( 0, i, " " );mvaddstr( maxy-1, i, " " );}mvaddstr( 0, maxx/2-10, "Five-in-a-row");mvaddstr( maxy-1, 1, "[N]ew Game [R]egert " );mvaddstr( maxy-1, maxx-13, "[Q]uit Game" ); attroff( COLOR_PAIR(1) );}void draw_grid( void ){int maxy, maxx, i, j, top, left;getmaxyx( stdscr, maxy, maxx );g.top = maxy/2 - 7;g.left = maxx/2 - 30;top = g.top;left = g.left;for( i = 0; i < 15; i++ ){for( j = 0; j < 15; j++ ){if( !g.board[i][j] )mvaddstr( top+i, left+2*j, ". ");if( g.board[i][j] == 1 )mvaddstr( top+i, left+2*j, "X ");if( g.board[i][j] == 2 )mvaddstr( top+i, left+2*j, "O ");}addstr( "\n" );}}void handle_signal( int signum ){if( signum == SIGWINCH )redraw_all();signal( signum, (void(*)(int))handle_signal );}bool start( void ){if( initscr() == NULL )return false;if( has_colors() == FALSE ){endwin();fprintf( stderr, "Your terminal does not support coloer\n");exit(0);}else{if( start_color() == ERR ){endwin();return false;}if( init_pair( 1, COLOR_RED, COLOR_YELLOW ) == ERR ){endwin();return false;}}if( noecho() == ERR ){endwin();return false;}if( raw() == ERR ){endwin();return false;}if( keypad(stdscr, true) == ERR ){endwin();return false;}//wait 1000 ms at a time for inputtimeout(1000);return true;}int win( int cal ) { int i, j, k; int s = 20; // col line for( i = g.y, j = 0; j < 4; j++ ) { if( g.board[++i][g.x] == g.board[g.y][g.x] ) { if( i >= 0 && i <= 14 ) cal++; } else break; } for( i = g.y, j = 0; j < 4; j++ ) { if( g.board[--i][g.x] == g.board[g.y][g.x] ) { if( i >= 0 && i <= 14 ) cal++; } else break; } if( cal+1 >= 5 ) return g.board[g.y][g.x]; cal = 0; //row line for( i = g.x, j = 0; j < 4; j++ ) { if( g.board[g.y][++i] == g.board[g.y][g.x] ) { if( i >= 0 && i <= 14 ) cal++; } else break; } for( i = g.x, j = 0; j < 4; j++ ) { if( g.board[g.y][--i] == g.board[g.y][g.x] ) { if( i >= 0 && i <= 14 ) cal++; } else break; } if( cal+1 >= 5 ) return g.board[g.y][g.x]; cal = 0; // oblique line one for( i = g.y, j = g.x, k = 0; k < 4; k++ ) { if( g.board[++i][--j] == g.board[g.y][g.x] ) { if( i >= 0 && i <= 14 && j >= 0 && j <= 14 ) cal++; } else break; } for( i = g.y, j = g.x, k = 0; k < 4; k++ ) { if( g.board[--i][++j] == g.board[g.y][g.x] ) { if( i >= 0 && i <= 14 && j >= 0 && j <= 14 ) cal++; } else break; } if( cal+1 >= 5 ) return g.board[g.y][g.x]; cal = 0; // oblique line two for( i = g.y, j = g.x, k = 0; k < 4; k++ ) { if( g.board[--i][--j] == g.board[g.y][g.x] ) { if( i >= 0 && i <= 14 && j >= 0 && j <= 14 ) cal++; } else break; } for( i = g.y, j = g.x, k = 0; k < 4; k++ ) { if( g.board[++i][++j] == g.board[g.y][g.x] ) { if( i >= 0 && i <= 14 && j >= 0 && j <= 14 ) cal++; } else break; } if( cal+1 >= 5 ) return g.board[g.y][g.x]; cal = 0; return 0; } void black_win( void ){int maxy, maxx;/*WINDOW *my_win;int startx, starty, width, height;height = 3;width = 10;starty = (LINES-height)/2;startx = (COLS-width)/2;my_win = create_newwin( height, width, starty, startx );wprintw( my_win, "black win!" );getchar();getchar();destroy_win( my_win ); */clear();getmaxyx( stdscr, maxy, maxx );signal( SIGWINCH, (void (*)(int))handle_win );mvprintw( maxy/2, maxx/2-5, "black win!!" );mvprintw( maxy/2+1, maxx/2-11, "press any key to continue..." );refresh();getchar();}void white_win( void ){int maxx, maxy;/*WINDOW *my_win;int startx, starty, width, height;height = 3;width = 10;starty = (LINES-height)/2;startx = (COLS-width)/2;my_win = create_newwin( height, width, starty, startx );wprintw( my_win, "white win!" );getchar();getchar();destroy_win( my_win );*/clear();getmaxyx( stdscr, maxy, maxx );signal( SIGWINCH, (void (*)(int))handle_win );mvprintw( maxy/2, maxx/2-5, "white win!!" );mvprintw( maxy/2+1, maxx/2-11, "press any key to continue..." );refresh();getchar();}/*WINDOW *create_newwin( int height, int width, int starty, int startx ){WINDOW *local_win;local_win = newwin( height, width, starty, startx );wrefresh( local_win );return local_win;}void destroy_win( WINDOW *local_win ){wrefresh(local_win);delwin( local_win );}*/void redraw_win( int flag ){int maxy, maxx;clear();refresh();getmaxyx( stdscr, maxy, maxx );if( flag == 1 ){mvprintw( maxy/2, maxx/2-5, "black win!!" );mvprintw( maxy/2+1, maxx/2-11, "press any key to continue..." );}else{mvprintw( maxy/2, maxx/2-5, "white win!!" );mvprintw( maxy/2+1, maxx/2-11, "press any key to continue..." );}refresh();}void handle_win( int signum ){if( signum == SIGWINCH )redraw_win( g.flag );signal( signum, (void(*)(int))handle_win );}