/*******************************************************************************************\
计算机胜时画最后一个子,但人赢时却不画最后的黑子 ???????????
还有智能化需改进
2006.2.16 21:34
\********************************************************************************************/
/* */
#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
#include <bios.h>
#include <time.h>
#include <math.h>
#include <conio.h>
#define PAN_X 120 /*棋盘初始位置,左上角坐标(120,70) */
#define PAN_Y 70
#define MAX 15
#define NN 7 /* 8:趋向防守,7:趋向进攻*/
#define A 1 /*各边代号*/
#define B 2
#define NONE 0
void kongpan(); /*画棋盘 */
void baizi(); /*画棋子 */
void xiangying(); /*键盘响应*/
void init(); /*初始化 */
void game(); /*游戏过程*/
void load(); /*读取游戏*/
int checka(int ); /*检查是否结束*/
void save(); /*保存游戏*/
int menu(int x); /*菜单 */
void self(); /*智能化 */
int a[MAX][MAX]; /*棋子状况 0-无 1-白 2-黑*/
int stepa=0,stepb=0; /*各方步数*/
int white_x=5,white_y=7; /*白方光标*/
int black_x=7,black_y=7; /*黑方光标*/
int self_control=0; /*二人对战*/
time_t *tim,begin,tim_a,tim_b;
main()
{
int gdriver=DETECT,gmode ; /*初始化显示模式*/
registerbgidriver(EGAVGA_driver); /* bgiobj egavga / tlib lib\graphics.lib+egavga*/
initgraph(&gdriver,&gmode,"");
cleardevice();
settextstyle(DEFAULT_FONT,HORIZ_DIR,2);
menu(0);
}
void init() /*初始化数据*/
{
int i,j ;
begin=time(tim); /* 开始记时时刻 */
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++) a[i][j]=0 ; /* 清空棋盘 状态 */
stepa=0;stepb=0 ; /* 下棋步数清零 */
white_x=5;white_y=7 ; /* 白方初始位置 */
black_x=7;black_y=7 ; /* 黑方初始位置 */
tim_a=0 ;tim_b=0 ;
game();
}
void game()
{
cleardevice(); /*死循环*/
while(1)
{
kongpan();
baizi();
if (checka(1)) menu(1); /* 只有进入menu才能选择退出循环 */
if (checka(2)) menu(2);
xiangying();
}
}
/* 菜单 兼报胜负 0-无 2- 黑方胜 1- 白方胜*/
int menu(int x)
{
int key ;
if(x==0)cleardevice();
setcolor(YELLOW);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,6);
switch(x)
{
case 2: if(self_control==0)outtextxy(40,22,"White Side-^Q^-Winner");
else outtextxy(40,22,"Computer ^Q^ Winner"); break;
case 1: outtextxy(40,22,"Black Side-^Q^-Winner"); break;
}
if(x!=0) {key=bioskey(0); cleardevice();}
setcolor(YELLOW);
settextstyle(GOTHIC_FONT,HORIZ_DIR,8);
outtextxy(70,90,"Five Checkers");
setcolor(GREEN);
settextstyle(GOTHIC_FONT,HORIZ_DIR,2);
outtextxy(150,180,"**************************************");
outtextxy(150,350,"**************************************");
setcolor(GREEN);
settextstyle(GOTHIC_FONT,VERT_DIR,2);
outtextxy(149,188,"********************");
outtextxy(457,188,"********************");
setcolor(GREEN);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,1);
outtextxy(150,370,"Compiled Chuwenbo in XiAndianzi ");
outtextxy(150,400,"All rights reserved @ 2005.5");
setcolor(MAGENTA);
settextstyle(SMALL_FONT,HORIZ_DIR,8);
outtextxy(170,200,"F1. Game Start");
outtextxy(170,230,"F2. V.s. Mode");
outtextxy(170,260,"F3. Save The Game");
outtextxy(170,290,"F4. Load The Game");
outtextxy(170,320,"F5. Exit");
while(1)
{
key=bioskey(0); /* printf("%d",key); 检查键盘码 */
switch(key)
{
case 0x3b00 : self_control=1 ; init();
case 0x3c00 : self_control=0 ; init();
case 0x3d00 : save();
case 0x3e00 : load();
case 0x3f00 : exit(0);
}
}
}
/* ********************智能化部分********************** */
void self( const int tempx,const int tempy )
{
int i,j,k,p,m,n,max=0 ;
int b[MAX][MAX],c[MAX][MAX],q_temp ;
for(i=0;i<MAX;i++)for(j=0;j<MAX;j++) /*在空位(0)上加权为1 */
{
if(a[i][j]==0) b[i][j]=1 ; else b[i][j]=0 ;
}
/*在黑方走子的周围加权为3*/
if(a[tempx-1][tempy]==0) b[tempx-1][tempy]+=1 ; /*左*/
if(a[tempx+1][tempy]==0) b[tempx+1][tempy]+=1 ; /*右*/
if(a[tempx][tempy+1]==0) b[tempx][tempy+1]+=1 ; /*上*/
if(a[tempx][tempy-1]==0) b[tempx][tempy-1]+=1 ; /*下*/
if(a[tempx-1][tempy+1]==0) b[tempx-1][tempy+1]+=1 ; /*左上*/
if(a[tempx-1][tempy-1]==0) b[tempx-1][tempy-1]+=1 ; /*左下*/
if(a[tempx+1][tempy+1]==0) b[tempx+1][tempy+1]+=1 ; /*右上*/
if(a[tempx+1][tempy-1]==0) b[tempx+1][tempy-1]+=1 ; /*右下*/
for(i=0;i<MAX;i++) for(j=0;j<MAX;j++) c[i][j]=b[i][j]; /* c[][]用于对白子做类似加权操作 */
/* 此空位a[tempx][tempy]周围为黑子, if( a[m][n]==2 ) b[i][j]++ ;*/
for(i=0;i<MAX;i++) for(j=0;j<MAX;j++)
{
q_temp=0 ; m=i ; n=j ;
while(b[i][j]!=0) /* 空位 */
{
m--; n--;
if(m<0||m==MAX||n<0||n==MAX) /* 范围之外 */
{
if(q_temp>b[i][j]) b[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==1)
{
if(q_temp>b[i][j]) b[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(b[i][j]>=NN) q_temp+=20 ;
if(b[i][j]>=20+NN)q_temp+=9000 ;
}
m=i ; n=j ;
while(b[i][j]!=0)
{
m++; n++;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==1)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(b[i][j]>=NN) q_temp+=20 ;
if(b[i][j]>=20+NN)q_temp+=9000 ;
}
m=i ; n=j ; q_temp=0 ;
while(b[i][j]!=0)
{
m++; n--;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==1)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(b[i][j]>=NN)q_temp+=20 ;
if(b[i][j]>=20+NN)q_temp+=9000 ;
}
m=i ; n=j ;
while(b[i][j]!=0)
{
m--; n++;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==1)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(b[i][j]>=NN)q_temp+=20 ;
if(b[i][j]>=20+NN)q_temp+=9000 ;
}
m=i ; n=j ; q_temp=0 ;
while(b[i][j]!=0) /* 左 */
{
m--;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>b[i][j])b[i][j]=q_temp ;
break ;
}
if(a[m][n]==0||a[m][n]==1)
{
if(q_temp>b[i][j])b[i][j]=q_temp ;
break ;
}
q_temp+=2 ;
if(b[i][j]>=NN)q_temp+=20 ;
if(b[i][j]>=20+NN)q_temp+=9000 ;
}
m=i ; n=j ;
while(b[i][j]!=0)
{
m++;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>b[i][j])b[i][j]=q_temp ;
break ;
}
if(a[m][n]==0||a[m][n]==1)
{
if(q_temp>b[i][j])b[i][j]=q_temp ;
break ;
}
q_temp+=2 ;
if(b[i][j]>=NN)q_temp+=20 ;
if(b[i][j]>=20+NN)q_temp+=9000 ;
}
m=i ; n=j ; q_temp=0 ;
while(b[i][j]!=0)
{
n++;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==1)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(b[i][j]>=NN)q_temp+=20 ;
if(b[i][j]>=20+NN)q_temp+=9000 ;
}
m=i ; n=j ;
while(b[i][j]!=0)
{
n--;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==1)
{
if(q_temp>b[i][j])b[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(b[i][j]>=NN)q_temp+=20 ;
if(b[i][j]>=20+NN)q_temp+=9000 ;
}
}
/*白子加权c[i][j]******************** if( a[m][n]==1 ) c[i][j]++ ;*/
for(i=0;i<MAX;i++) for(j=0;j<MAX;j++)
{
m=i ; n=j ; q_temp=0 ;
while(c[i][j]!=0)
{
m--; n--;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==2)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(q_temp>=NN) q_temp+=100 ;
if(q_temp>=100+NN)q_temp+=500 ;
}
m=i ; n=j ;
while(c[i][j]!=0)
{
m++; n++;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==2)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(q_temp>=NN)q_temp+=100 ;
if(q_temp>=100+NN)q_temp+=500 ;
}
m=i ; n=j ; q_temp=0 ;
while(c[i][j]!=0)
{
m++; n--;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==2)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(q_temp>=NN)q_temp+=100 ;
if(q_temp>=100+NN)q_temp+=500 ;
}
m=i ; n=j ;
while(c[i][j]!=0)
{
m--; n++;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==2)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(q_temp>=NN) q_temp+=100 ;
if(q_temp>=100+NN)q_temp+=500 ;
}
m=i ; n=j ; q_temp=0 ;
while(c[i][j]!=0) /* 左 */
{
m--;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==2)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(q_temp>=NN)q_temp+=100 ;
if(q_temp>=100+NN)q_temp+=500 ;
}
m=i ; n=j ;
while(c[i][j]!=0)
{
m++;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==2)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(q_temp>=NN)q_temp+=100 ;
if(q_temp>=100+NN)q_temp+=500 ;
}
m=i ; n=j ; q_temp=0 ;
while(c[i][j]!=0)
{
n++;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==2)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(q_temp>=NN)q_temp+=100 ;
if(q_temp>=100+NN)q_temp+=500 ;
}
m=i ; n=j ;
while(c[i][j]!=0)
{
n--;
if(m<0||m==MAX||n<0||n==MAX)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
if(a[m][n]==0||a[m][n]==2)
{
if(q_temp>c[i][j])c[i][j]=q_temp ; break ;
}
q_temp+=2 ;
if(q_temp>=NN) q_temp+=100 ;
if(q_temp>=100+NN)q_temp+=500 ;
}
}
/*白子加权c[i][j] if( a[m][n]==1 ) c[i][j]++ ;*/
for(i=0;i<MAX;i++) /*扫描b[][],c[][]找权值最大位的位置(i,j)*/
for(j=0;j<MAX;j++)
{
if(b[i][j]>max) { max=b[i][j]; white_x=i ; white_y=j ; }
if(c[i][j]>max) { max=c[i][j]; white_x=i ; white_y=j ; }
if(b[i][j]==max) /* 使尽量棋子向中心靠 */
if( (i-7)*(i-7)+(j-7)*(j-7)<(white_x-7)*(white_x-7)+(white_y-7)*(white_y-7) ){ white_x=i ; white_y=j ;}
if(c[i][j]==max)
if( (i-7)*(i-7)+(j-7)*(j-7)<(white_x-7)*(white_x-7)+(white_y-7)*(white_y-7) ){ white_x=i ; white_y=j ;}
}
a[white_x][white_y]=2 ;/* 计算机为白方 */
stepa = stepa+1 ;
tim_a = time(tim)-begin-tim_b ;
return ;
}
/* ********************智能化部分********************** */
void save()
{
int i,j ;
char fname[13];
char c= 'n';
FILE *fp ;
while(c=='n')
{
setcolor(GREEN);
outtextxy(180,270,"save filename:");
setcolor(YELLOW);
gotoxy(42,19);
scanf("%s",fname);
if((fp=fopen(fname,"r"))!=NULL)
{
gotoxy(50,19);
printf("Overwrite %s y/n?",fname);
c=getche();
if(c=='y')
{
fclose(fp);
fp=fopen(fname,"w");
}
}
else
{
fclose(fp);
fp=fopen(fname,"w");
c='y';
}
}
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++) fprintf(fp,"%d",a[i][j]);
fprintf(fp,"%d%d",stepa,stepb);
fprintf(fp,"%d%d",white_x,white_y);
fprintf(fp,"%d%d",black_x,black_y);
fprintf(fp,"%d%d",tim_a,tim_b);
fclose(fp);
menu(0);
}
void load()
{
int i,j ;
char fname[13];
FILE *fp ;
setcolor(GREEN);
outtextxy(175,305,"load filename:");
gotoxy(42,21); scanf("%s",fname);
if((fp=fopen(fname,"r"))==NULL)
{
outtextxy(200,100,"File not found"); getch(); menu(0);
}
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++) a[i][j] =(int)(fgetc(fp))-48 ;
stepa = (int)(fgetc(fp))-48 ; stepb = (int)(fgetc(fp))-48 ;
white_x=(int)(fgetc(fp))-48 ; white_y=(int)(fgetc(fp))-48 ;
black_x=(int)(fgetc(fp))-48 ; black_y=(int)(fgetc(fp))-48 ;
tim_a = (int)(fgetc(fp))-48 ; tim_b = (int)(fgetc(fp))-48 ;
fclose(fp);
game();
}
int checka(int k) /* 对整个棋盘状态扫描判断 */
{
int i,j,m,n,p,q=0 ;
for(i=0;i<MAX;i++) /* 横竖判满 */
{
q=0 ; p=0 ;
for(j=0;j<MAX;j++)
{
if(a[i][j]==k) q++;
if(a[j][i]==k) p++;
if( q>=5||p>=5 ) return k;
if(a[i][j]!=k) q=0 ;
if(a[j][i]!=k) p=0 ;
}
}
/*斜判满*/
for(i=0;i<MAX;i++) for(j=0;j<MAX;j++)
{
q=0 ; p=0 ; m=i ; n=j ;
while(a[m][n]==k)
{
q++; m--; n--;
if(m<0||m==MAX||n<0||n==MAX) break ; /* 在范围之外 */
}
m=i+1 ; n=j+1 ;
while(a[m][n]==k)
{
q++; m++; n++;
if(m<0||m==MAX||n<0||n==MAX) break ;
}
m=i ; n=j ;
while(a[m][n]==k)
{
p++; m++; n--;
if(m<0||m==MAX||n<0||n==MAX) break ;
}
m=i-1 ; n=j+1 ;
while(a[m][n]==k)
{
p++; m--; n++;
if(m<0||m==MAX||n<0||n==MAX) break ;
}
if(q>=5||p>=5) return k;
}
return 0;
}
void xiangying()
{
int key,i;
char ti[40];
time_t temp ;
while(1)
{
setcolor(RED);
gotoxy(3,MAX);
if(self_control==0)printf("%4d",tim_a);
gotoxy(70,MAX);
printf("%4d",tim_b);
if(stepa<stepb) /* 白方下子时画白方的头像(左边) */
{
circle(PAN_X-80,PAN_Y+90,28);
arc(PAN_X-60,PAN_Y+70,-50,140,10); /* 右耳朵 */
arc(PAN_X-100,PAN_Y+70,40,230,10); /* 左耳朵 */
circle(PAN_X-68,PAN_Y+77,6); /* 眼睛 */
circle(PAN_X-92,PAN_Y+77,6);
for(i=0;i<8;i++)ellipse(PAN_X-80,PAN_Y+100,0,360,i,i-2);/* 嘴巴 */
}
else
{
circle(PAN_X+445,PAN_Y+90,28);
arc(PAN_X+465,PAN_Y+70,-50,140,10);
arc(PAN_X+425,PAN_Y+70,40,230,10);
circle(PAN_X+457,PAN_Y+77,6);
circle(PAN_X+433,PAN_Y+77,6);
for(i=0;i<8;i++)ellipse(PAN_X+445,PAN_Y+100,0,360,i,i-2);
}
key=bioskey(0); /* printf("%d",key);*/
switch(key)
{
case 0x1177 : white_y=(white_y>0)?--white_y:14 ; return ;
case 0x1f73 : white_y=(white_y<14)?++white_y:0 ; return ;
case 0x1e61 : white_x=(white_x>0)?--white_x:14 ; return ;
case 0x2064 : white_x=(white_x<14)?++white_x:0 ; return ;
case 0x4800 : black_y=(black_y>0)?--black_y:14 ; return ;
case 0x5000 : black_y=(black_y<14)?++black_y:0 ; return ;
case 0x4b00 : black_x=(black_x>0)?--black_x:14 ; return ;
case 0x4d00 : black_x=(black_x<14)?++black_x:0 ; return ;
case 0x3920 : /* 二人战时 白方用 SPACE 确定,智能化时总是无效 */
if(self_control==1 || stepa>=stepb||a[white_x][white_y]!=0) return ;
else
{
a[white_x][white_y]=2 ;
stepa=stepa+1 ;
tim_a=time(tim)-begin-tim_b ;
return ;
}
case 0x1c0d : /* 黑方用 ENTER 确定 */
if(stepa<stepb||a[black_x][black_y]!=0) return ; /* 无效着子,直接返回 */
else /* 黑方无效着子条件:黑方下的步数多,这个位置不是空位,*/
{
a[black_x][black_y]=1 ;
stepb=stepb+1 ;
tim_b=time(tim)-begin-tim_a ;
if(self_control==1) { /* 智能化时计算机着子 */
if (checka(1)) menu(1);
if (checka(2)) menu(2);
self(black_x,black_y);
}
return ;
}
case 0x011b : menu(0);
default : key=bioskey(0); /*没有按键或者按其它键时*/
}
}
}
void baizi()
{
int i,j,p ;
setcolor(YELLOW);
rectangle((PAN_X+white_x*25)-12,(PAN_Y+12+white_y*25)-24,(PAN_X+white_x*25)+12,(PAN_Y+white_y*25)+12);
setcolor(BLACK);
rectangle((PAN_X+black_x*25)-12,(PAN_Y+12+black_y*25)-24,(PAN_X+black_x*25)+12,(PAN_Y+black_y*25)+12);
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
{
if(a[i][j]==NONE) continue ;
if(a[i][j]==A)
{
setcolor(BLACK);
for(p=0;p<12;p++) circle(PAN_X+i*25,PAN_Y+j*25,p);
}
else
{
setcolor(YELLOW);
for(p=0;p<12;p+=1) circle(PAN_X+i*25,PAN_Y+j*25,p);
}
}
}
void kongpan()
{
int i,j ;
setbkcolor(BLACK);
bar3d(PAN_X-30,PAN_Y-30,PAN_X+380,PAN_Y+380,7,5);
setcolor(RED);
bar3d(PAN_X-120,PAN_Y+30,PAN_X-40,PAN_Y+180,2,1);
bar3d(PAN_X+400,PAN_Y+30,PAN_X+490,PAN_Y+180,2,1);
setpalette(WHITE,2);
setcolor(YELLOW);
for(i=0;i<MAX;i++)
{
line(PAN_X+25*i,PAN_Y,PAN_X+25*i,PAN_Y+350);
line(PAN_X,PAN_Y+25*i,PAN_X+350,PAN_Y+25*i);
}
for(i=0;i<4;i++)
{
circle(PAN_X+175,PAN_Y+175,i);
circle(PAN_X+75,PAN_Y+75,i);
circle(PAN_X+275,PAN_Y+275,i);
circle(PAN_X+75,PAN_Y+275,i);
circle(PAN_X+275,PAN_Y+75,i);
}
}
评论