正文

五子棋(人机对下)2007-10-02 21:22:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/vfdff/29795.html

分享到:

/***************************************************************************************\ 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(); }

阅读(3856) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册