/***************************************************************************************\
modify at 2006.3.28 编译器:MYTC
\***************************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#define MAX 15
#define OFFSET 8 /* 14*14=196<2^8-1=255 偏移8位足够,而优先级最大也是16 */
#define PAN_X 125 /*棋盘初始位置,左上角坐标(125,75) */
#define PAN_Y 75
#define COMPUTER 1 /*计算机棋子 */
#define PLAYER 2 /*玩家棋子 */
int qp[MAX][MAX]; /*定义棋盘 */
int iswin; /*输赢标记,1=计算机胜,2=玩家胜,0=未分胜负;*/
int key;
struct LIST {
int id;
struct LIST *next;
}*PList=NULL,*CList=NULL; /*定义链表,Plist为玩家棋局链表指针,用于阻击,Clist为计算机棋局链表指针,用于攻击 */
void * mouse_buf;
MOUSE mouse;
/* 恢复图象,每次鼠标一走后,把鼠标覆盖的范围图象恢复 */
void ResumeGraphics(int x,int y,void *p);
/*给图形指针赋值*/
bool GetBuf(int x,int y,int xx,int yy,void *p);
/* 画一颗旗子,不同颜色代表棋手双方 */
void qizi(int px,int py,int color);
/*正方行小框标志当前的有效着子位置 */
void kuang(int px,int py,int color);
static int black_x=MAX,black_y=MAX; /* 预先置初始位置,在画框外 */
static int AddList(struct LIST **List,int add)
{
struct LIST *tmp=*List, **temp=List;
int atemp=add>>OFFSET;
int id;
struct LIST *newlist=malloc(sizeof(*newlist));
if(!newlist) return 1;
while(tmp)
{
id=(tmp->id)>>OFFSET;
if(id<=atemp) break;
if(id>atemp) { temp=&(tmp->next); tmp=tmp->next; }
}
newlist->id=add; newlist->next=tmp; *temp=newlist;
return 0;
}
/*函数获得指定链中最大优先级的值 */
static int GetMax(struct LIST *List) { if(List) return (List->id>>OFFSET); return 0; }
static int GetLast(struct LIST **List) /*函数获得指定链中的链首数据 */
{
if(*List) {
int ret;
struct LIST *temp;
ret=((*List)->id& 0xff); /* 取低字节棋盘位置数据 , 0xff与OFFSET位数一致 */
temp=*List; /* 记住需要销毁的结点,使用的结点销毁 */
*List=(*List)->next;
free(temp);
return ret;
}
return 0;
}
#define DestroyList(L) while(GetLast(&L)) /*宏——销毁链表 */
/*函数探测参数tmp指定的棋盘位置的优先级并加入相应的链表中 */
/*凡进入该函数扫描的点,皆为棋盘上的空位置。我们将在此处分析该位置在棋局中的地位。*/
static int AddTo_List(int tmp)
{
int temp,py,px;
py=tmp/MAX; px=tmp%MAX; /*探测计算机在此位置的优先级 ,tmp=y*MAX+x */
qp[py][px]=COMPUTER;
temp=scan(px,py,0); /*最后一个参数必须为0,否则将进入死循环。 */
AddList(&CList,(temp<=0&&qp[y][x]==play); /*该方向前面没有充足的位置,置标记位为1。这样,我们可以略去无效探测。 */
if(x+5>MAX) side=1 ;
else {
x+=2 ; /*沿该方向向前,跳过第一个与play相等的位置,对前方四个位置进行纪录 */
for(j=0;j<4;j++) { temp[j]=(MAX*y+x); x++; } /*将棋盘位置合成整型数据保存 */
} break ;
}
case 1 :{ /*x--;y--; */
do { x--; y--; }
while(x>=0&&y>=0&&qp[y][x]==play);
if(x+5>MAX||y+5>MAX) side=1 ;
else {
x+=2 ; y+=2 ;
for(j=0;j<4;j++) { temp[j]=(MAX*y+x); x++; y++; }
} break ;
}
case 2 :{ /*y--; */
do {y--; }
while(y>=0&&qp[y][x]==play);
if(y+5>MAX) side=1 ;
else {
y+=2 ;
for(j=0;j<4;j++) { temp[j]=(MAX*y+x); y++; }
} break ;
}
case 3 :{ /*x--;y++; */
do { x--; y++; }
while(x>=0&&yMAX||y-5<0)side=1 ;
else {
x+=2 ; y-=2 ;
for(j=0;j<4;j++) { temp[j]=(MAX*y+x); x++; y--; }
} break ;
}
case 4 :{ /*x++; */
do { x++; }
while(x=0&&qp[y][x]==play);
if(x-5<0||y+5>MAX)side=1 ;
else {
x-=2 ; y+=2 ;
for(j=0;j<4;j++) { temp[j]=(MAX*y+x); x--; y++; }
} break ;
}
case 6 :{ /*x++;y++; */
do { x++; y++; }
while(x0?--t:0 */
}
if(t==0x0f && mode) return 0 ; /* 若五子连成一线,返回零 */
if(retrtemp) { int t=ret ; ret=rtemp ; rtemp=t ; } /* rtemp记录八向中最大的权 */
}
}
}/* 对mode= 1此返回植无意义 */
return(rtemp); /*当前局势, 返回0就成一下 return(ret+rtemp),加ret为增加随机性? */
}
void initqp(void) /*初始化棋盘 */
{
register int i, j;
for(i=0;iGetMax(CList)) list=&PList; /* 确定攻击性,防御 */
else list=&CList; /* 攻击 */
while(tmp=GetLast(list)) /* 获取最大优先级的棋盘位置 */
{ /* 连表 list 为空时 给 tmp 返回 0 ,然后随机取一个坐标点 */
px=tmp%MAX; py=tmp/MAX;
if(qp[py][px]!=0) /* 该位置不为空则继续循环 */
{
if(GetMax(PList)>GetMax(CList)) list=&PList; /* 重新确定攻击性 */
else list=&CList;
continue;
} break;
}
if(!tmp){ /*在链表中未找到数据,tmp=0 则生成随机数据 */
do { px=random(MAX); py=random(MAX); }
while(qp[py][px]!=0); tmp=0;
}
qp[py][px]=COMPUTER; /*计算机走子 */
qizi(px,py,YELLOW);
if(!scan(px,py,1)) { DestroyList(PList); DestroyList(CList); iswin=COMPUTER;
return 0;
} /*计算机胜 */
return ((py*MAX)+px); /*返回走子位置 */
}
void kongpan()
{
int i,j ;
setbkcolor(BLACK);
bar3d(PAN_X-30,PAN_Y-30,PAN_X+380,PAN_Y+380,7,5);
setpalette(WHITE,GREEN);
setcolor(YELLOW);
for(i=0;iPAN_X-25&(*y)>PAN_Y-25&(*x)PAN_X+(MAX-1)*25) (*x)=PAN_X+(MAX-1)*25 ;
if((*y)>PAN_Y+(MAX-1)*25) (*y)=PAN_Y+(MAX-1)*25 ;
}
bool MouseControl()
{
static int FIRST = 0;
if(!FIRST)
{
Get_xy(&mouse);
mouse.oldx = mouse.x;
mouse.oldy = mouse.y;
GetBuf(mouse.oldx,mouse.oldy,mouse.oldx+10,mouse.oldy+16,mouse_buf);
Shape[0].Draw(mouse.x, mouse.y);
FIRST = 1;
}
mouse.but = Which_pressed(); /* 无此句鼠标无反应 */
if( !mouse.but) /* 没有点鼠标时 */
{
Get_xy(&mouse);
Limit(&mouse.x,&mouse.y);/* 使在框中运动 */
if(mouse.x != mouse.oldx | mouse.y != mouse.oldy)
{
ResumeGraphics(mouse.oldx, mouse.oldy, mouse_buf);
mouse.oldx = mouse.x;
mouse.oldy = mouse.y;
GetBuf(mouse.x, mouse.y, mouse.x + 10, mouse.y + 16, mouse_buf);
Shape[0].Draw(mouse.x, mouse.y);
return 1;
}
else return 0;
}
else
{
if(FIRST==1)
{
kuang(MAX/2,MAX/2,WHITE);
FIRST = 2;
}
/*if(qp[black_y][black_x]!=COMPUTER) {*/
SetMouseXY(mouse.oldx,mouse.oldy);
kuang(black_x,black_y,WHITE);
black_x=(mouse.oldx-PAN_X+12)/25; black_y= (mouse.oldy-PAN_Y+12)/25;
kuang(black_x,black_y,BLACK);
return 1;
}
}
void xiangying()
{
kuang(MAX/2,MAX/2,BLACK);
while(bioskey(1)==0)
{
MouseControl(); /*delay(20);*/
if(pow(mouse.oldx-PAN_X-black_x*25,2)+pow(mouse.oldy-PAN_Y-black_y*25,2) <146 )
if(!five(black_x,black_y))
{
qizi(black_x,black_y,RED);
GetBuf(mouse.oldx, mouse.oldy, mouse.oldx + 10, mouse.oldy + 16, mouse_buf);
return;
}
}
}
void InitGraphicsBuf(int x,int y,int xx,int yy,void **p)
{
*p=malloc(imagesize(x,y,xx,yy));
}
bool init()
{
int driver = VGA, drivermode = VGAHI;
initgraph(&driver, &drivermode, "");
if(graphresult() != 0)
{
printf("can't initgraph"); return FALSE;
}
InitGraphicsBuf(0,0,10,16,&mouse_buf);
cleardevice();
return TRUE;
}
main()
{
init();
settextstyle(DEFAULT_FONT,HORIZ_DIR,2);
initqp();
kongpan();
xiangying();
printf("came over \nwinner:%d(COMPUTER:1,PLAYER:2)",iswin);
getch();
closegraph();
}
评论