#include<stdio.h> #include<conio.h>
/*程序用了很多的全局变量,也是没办法的,因为这些变量在程序运行时都占用,为了不必要的函数参数接口,就把许多变量设为全局变量*/ /*所有1表示player1,2表示player2,*/ /*程序增加了config,可以自己定义键位设置 config是相当独立的, 我用2个char存储一个键位,
默认键位设置: 0 1 2 3 4 5 6 7 8 9 功能 对方确认 上 左 下 右 己方悔棋 对方悔棋 己方认输 对方认输 己方确认 p1 + w a s d h - r * 回车 p2 回车 上 左 下 右 - h * r +
*/ /*关于全局变量的用途: qp[][]:把需要打印的图象储存起来,方便打印 cmp[][]:存储键位设置 strdef[][]:默认键位设置 qps[][]:真实的棋盘,0 空 1 p1 2 p2 lsqp[][]:能下的地方 1 能下 0 不能下 用来计算是否结束 和 打印能下的地点 qpold[][][]储存旧的棋盘,悔棋用//可以做到无限悔棋,我觉得没意思,就只能悔一步 x[] y[] 光标要移动到的位置,比如说我下在5,5 当对方下时光标一开始在5,5 xold[] yold[] 储存旧的光标位置//好象没用,时间长了也不太好改 xn[]能下的数目,双方都为0时结束,统计棋子数目 m[]盘数 */ /*程序显示能下的地方,假如觉得不好,删除有关refresh3()的语句就行了*/ char qp[25][26],cmp[3][21],strdef[3][21]={{0},{'+',0,'w',0,'a',0,'s',0,'d',0,'h',0,'-',0,'r',0,'*',0,'\r',0,0},{'\r',0,0,72,0,75,0,80,0,77,'-',0,'h',0,'*',0,'r',0,'+',0,0}}; int qps[10][10],lsqp[10][10],qpold[3][10][10],x[3],y[3],xold[3],yold[3],xn[3],m[3]={0,0,0}; int p,p1; /*p为当前player,p1为对方*/
void csqp(void) /*初始化棋盘*/ {int i,j; for(i=0;i<25;i++)for(j=0;j<25;j++)qp[i][j]=' '; /*qp[][]外壳初始化*/ for(i=0;i<25;i++)qp[i][25]=0; for(i=0;i<25;i+=3) {for(j=0;j<24;j+=3) {qp[i][j]='+';qp[i][j+1]='-';qp[i][j+2]='-';} qp[i][j]='+'; } for(i=1;i<23;i+=3)for(j=0;j<25;j+=3)qp[i][j]=qp[i+1][j]='|'; for(i=0;i<10;i++)for(j=0;j<10;j++){qps[i][j]=0;qpold[p][i][j]=0;} qps[4][4]=qps[5][5]=p1; /*放上棋子*/ qps[4][5]=qps[5][4]=p; qpold[p][4][4]=qpold[p][5][5]=p1; /*初始化悔棋的棋盘 //其实不用*/ qpold[p][4][5]=qpold[p][5][4]=p; xold[p1]=6;yold[p1]=5; x[1]=5;y[1]=4; }
int refresh1(int player) /*计算给定player能下的棋子,放在lsqp[][]中,返回能下的数目*/ { int i,j,m,n,a,b,aoplayer; aoplayer=-player+3; for(i=0;i<10;i++) for(j=0;j<10;j++) lsqp[i][j]=0; for(i=1;i<9;i++) for(j=1;j<9;j++) { if(qps[i][j])continue; for(m=-1;m<2;m++) for(n=-1;n<2;n++) { a=i+m;b=j+n; if(qps[a][b]==aoplayer) { while(qps[a+=m][b+=n]==aoplayer); if(qps[a][b]==player)lsqp[i][j]=1; } } } m=0; for(i=1;i<9;i++) for(j=1;j<9;j++) m+=lsqp[i][j]; return m; }
int hmq(int player) /*返回给定player棋子数目*/ { int i,j,n=0; for(i=1;i<9;i++) for(j=1;j<9;j++) if(qps[i][j]==player) n++; return n; }
void refresh3() /*把当前player能下的地方放到qp[][]中,用来打印*/ { int i,j,m,n; for(i=1;i<9;i++) for(j=1;j<9;j++) { if(!lsqp[i][j]) continue; m=i*3-2; n=j*3-2; qp[m][n]=qp[m+1][n+1]='\\'; qp[m+1][n]=qp[m][n+1]='/'; } }
void refresh2() /*把棋子打印,就是放到qp[][]中,要在refresh3()用,不然把打印能显示下的地方覆盖*/ { int i,j,m,n; for(i=1;i<9;i++) for(j=1;j<9;j++) { m=i*3-2; n=j*3-2; qp[m][n]=qp[m][n+1]=qp[m+1][n]=qp[m+1][n+1]=qps[i][j]==1?'+':qps[i][j]?'o':' '; } }
void hq_(int *hq) /*悔棋处理,谁悔棋,当前player就是谁,把qpold[][][]拷到qps[][]中*/ {int i,j; p=*hq;p1=-p+3; *hq=0; for(i=1;i<9;i++)for(j=1;j<9;j++)qps[i][j]=qpold[p][i][j]; x[p]=xold[p];y[p]=yold[p]; refresh1(p1);refresh1(p); }
char tranf(char ch1,char ch2) /*把接受进来的字符与键位设置比较,返回字符0~9 出错返回数字0*/ {int i;
if(!ch1) {for(i=0;i<10;i++) {if(ch2==cmp[p][i*2+1]){ch1=i+48;break;}} if(i==10)ch1=0; } else {for(i=0;i<10;i++) {if(ch1==cmp[p][i*2]){ch1=i+48;break;}} if(i==10)ch1=0; }
return ch1; }
char sure() /*认输确认,*/ {char ch1,ch2; gotoxy(26,4);clreol();printf("Are you sure?"); ch1=getche();if(!ch1)ch2=getche(); ch1=tranf(ch1,ch2); return ch1; }
void play(int x1,int y1) /*在x1,y1下子 下子前经过确认能下*/ {int i,j,m,n,a,b,x2,y2; x2=x1/3;y2=y1/3;x[p1]=x2;y[p1]=y2;
xold[p]=x[p];yold[p]=y[p]; for(i=1;i<9;i++)for(j=1;j<9;j++)qpold[p][i][j]=qps[i][j]; for(i=-1;i<2;i++)for(j=-1;j<2;j++) {a=m=x2+i+1;b=n=y2+j+1; if(qps[b][a]==p1) { while(qps[b+=j][a+=i]==p1); if(qps[b][a]==p)for(;(m-a)||(n-b);m+=i,n+=j)qps[n][m]=p; } } qps[y2+1][x2+1]=p; }
void go() /*显示谁下子*/ {gotoxy(26,4);clreol(); printf("player%d go!",p); }
void printhead() /*打印信息,有多少子,赢几盘等等*/ { gotoxy(26,1); printf("++ oo\n"); gotoxy(26,2); printf("++ player1:%2d oo player2:%2d\n",hmq(1),hmq(2)); gotoxy(26,3); printf("player1:player2 %d:%d\n",m[1],m[2]); }
void unmake(char str[15],int player) /*config部件 从键位设置中提取player的设置*/ {int i; for(i=0;i<7;i++)str[i]=cmp[player][i+2]; str[8]=cmp[player][10]; str[9]=cmp[player][11]; str[10]=cmp[player][14]; str[11]=cmp[player][15]; str[12]=cmp[player][18]; str[13]=cmp[player][19]; }
void make(char str[15],int player) /*config部件 player设置完了 把这些设置放到键位设置里,不然白设置*/ {int i,aoplayer;aoplayer=-player+3; for(i=0;i<7;i++)cmp[player][i+2]=str[i]; cmp[player][10]=str[8]; cmp[player][11]=str[9]; cmp[player][14]=str[10]; cmp[player][15]=str[11]; cmp[player][18]=str[12]; cmp[player][19]=str[13]; cmp[aoplayer][0]=str[12]; cmp[aoplayer][1]=str[13]; cmp[aoplayer][12]=str[8]; cmp[aoplayer][13]=str[9]; cmp[aoplayer][16]=str[10]; cmp[aoplayer][17]=str[11]; }
void defconfig() /*config部件 假如用默认设置,用这个函数就行了*/ {int i; for(i=0;i<21;i++) {cmp[1][i]=strdef[1][i];cmp[2][i]=strdef[2][i];} }
void config(int player) /*c
onfig部件 设置 不知道怎么回事,右好象不能打印*/ {char ch1,ch2,str[15],a[]="about"; int i,j,flag=1; char pr[7][11]={{"\n\030 "},{"\n\033 "},{"\n\031 "},{"\n\032 "},{"\nhui qi "},{"\nren shu "},{"\nque ding "}}; unmake(str,player); printf("\nplayer%d",player); for(i=0;i<7;i++) {printf(pr[i]); ch1=getche();if(!ch1)ch2=getche();else ch2=0;
if(ch1==27)break; str[i*2]=ch1;str[i*2+1]=ch2; if(i==4) /* 彩蛋 设置键位时敲about就看到了 */ { for(j=0;j<5;j++) if(str[j*2]!=a[j]){flag=0;break;} if(flag){defconfig(); clrscr(); printf("progammed by GW\n"); getche();break; } } } make(str,player); }
void rc() /*config部件 reconfig() 除了方向键,别的不可以重复,否则就要用这个函数了*/ {printf("\nsorry,you must reconfig\n"); config(1);config(2); }
int check(int *flag) /*config部件 检查有没有重复键*/ {char str[3][15]; int i,j,k,l; unmake(str[1],1);unmake(str[2],2); printf("\nchecking......\n"); for(k=1,l=2;k<3;k++,l--) for(i=8;i<14;i+=2)for(j=0;j<14;j+=2) {if(str[k][i]==str[l][j]&&str[k][i+1]==str[l][j+i]) {rc();*flag=0;return;} if(i==j)continue; if(str[k][i]==str[k][j]&&str[k][i+1]==str[k][j+i]) {rc();*flag=0;return;} } printf("pass\n"); }
void isconfig() /*config部件 config主要函数主界面*/ {char ch; int flag=1; defconfig(); if(flag){printf("Do you want to config?\nPress y to config\n"); ch=getche();if(!ch)getche(); if(ch=='y'){config(1);config(2);flag=0;} } while(!flag) {printf("\nDo you want to reconfig?\nPress y to reconfig\nPress d to use default config\nPress any other key to exit config\n"); ch=getche();if(!ch)getche(); flag=1; if(ch=='d'){defconfig();flag=0;} if(ch=='y'){config(1);config(2);flag=0;} check(&flag); } }
void pgo(int *hq,int *rs) /*玩家主界面*/ {int i,j,x1,y1,n; char ch1,ch2;
if(!xn[p]) {xn[p]=refresh1(p);xn[p1]=refresh1(p1);p=p1;p1=-p+3;return;} clrscr();printhead();go();refresh2();refresh3();
x1=x[p]*3;y1=y[p]*3;n=hmq(1)+hmq(2); for(;;) { gotoxy(1,1); for(i=0;i<25;i++) {printf("%s",qp[i]); if(i!=24)printf("\n"); }
gotoxy(x1+2,y1+3); ch1=getche();if(!ch1)ch2=getche(); ch1=tranf(ch1,ch2);
switch(ch1) {case '1':y1=(y1+21)%24;go();break; case '2':x1=(x1+21)%24;go();break; case '3':y1=(y1+3)%24;go();break; case '4':x1=(x1+3)%24;go();break; case '5':if(n<6)break;*hq=p;return; case '6':if(n<6)break;*hq=p1;return; case '7':{ch2=sure(); if(ch2=='9'){*rs=p;return;} else{go();break;} } case '8':{ch2=sure(); if(ch2=='0'){*rs=p1;return;} else{go();break;} } case '9':{ if(!lsqp[y1/3+1][x1/3+1]) {gotoxy(26,4);clreol();printf("It's impossible!");break;} play(x1,y1); xn[p]=refresh1(p);xn[p1]=refresh1(p1); p=p1;p1=-p+3;return; }
} } }
void main() { char ch; int hq,tag=2,rs; int n[2]; isconfig(); for(;;) {if(m[2]||m[1]) {clrscr(); printf("more again?\nPress Enter to continue\n"); ch=getche();if(ch-13)break;} p=-tag+3;p1=-p+3;clrscr();csqp();rs=0;hq=0;
xn[p1]=refresh1(p1);xn[p]=refresh1(p); for(;(xn[2]||xn[1])&&!rs;) {pgo(&hq,&rs);if(hq)hq_(&hq);} n[1]=hmq(1);n[0]=hmq(2);clrscr(); if(rs==2||(rs==0&&n[1]>n[0])) {m[1]++;printf("player1 win!\n");} if(rs==1||(rs==0&&n[0]>n[1])) {m[2]++;printf("player2 win!\n");} if(rs==0&&n[0]==n[1]) printf("draw!\n"); printf("player1:player2 %d:%d\n",n[1],n[0]); printf("player1:player2 %d:%d\n",m[1],m[2]); printf("Press any key to continue\n"); ch=getche();if(!ch)getche(); tag=-tag+3; } }
视频教程列表
文章教程搜索
C语言程序设计推荐教程
C语言程序设计热门教程
|