#include <stdio.h> #include <stdlib.h> #include <ncurses.h> #include <locale.h> #include <time.h> #include <signal.h> #include <unistd.h> #include <sys/time.h> #define StartX 28 //光标起始位置 #define StartY 14 #define INTERVAL 1 //计时间隔 1 秒 #define N 32 //棋子个数 #define COL 75 #define ROW 25 /*************************************************************************** 中国象棋 C语言版 游戏说明:通过键盘上的方向键来控制光标的移动,光标落到棋子上时,按下空格键 即选定要移动的棋子,然后移动光标到目标位置,再按下空格键,即放定棋子。 编译时要加入动态链接库 gcc filename.c -lncurses 作者:ThomasHwak 运行环境: OS X 10.7.4 最后一次修改时间:2013-9-25 版本号:1.0 ***************************************************************************/ typedef struct chess { int x; int y; int prev_x; int prev_y; char *name; } CHESS; //定义棋子结构体,存储棋子的属性 CHESS array[N]; int x=StartX; int y=StartY; int ch=0; //读取键盘字符 int cnt=0; //统计空格按下次数 int i=0,j=0; int second=0; int minute=0; //计时用分钟,秒 int startOrPause=1; int flag=0; int board[ROW][COL]={0}; //保存棋盘坐标 void chess_init(void); //初始化棋子,界面 void menu_show(void); void interface_Init(void); void curse_Init(void); void doAction(int sig); int chess_control(void); void key_check(void); void setMyTimer(int val); void put_chess(void); int check_rule(struct chess current_chess,int x,int y); int check_rule(struct chess current_chess,int x,int y) { int min_x=0; int min_y=0; if(strcmp(current_chess.name,"馬")==0) { if(y>=5 && y<=23 && x>=30 && x<=70) { if(((abs(x-current_chess.x)==5 && abs(y-current_chess.y)==4)) || (abs(x-current_chess.x)==10 && abs(y-current_chess.y)==2)) { if(flag==1) { mvprintw(15,8," "); flag=0; } return 1; } else { attron(A_BOLD); mvprintw(15,8,"馬行一步一尖冲!"); attrset(A_NORMAL); flag=1; return 0; } } else return 0; } if(strcmp(current_chess.name,"車")==0) { if(y>=5 && y<=23 && x>=30 && x<=70) { if(((abs(x-current_chess.x)==0 && abs(y-current_chess.y)%2==0)) || (abs(x-current_chess.x)%5==0 && abs(y-current_chess.y)==0)) { min_x = x<current_chess.x ? x:current_chess.x; min_y = y<current_chess.y ? y:current_chess.y; if(flag==1) { mvprintw(15,8," "); flag=0; } return 1; } else { attron(A_BOLD); mvprintw(15,8,"車行直路任西东!"); attrset(A_NORMAL); flag=1; return 0; } } else return 0; } if(strcmp(current_chess.name,"象")==0 || strcmp(current_chess.name,"相")==0) { if(y>=5 && y<=23 && x>=30 && x<=70) { if((abs(x-current_chess.x)==10 && abs(y-current_chess.y)==4)) { if(flag==1) { mvprintw(15,8," "); flag=0; } return 1; } else { attron(A_BOLD); mvprintw(15,8,"象飞四方营四角!"); attrset(A_NORMAL); flag=1; return 0; } } else return 0; } if(strcmp(current_chess.name,"士")==0 || strcmp(current_chess.name,"仕")==0) { if((y>=5 && y<=9 && x>=45 && x<=55) || (y>=19 && y<=23 && x>=45 && x<=55)) { if((abs(x-current_chess.x)==5 && abs(y-current_chess.y)==2)) { if(flag==1) { mvprintw(15,8," "); flag=0; } return 1; } else { attron(A_BOLD); mvprintw(15,8,"士止相随不出宫!"); attrset(A_NORMAL); flag=1; return 0; } } else return 0; } if(strcmp(current_chess.name,"将")==0 || strcmp(current_chess.name,"帅")==0) { if((y>=5 && y<=9 && x>=45 && x<=55) || (y>=19 && y<=23 && x>=45 && x<=55)) { if((abs(x-current_chess.x)==0 && abs(y-current_chess.y)==2) || (abs(x-current_chess.x)==5 && abs(y-current_chess.y)==0)) { if(flag==1) { mvprintw(15,8," "); flag=0; } return 1; } else { attron(A_BOLD); mvprintw(15,8,"将军不离九宫内!"); attrset(A_NORMAL); flag=1; return 0; } } else return 0; } if(strcmp(current_chess.name,"卒")==0) { if((y>=5 && y<=23 && x>=30 && x<=70)) { if( (abs(x-current_chess.x)==0 && y-current_chess.y==2 ) || (abs(x-current_chess.x)==5 && y-current_chess.y==0 && y>=15)) { if(flag==1) { mvprintw(15,8," "); flag=0; } return 1; } else { attron(A_BOLD); mvprintw(15,8,"小卒过河横竖闯!"); attrset(A_NORMAL); flag=1; return 0; } } else return 0; } if(strcmp(current_chess.name,"兵")==0) { if((y>=5 && y<=23 && x>=30 && x<=70)) { if( (abs(x-current_chess.x)==0 && y-current_chess.y==-2 ) || (abs(x-current_chess.x)==5 && y-current_chess.y==0 && y<=13)) { if(flag==1) { mvprintw(15,8," "); flag=0; } return 1; } else { attron(A_BOLD); mvprintw(15,8,"小卒过河横竖闯!"); attrset(A_NORMAL); flag=1; return 0; } } else return 0; } if(strcmp(current_chess.name,"炮")==0) { if(y>=5 && y<=23 && x>=30 && x<=70) { if(((abs(x-current_chess.x)==0 && abs(y-current_chess.y)%2==0)) || (abs(x-current_chess.x)%5==0 && abs(y-current_chess.y)==0)) { if(flag==1) { mvprintw(15,8," "); flag=0; } return 1; } else { attron(A_BOLD); mvprintw(15,8,"炮需隔子打一子!"); attrset(A_NORMAL); flag=1; return 0; } } else return 0; } } void put_chess(void) { int i=0; for(i=0;i<N;i++) { if(i<=15) mvprintw(array[i].y,array[i].x,array[i].name); else { attron(A_REVERSE); mvprintw(array[i].y,array[i].x,array[i].name); attrset(A_NORMAL); } } } void chess_init(void) { int i=0; int y=0; int x=0; curse_Init(); /*********************** 初始化结构体数组 *******************/ for(i=0;i<N;i++) { if(i==0 || i==8 || i==16 ||i==24) { array[i].name="車"; } if(i==1 || i==7 || i==17 || i==23) { array[i].name="馬"; } if(i==2 || i==6) { array[i].name="象"; } if(i==18 || i==22) { array[i].name="相"; } if(i==3 || i==5) { array[i].name="士"; } if(i==19 || i==21) { array[i].name="仕"; } if(i==4) { array[i].name="将"; } if(i==20) { array[i].name="帅"; } if(i==9 || i==10 ||i==25 ||i==26) { array[i].name="炮"; } if(i==11 || i==12 || i==13 || i==14 ||i==15) { array[i].name="卒"; } if(i==27 || i==28 || i==29 || i==30 || i==31) { array[i].name="兵"; } } /******************** 棋盘上半部分 ********************/ for(i=0,y=5,x=30;x<=70;x+=5,i++) { array[i].x=x; array[i].y=y; board[y][x]=1; } for(i=11,y=11,x=30;x<=70;x+=10,i++) { array[i].x=x; array[i].y=y; board[y][x]=1; } for(i=9,y=9,x=35;x<=65;x+=30,i++) { array[i].x=x; array[i].y=y; board[y][x]=1; } /********************* 棋盘下半部分 *****************/ for(i=16,y=23,x=30;x<=70;x+=5,i++) { array[i].x=x; array[i].y=y; board[y][x]=1; } for(i=25,y=19,x=35;x<=65;x+=30,i++) { array[i].x=x; array[i].y=y; board[y][x]=1; } for(i=27,y=17,x=30;x<=70;x+=10,i++) { array[i].x=x; array[i].y=y; board[y][x]=1; } } void key_check(void) { do { if(startOrPause==-1) setMyTimer(INTERVAL); else setMyTimer(10000); ch=getch(); chess_control(); switch(ch) { case KEY_UP: --y; break; case KEY_DOWN: ++y; break; case KEY_LEFT: --x; break; case KEY_RIGHT: ++x; break; case '\t': x+=7; break; case '\r': startOrPause=0-startOrPause; break; case KEY_BACKSPACE: mvaddch(y,--x,' '); break; case 27: endwin(); exit(1); default: //addch(ch); x=x; break; } move(y,x); }while(1); } int chess_control(void) { if(ch==' ') { if(cnt==1) { if(check_rule(array[i],x,y)==0) { cnt=0; return 0; } for(j=0;j<32;j++) { if(array[j].y==y && array[j].x==x) { if((i<=15 && j<= 15) || (i>=16 && j>=16)) return 0; board[array[j].y][array[j].x]=0; array[j].x=300; //mvprintw(array[j].y,array[j].x,"|"); if(j==4) { attron(A_BLINK); mvprintw(14,8,"黑方胜!"); attrset(A_NORMAL); } if(j==20) { attron(A_BLINK); mvprintw(14,8,"白方胜!"); attrset(A_NORMAL); } } } board[array[i].y][array[i].x]=0; array[i].y=y; array[i].x=x; interface_Init(); if(i<=15) { mvprintw(array[i].y,array[i].x,array[i].name); } else { attron(A_REVERSE); mvprintw(array[i].y,array[i].x,array[i].name); attrset(A_NORMAL); } cnt=0; } else { for(i=0;i<32;i++) { if(array[i].y==y && array[i].x==x && cnt==0) { cnt=1; break; } } } } } void curse_Init(void) { initscr(); cbreak(); nonl(); noecho(); intrflush(stdscr,FALSE); keypad(stdscr,TRUE); refresh(); } void interface_Init(void) { curse_Init(); int rows=0; int cols=30; /************************** 画棋盘 ******************/ for(rows=5;rows<=24;rows=rows+2) //画横线 { move(rows,cols); whline(stdscr,'-',40); } rows=5; for(cols=30;cols<=70;cols=cols+5) { move(rows,cols); wvline(stdscr,'|',19); } move(14,31); whline(stdscr,' ',39); mvprintw(14,37,"楚"); mvprintw(14,43,"河"); mvprintw(14,56,"汉"); mvprintw(14,62,"界"); attron(A_BOLD|A_UNDERLINE); mvprintw(1,47,"中国象棋"); attrset(A_NORMAL); put_chess(); move(y,x); } void menu_show(void) { int k=0; curse_Init(); attron(A_BOLD); mvprintw(8,85,"回车键开始计时"); mvprintw(10,85,"Esc键退出"); attrset(A_NORMAL); mvaddstr(1,75,"╭∩╮(︶︿︶)╭∩╮"); mvaddstr(1,10,"╭∩╮(︶︿︶)╭∩╮"); refresh(); } void doAction(int sig) { curse_Init(); if(second==59) { minute++; second=0; } mvprintw(5,85,"游戏已经开始 %d 分钟 %d 秒",minute,second); second++; interface_Init(); refresh(); signal(SIGALRM,doAction); } void setMyTimer(int val) { struct itimerval value; value.it_value.tv_sec=val; value.it_value.tv_usec=0; value.it_interval.tv_sec=val; //val 秒 value.it_interval.tv_usec=0; signal(SIGALRM,doAction); setitimer(ITIMER_REAL,&value,NULL); } int main(void) { setlocale(LC_ALL,""); menu_show(); chess_init(); interface_Init(); key_check(); return 0; }
Unix 系统下用C语言写的中国象棋程序(使用光标库)
最新推荐文章于 2020-10-16 21:15:50 发布