一字棋源代码
- 格式:doc
- 大小:39.50 KB
- 文档页数:6
中国象棋python代码下面是一个简单的中国象棋的Python 代码示例:# 定义棋盘# 绘制棋盘def draw_board():for row in chessboard:for piece in row:print(piece, end=' ')print()# 判断是否在棋盘内def is_valid_move(x, y):return 0 <= x < 9 and 0 <= y < 10# 判断移动是否合法def is_valid_move(x1, y1, x2, y2):piece = chessboard[y1][x1]target = chessboard[y2][x2]if piece == ' ':return Falseif piece == '車' or piece == '車':if x1 != x2 and y1 != y2:return Falseif x1 == x2:min_y, max_y = (y1, y2) if y1 < y2 else (y2, y1)for y in range(min_y + 1, max_y):if chessboard[y][x1] != ' ':return Falseif y1 == y2:min_x, max_x = (x1, x2) if x1 < x2 else (x2, x1)for x in range(min_x + 1, max_x):if chessboard[y1][x] != ' ':return Falseif piece == '馬' or piece == '馬':dx = abs(x2 - x1)dy = abs(y2 - y1)if (dx == 1 and dy == 2) or (dx == 2 and dy == 1): return Truereturn Falseif piece == '象' or piece == '相':if y2 > 4 and (y2 - y1) % 2 != 0:return Falseif abs(x2 - x1) != 2 or abs(y2 - y1) != 2:return Falseif chessboard[(y1 + y2) // 2][(x1 + x2) // 2] != ' ': return Falseif piece == '士' or piece == '士':if x2 < 3 or x2 > 5:return Falseif y2 < 7 or y2 > 9:return Falseif abs(x2 - x1) != 1 or abs(y2 - y1) != 1: return Falseif piece == '帥' or piece == '将':if x2 < 3 or x2 > 5:return Falseif y2 < 0 or y2 > 2:return Falseif abs(x2 - x1) + abs(y2 - y1) != 1:return Falseif piece == '兵':if y1 < 5 and y2 != y1 - 1:return Falseif y1 >= 5 and (x1 != x2 or y2 != y1 - 1):return Falseif piece == '卒':if y1 > 4 and y2 != y1 + 1:return Falseif y1 <= 4 and (x1 != x2 or y2 != y1 + 1):return Falseif target == '帥' or target == '将':if piece == '卒' or piece == '兵':if y2 > 2:return Falseif piece == '兵' or piece == '卒':if y2 < 7:return Falsereturn True# 移动棋子def move_piece(x1, y1, x2, y2):if is_valid_move(x1, y1, x2, y2):piece = chessboard[y1][x1]chessboard[y2][x2] = piecechessboard[y1][x1] = ' 'else:print("Invalid move!")# 游戏循环def game_loop():while True:draw_board()player_input = input("请输入移动的起始位置和目标位置,以逗号分隔(例如:2,1,2,3):")positions = player_input.split(',')if len(positions) != 4:print("请输入正确的起始位置和目标位置!")continuex1, y1, x2, y2 = map(int, positions)if not is_valid_move(x1, y1) or not is_valid_move(x2, y2):print("请输入正确的起始位置和目标位置!")continuemove_piece(x1, y1, x2, y2)# 启动游戏game_loop()这是一个简单的中国象棋游戏代码示例,包括棋盘的绘制、棋子移动的判断和执行等功能。
chess.c*/ #include °'dos.h”include "stdio.h”/* ----------------------------------------------------- */ #define RED 7#define BLACK 14#define tnie 1#define false 0#define SELECTT 0#define MOVE 1#define RED_UPOxllOO#define RED_DOWN OxlfOO#define RED_LEFT OxleOO#define RED_RIGHT 0x2000#define RED_DO 0x3900#define RED_UNDO 0x1000#define BLACK_UP 0x4800#define BLACK_DOWN 0x5000#define BLACK_LEFT 0x4b00#define BLACK_RIGHT 0x4d00#define BLACK.DO OxleOO#define BLACK_UNDO Ox2bOO#define ESCAPE 0x0100#define RED JU 1#define RED_MA 2#define RED_XIANG 3#define RED_SHI 4#define RED JIANG 5#define RED_PAO 6#define RED.BIN 7#define BLACK JU 8#define BLACK_MA 9#define BLACK_XIANG 10#define BLACK_SHI 11#define BLACKJIANG 12#define BLACK_PAO 13#define BLACK_BIN 14/* ----------------------------------------------------- */ int firsttime=l;int savemode;char page_new=0.page_old=0;int finish=faIse,turn=BLACK r winner=O;int key;int redstate=SELECT,blackstate=SELECT;int board[10][9];/* ----------------------------------------------------- */char ♦chess]={',,\”bmp\\iju・wfb”,”bmp\\rma・wfb”「bmp\\rxiang・wft/「bmp\\rshi・wfly;H bmp\\ijiang.wfb,\H bmp\\rpao.wfb,,/bmp\\rbin.wfb,\"bmpWbju.wfb*;,'bmp\\bma.wfb,\ H bmp\\bxiangAvfb^M bmp\\bshi.wfb,\H bmp\\bjiang.wfb,\u bmp\\bpao.wfb H,H bmp\\bbin.wfb,'};char *board][9]={{”bmp\\ll・wfbTbmp\\lt・wfbTbmp\\lt・wfbTbmp\\14・wfbTbmp\\15.wfbTbmp\\16・wfb'「bmp \\ltwfb^,,bmp\\lt.wfb,\H bmp\\19.wfb,t)t{”bmp\\21・wny「bmp\\2c・wny「bmp\\2c・wfly「bmp\\24・wflyT'bmp\\25・wfb;・bmp\\26・wfb;'bm p\\2c・wfb;'bmp\\2c・wfb;'bmp\\29・wflT},{”bmp\\21 ・ wfly「bmp\\3a. wfiy「bmp\\3L wfbTbmp\\34・ wfly「bmp\\3t・ wfbTbmp\\36. wfb”「bmp \\3t・ wfb;'bmp\\3a・wfb・「bmp\\29. wfb”},{”bmp\\41・wfly「bmp\\4t・wfbTbmp\\4a・wfb”「bmp\\4(・wfb;・bmp\\4a・wfb”「bmp\\4t・wfb;'bmp\\4a・wfb”,”bmp\\4L wfbTbmp\\49・wfb”},{H bmp\\51 .wfb^u bmp\\52. wfb^^mp\\5t.wfb^M bmp\\54. wfb^M bmp\\5t Avfb^^mpXXSd.wfb^'bmp\\5t.wfb;'bmp\\5&wfbTbmp\\59.wfb”},{”bmp\\61・wfly「bmp\\62・wnyT'bmp\\6Lwny「bmp\\64・wnyT'bmp\\6匸wflyT'bmp\\66・wflyT'bmp\\6t・wfb;'bmp\\6 &wfbTbmp\\69.wfb”},{”bmp\\71 ・wny「bmp\\7(・wfb”「bmp\\7a・wfb”rbmp\\7t. wfb;'bmp\\7a・wfb”「bmp\\7t.wfb・T・bmp\ \7a・wflA”bmp\\7t・wfbTbmp\\79・wfW},{”bmp\\81・wfb”「bmp\\8a・wfb”rbmp\\8f・wfbTbmp\\84・wfb”「bmp\\85・wfb"「bmp\\86・wfb;'binp\\8t・ wfb;'bmp\\8a・ wfb・「bmp\\89. wfb”},rbmp\\91・wfly「bmp\\9(・wfb”Fbmp\\9t・wfb;'bmp\\9Lwfb”「bmp\\95・wfb;・bmp\\9(・wnyT'bmp\\9t・ wfbTbmp\\9t・ wfb;bmp\\99・wfb”},{”bmp\\101・wfbTbmp\\102・wfbTbmp\\102・wfbTbmp\\104・wfbTbmp\\105・wfbTbmp\\106・wf b^H bmp\\108.wfb\H bmp\\108.wfb\,,bmp\\109.wfb H)};char cursor[14][14]={O,O,OQO,O,O,OQO,O,0,1 丄0,0,0,000,0,0,0,0,0,1,1,1, 0,255,255,255,255,255,255,255Q0丄11, 0,255,255,255,255,255,255,(X0,1,1,11, 0,255,255,255,255,255,25500,1 丄1,1 丄0,255,255,255,255,255,255,255,0,0,1 丄1,1, 0,255,255,255,255,255,255,255,255.0.0.1,1,1,0,255,255,255,255,255,255,255,255,255Q0丄1,0,255,255,0,255,255,255,255.255,255,255,0,0.1, 0,25501」0255,255,255,255,255,255,255,0,0,0,1,1」,1,0,255,255,255,255,255,0」, 0,1,1 丄1 丄1,0,255,255,255,0,1 丄1,1,1丄1丄1丄0,255,0丄1丄1,1,1丄1」」丄1Q1」丄1struct pos{int x;int y;} position[ 10] [9],redcurpos,redtemppos,redoldpos,blackcurpos,blacktemppos,blackoldpos;/* ----------------------------------- */selectpage(register char page) /*换页函数*/{union REGS r;r. x.ax=0x4f05;r. x.bx=O;r.x.dx=page; /*选择页而引int86(0xl0,&r,&r);}unsigned char sef_SVGA_mode(int vmode) /*设置SVGA 屏幕模式*/{union REGS r;匚x.ax=0x4f02;r.x.bx=vmode;int86(0xl0,&r,&r);return(r.h.ah);}unsigned int gcl_SVGA_mode() /*获取当前SVGA 屏幕模式*/union REGS r;匚x.ax=Ox4fO3;int86(0xl0,&r,&r);return(r.x.bx);}drawbmp(int start_xjnt start_j;char []){char buffer[640];int ij,k,nj,g,b,widthJength:long position;HLE *fp;if((fp=fopen(/rb M))==NULL){printf(M Error! Can't open file!”);getch();return;}fscck(fp,28,SEEK_SET);frcad(&i,2,l,fp);if(i!=8)/*检查是否为256色位图*/{puts(,,Error!Can,t find bitmap!n);fclose(fp);getch();exit(O);}fseck(fp,l&SEEK_SET);fread(& widths J ,fp);fread(&length.4J、fp);if(firsttime){fseek(fp,54,SEEK_SET);for(i=0;i<256;i++) /*按照该图片的DAC色表设置色彩寄存器*/{b=fgetc(fp);g=fgetc(fp);r=fgetc(fp);/*获取R、G、B 分量*7 outportb(0x3c8,i);outportb(0x3c9.r»2); /*右移是要转化为VGA的6位寄存器形式*/ outportb(0x3c9,g»2);outportb(0x3c9,b»2);fgetc(fp);elsefseek(fp300,SEEK_SET);k=(width%4)?(4-width%4):0;严宽度修正值 */for(j=length-l +start_x ;j>=start_x:j-){fread(buffer,widthJ Jp);for(i=start_};n=0;i<width+start_y;i++.n++){position=j*6401+i; /*计算要显示点的显存位置*/page_new=position/65536; /* 计算显示页 */if(page_new!=page_old)/*当显示页不同时更换页而,提髙一立的输出速度*/{selectpage(page_new);page_old=page_new;} pokeb(OxaOOO,position%65536,buffer(n]); /* 写到显存位置 */}fseek(fp,k,SEEK_CUR);/*每行绘制完后修正宽度旬}fclose(fp);}init(){savemode=geCSVGA_mode(); /*先保存原来的屏幕模式*/ set_SVGA_mode(0xl01); /*硬件无关性初始化屏幕为640*480 256色模式旬}end(){set_SVGA_mode(savemode); /* 恢复屏幕*7}/* ----------------------------------------------------- */initpos(){int ij;for(i=0;i<10;i++)for Q=0;j<9 J 卄){position[i][j].x=35+i*39;position[i][j].y=43+j*40;}}initchessmapO{board[0][0]=BLACKJU: board[0][l]=BLACK…MA;board[0n2]=BLACK_XIANG;board[0][3]=BLACK_SHI;board[0][4]=BLACKJIANG;board[0][5]=BLACK.SHI;board[0][6]=BLACK_XIANG;board[0][7]=BLACK_MA;board[0][8]=BLACKJU;board[2][l]=BLACK_PAO;board[2][7]=BLACK_PAO;board[3][0]=BLACK_BIN;board[3][2]=BLACK_BIN;board[3][4]=BLACK_BIN;board[3][6]=BLACK_BIN;board[3][8]=BLACK_BIN;board[9][0]=REDJU;board[9][l]=RED_MA;board[9][2]=RED_XIANG;board[9][3]=RED_SHI;board[9][4]=REDJIANG;board[9][5]=RED_SHI;board ⑼[6]=RED_XIANG;board[9][7]=RED_MA;board[9][8]=REDJU;board[7][l]=RED_PAO;board[7][7]=RED_PAO;board ⑹[0]=RED_BIN;board ⑹[2]=RED_BIN;board ⑹[4]=RED_BIN;board ⑹[6]=RED_BIN;board ⑹[8]=RED_BIN;}initdrawchess(){int i,j;;fbr(i=0;i<10;i++)for(j=0;j<9:j 卄){if(board[i]|j])drawbmp(position[i][j].x,position[i][j].y,chess[i][j]]);drawcursor(stmct pos p)int i,j,n、m,x,y;long thisposition;x=position[p.x] [p.y] .x+20;y=position[p.x][p.y].y+25;for(j= 13-1 +x,m= 13{for(i=y,n=0;i< 13+y;i++,n++){thisposition=j *6401+i; /*计算要显示点的显存位置*/pagejie w=t hi sposi t ion/65536: /* 汁算显示页*/ if(page_new!=pagc_old) /*当显示页不同时更换页而,提高一定的输岀速度*/{selectpage(page_new);page_old=page_new;}if(cursor[m][n]!=l)if(cursor[m] [ n ]=0)pokeb(0xa000,thisposition%65536,0);elseif(turn=RED) pokeb(0xa000,thisposition%65536,153);elsepokeb(OxaOOO,thisposition%65536,255);}drawselecursor(struct pos p){int ilong thisposition;x=position[p.x][p.y].x+20;y=position[p.x][p.y].y+25;for(j= 13-1 +x,m= 13{for(i=y,n=0;i< 13+y;i++,n++){thisposition=j *6401+i; /*计算要显示点的显存位置*/ page.new=thisposition/65536; /* 汁算显示页 */ if(page_new!=page_old)/*当显示页不同时更换页而,提髙一立的输出速度*/{selectpage(page_new);page_old=page_new;}if(cursor[m][n]!=l)pokeb(0xa000,thisposition%65536,0);/* ----------------------------------- */int getkeyO{int press;while(bioskey( 1) == 0);press=bioskey(0);press=press&OxffOO:return(press);}/* ------------- 红方操作------------- */int redcanselect(){int x,y;x=redcurpos.x;y=redcurpos.y;if(board[x][y]>=REDJU&&board[x][y]<=RED_BIN)return 1;elsereturn 0;}int redcanmove(){int iJ.min,maxQldx,oldy,x.y;oldx=redoldpos.x;oldy=redoldpos.y;x=redcurpos.x;y=redcurpos.y;/*casel目标位置是否是自己人*/if(board[x][y]>=RED_JU&&board[x][y]<=RED_BIN) return 0;/*军、马、炮、相、士、将、卒的走法正确性的判断可switch(board[oldx][oldyj){case RED.BIN: 产完成 */if(oldx>=5){ if(y!=oldyll(oldx-x)!=l) return 0;}else{ if(x==(oldx-l)&&y=oldy) return 1;elseif(x=oldx&&y=(oldy+l)) return 1;elseif(x==oldx&&y=(oldy-l)) return 1;elsereturn 0;}break;case RED JIANG: /* 完成*7if(x!=oldx&&y!=oldy) return 0;if(x!=oldx)if((x-oldx)> 1 ll(oldx-x)> 1) return 0; else if(x<7) return 0;else if(y!=oldy)if((y-oldy)> 1 ll(oldy-y)> 1) return 0; else if(y<3lly>5) return 0;break;case RED JU: 严完成可if(x!=oldx&&y!=oldy) return 0;else if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx )?x:oldx;for(i=min+l ;i<max;i++) if(board[i][y]!=0) return 0;}else if(y!=oldy){ min=(y>oldy)?o!dy:y;max=(y>oldy)?y:oldy;for(i=min+l ;i<max;i++) if(board[x][i]!=0) return 0;} break;case RED.MA: /* 完成可if((x-oldx)=2&&((y-oldy)= lll(oldy-y)== 1)) (if(board[oldx+l][oidy]!=0) return 0; }else if((oldx-x)==2&&((y・oldy)== lll(oldy-y)== 1)) { if(board[oldx-1 ][oldy] !=0) return 0;}else if((y-oldy)==2&&((x・oldx)= lll(oldx-x)== 1)) { if(board[oldx][oldy+1 ] !=0) return 0; }else if(⑹ dy-y)==2&&((x・oldx)=lll(oldx・x)==l))if(board[oldx][oldy-l]!=0) return 0;}else return 0;break;case RED_PAO:if(x!=oldx&&y!=oldy) return 0;if(board[x][y]==0){if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+l ;i<max;i++)if(board[i][y]!=0) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(yx)ldy)?y:oldy;for(i=min+l ;i<max;i++)if(board[x][i]!=0) return 0;}}else{if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+l.j=0;i<max:i++)if(board[i][y] !=0) j++;if(j!=l) return 0:}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+l .j=0;i<max:i++)if(board[x][i]!=0)j++;if(j!=l) return 0;}} break;case RED_SHI: if(oldx=9lk)ldx=7) {if(x!=8lly!=4) return 0;} elseif(oldx==8){if(x==9&&y==3) return 1; else /*完成引严完成if(x=9&&y=5) return 1;elseif(x=7&&y=3) return 1;elseif(x=7&&y=5) return 1;else return 0;}else return 0:break;case RED.XIANG: /* 完成*7if(x<5) return 0;if(x!=oldx&&y!=oldy)(if((x-oldx)==2&&(y-oldy)==2){i=oldx+1 y=oldy+1;}else if((x-oldx)=2&&(oldy-y)==2){i=oldx+l y=oldy-l;}else if((oldx-x)=2&&(y-oldy)==2){i=oldx-l j=oldy+1;}else if((oldx-x)=2&&(oldy-y)=2){i=oldx-l;j=oldy-l;}else return 0;if(board[i][j]!=0) return 0;}else return 0;break;}return 1;redupO{int xyn;if(redcurpos.x>0){redcurpos.x-;x=positionfredtemppos.x][redtemppos.y].x;y=position[redtemppos.x][redtemppos.y].y;if(board[redtemppos.x][redtemppos.y]=0)drawbmp(x,y,board][redtemppos.y]);else if(!(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE))n=board[redtemppos.x][redtemppos.y];drawbmp(x,y,chessfile[n]);if(redtemppos.x==redoldpos.x&&redtemppos.y=redoldpos.y&&redstate==MOVE)drawselecursor(redoldpos);drawcursor(redcurpos);{redtemppos.x=redcurpos.x;redtemppos.y=rcdcurpos.y;}}reddown(){int x,y,n;if(redcurpos.x<9){redcurpos.x++;x=position[redtemppos.x][redtemppos.y].x;y=position[redtemppos.x][redtemppos.y].y;if(board[redtemppos.x][redtemppos.y]==0)drawbmp(x,y,board][redtemppos.y]);else if( !(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE)) { n=board[redtemppos.x](redtemppos.y];drawbmp(x,y,chessfi lefn]);}if(redtemppos.x==redoldpos.x&&redtemppos.y=redoldpos.y&&redstate==MOVE)drawselecursor(redoldpos);drawcursor(redcurpos);redtemppos.x=redcurpos.x;redtemppos.y=rcdcurpos.y;}}redleft(){int x,y,n;if(redcurpos.y>0){redcurpos.y-;x=position[redtemppos.x][redtemppos.y].x;y=position[redtemppos.x][redtemppos.y].y;if(board[redtemppos.x][redtemppos.y]=0)drawbmp(x,y5board][redtemppos.y]);else if(!(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE)){n=board[redtemppos.x][redtemppos.y];d rawbmp(x ychcssfi le[n]);}if(redtemppos.x==redoldpos.x&&redtemppos.y=redoldpos.y&&redstate==MOVE)drawselecursor(redoldpos);drawcursor(redcurpos);redtemppos.x=redcurpos.x;redtemppos.y=redcurpos.y;}} redright()int xyn;if(redcurpos.y<8){redcurpos.y++;x=positionfredtemppos.x][redtemppos.y].x;y=position[redtemppos.x][redtemppos.y].y;if(board[redtemppos.x][redtemppos.y]==0)drawbmp(x,y5board][redtemppos.y]);else if( !(redtemppos.x==redoldpos.x&&redtemppos.y==redoldpos.y&&redstate==MOVE)) { n=board[redtemppos.x][redtemppos.y];drawbmp(x,y,chessfile[n]);}if(redtemppos.x==redoldpos.x&&redtemppos.y=redoldpos.y&&redstate==MOVE)drawselecursor(redoldpos);drawcursor(redcurpos);redtemppos.x=redcurpos.x;redtemppos.y=redcurpos.y;}} reddo()int i,j,x,y,n;if(redstate==SELECT&&redcanselectO)if(board [redcurpos.x] [redcurpos. y]<=RED&&board[redcurpos.x] [redcurpos.y]>0){redstate=MOVE;drawselecursor(redcurpos);redoldpos.x=redcurpos.x;redoldpos.y=redcurpos.y;}}else if(redstate=MOVE&&redcanmoveO){x=position[redoldpos.x][redoldpos.y].x:y=position[redoldpos.x][redoldpos.y].y;drawbmp(x,y,board][rcdoldpos.y]);{x=position[redcurpos.x] [redcurpos. y].x;y=position[redcurpos.x][redcurpos. y].y;n=board[redoldpos.x][redoldpos. y];drawbmp(x,y,chessfile[n]);if(board[redcurpos.x][redcurpos.y]=BLACK_JIANG){winner=RED;finish=l;return;}board[redcurpos.x][redcurpos.yj=n;board [ redoldpos.x ] [rcdoldpos.y ]=0;for(i=0;i<=2;i++)for(j=3;j<=5;j++)if(board[i][j]=BLACKJIANG){x=i;y=j;}for(i=x+1 ,j=y,n=O;i<=9;i++){if(board[i][j]=RED JIANG&&n=0){winner=BLACK:finish=l ;break;}else if(board[i][j]!=0) n++;}turn=BLACK;blackstate=SELECT;drawcursor(blackcurpos);drawbmp(30,43&”bmp\\bzq.wfb”);/* 转交控制权给黑方引redundo(){int xyn;if(redstate==MOVE){ x=position[redoldpos.x][redoldpos. y].x; y=position[redoldpos.x][redoldpos.y].y;n=board[redoldpos.x][redoldpos.y]; drawbmp(xychcssfilc[n]);redoldpos.x=redcurpos.x;redoldpos.y=redcurpos.y; drawcursor(redcurpos);redstate=SELECT;}}/* ------------- 黑方操作 -------------- */int blackcanselect(){int x,y;x=blackcurpos.x;y=blackcurpos.y;if(board[x][y]>=BLACK_JU&&board[x][y]<=BLACK_BIN) return 1;elsereturn 0;}int blackcanmoveO{int ij,miiLmax,oldx,oldy,x,y;oldx=blackoldpos.x;oldy=blackoldpos.y;x=blackcurpos.x;y=blackcurpos.y;/*casel目标位置是否是自己人*/if(board[x][y]>=BLACK_J U&&board[x][y]<=BLACK_BIN) return 0;/*军、马、炮、相、士、将、卒的上法正确性的判断*/s witch(board[oldx] [oldy])case BLACKJU: /* 完成勺if(x!=oldx&&y!=oldy) return 0;else if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+l ;i<max;i++) if(board[i][y]!=0) return 0;}else if(y!=oldy){ min=(y r>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+l ;i<max;i++) if(board[x][i]!=0) return 0;{}break;case BLACK.MA: /*完成*/ if((x-oldx)==2&&((y-oldy)== 1 ll(oldy-y)== 1)) {if(board[oldx+1 ] [oldy] !=0) return 0;}elseif((oldx-x)==2&&((y・oldy)= 1 ll(oldy-y)== 1)) ( if(board[oldx-1 ][oldy] !=0) return 0;}else if((y-oldy)==2&&((x・oldx)= lll(oldx-x)== 1)) {if(board[oldx][oldy+1 ] !=0) return 0:}elseif((oldy-y)==2&&((x-oldx)= lll(oldx-x )== 1)) {if(board[oldx][oldy-1 ] !=0) return 0;}elsereturn 0;break;case BLACK.PAO: /* 完成 */ if(x!=oldx&&y!=oldy) return 0;if(board[x] [y ]=0){if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+l ;i<max;i++) if(board[i][y]!=0) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+l :i<max;i++)if(board[x][i]!=0) return0;}}else(j=0;if(x!=oldx){ min=(x>oldx)?oldx:x;max=(x>oldx)?x:oldx;for(i=min+l ;i<max;i++)if(board[i][y] !=0) j++;if(j!=l) return 0;}else if(y!=oldy){ min=(y>oldy)?oldy:y;max=(y>oldy)?y:oldy;for(i=min+l ;i<max;i++)if(board[x][i]!=0) j++;if(j!=l) return 0:}}break;case BLACK_XIANG: if(x>4) return 0;if(x!=oldx&&y!=oldy){if((x-oldx)==2&&(y-oldy)==2){i=oldx+1 y=oldy+1;}else if((x-oldx)=2&&(oldy・y)==2) {i=oldx+l:j=oldy-l;}else if((oldx-x)=2&&(y-oldy)==2) (i=oldx-l ;j=oldy+l;}else if((oldx-x)=2&&(oldy-y)==2) {i=oldx-l;j=oldy-l;}else return 0; if(board[i][j]!=0) return 0;}else return 0;break;case BLACK SHI:if(oldx==0lloldx=2){if(x!=llly!=4) return 0;} else if(oldx==l ){if(x==0&&y==3) return 1;elseif(x=O&&y=5) return 1;elseif(x=2&&y=3) return 1;elseif(x=2&&y=5) return 1;else return 0;}else return 0:break;case BLACKJIANG:if(x!=oldx&&y!=oldy) return 0; if(x!=oldx)if((x-oldx)> 1 ll(oldx-x)> 1) return 0: else if(x>2) return 0;else if(y!=oldy)if((y-oldy)> 1 ll(oldy-y)> 1) return 0; else if(y<3lly>5) return 0; break;case BLACK_BIN:if(oldx<=4){ if(y!=oldyll(x-oldx)!=l) return 0;} else{ if(x==(oldx+l )&&y=oldy) return 1;elseif(x==oldx&&y=(oldy+1)) return 1; elseif(x==oldx&&y=(oldy-l)) return 1; elsereturn 0;} break;}return 1;}blackupO{int x,y,n;if(blackcurpos.x>0)blackcurpos.x-;x=position[blacktemppos.x][blacktemppos.y].x;y=position[blacktemppos.x][blacktemppos.y].y;if(board[blacktemppos.x][blacktemppos.y]=0)drawbmp(x,y,board][blacktemppos.y]);elseif(!(blacktemppos.x==blackoldpos.x&&blacktemppos.y=blackoldpos.y&&blackstate==MOVE)) { n=board[blacktemppos.x][blacktemppos.y];drawbmp(x,y,chessfi lefn]);}if(blacktemppos.x=blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate==MOVE) drawselecursor(blackoldpos);drawcursor(blackcurpos);blacktemppos.x=blackcurpos.x:blacktemppos.y=blackcurpos.y;}}blackdown(){int xyn;if(blackcurpos.x<9){blackcurpos.x++;x=position[blacktemppos.x][blacktemppos.y].x;y=position[blacktemppos.x][blacktemppos.y].y;if(board[blacktemppos.x]|blacktemppos.y]==0)drawbmp(x,y,board][blacktemppos.y]);elseif(!(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&& blackstate==MOVE)) { n=board[blacktemppos.x][blacktemppos.y];drawbmp(x,y5chessfile[n]);if(blacktemppos.x=blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate==MO VE) drawselecursor(blackoldpos);drawcursor(blackcurpos);blacktemppos.x=blackcurpos.x;blacktemppos.y=blackcurpos.y;blackleft(){int xyn;if(blackcurpos.y>0){blackcurpos.y-;x=position[blacktemppos.x][blacktemppos.y].x;y=position[blacktemppos.x][blacktemppos.y].y;if(board[blacktemppos.x]|blacktenippos.y]==0)drawbmp(x,y,board][blacktemppos.y]);elseif(!(blacktemppos.x==blackoldpos.x&&blacktemppos.y=blackoldpos.y&&blackstate==MOVE)) { n=board[blacktemppos.x][blacktemppos.y];d rawbmp(x ychcssfi le[n]);}if(blacktemppos.x=blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate==MO VE) drawselecursor(blackoldpos);drawcursor(blackcurpos);blacktemppos.x=blackcurpos.x;blacktemppos.y=blackcurpos.y;}blackright(){int xyn;if(blackcurpos.y<8){blackcurpos.y++;x=position[blacktemppos.x][blacktemppos.y].x;y=position[blacktemppos.x][blacktemppos.y].y;if(board[blacktemppos.x][blacktenippos.y]==0)drawbmp(x,y,board][blacktemppos.y]);elseif(!(blacktemppos.x==blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate==MOVE)) { n=board[blacktemppos.x][blacktemppos.y];drawbmp(x,y,chessfile[n]);if(blacktemppos.x=blackoldpos.x&&blacktemppos.y==blackoldpos.y&&blackstate==MOVE) drawselecursor(blackoldpos);drawcursor(blackcurpos);blacktemppos.x=blackcurpos.x;blacktemppos.y=blackcurpos.y;}blackdo(){int i,j,x,y,n;if(blackstate==SELECT&&blackcanselectO){if(board[blackcurpos.x][blackcurpos.y]<=BLACK&&board[blackcurpos.x][blackcurpos.y]>0) { blackstate=MOVE;drawselecursor(blackcurpos);blackoldpos.x=blackcurpos.x;blackoldpos.y=blackcuipos.y;}}else if(blackstate=MOVE &&blackcanmoveO){x=position[blackoldpos.x][blackoldpos.y].x;y=position|blackoldpos.x][blackoldpos.y].y;drawbmp(x,y,board][blackoldpos.y]);x=position[blackcurpos.x][blackcurpos.y].x;y=position(blackcurpos.x][blackcurpos.y].y;n=board[blackoldpos.x][blackoldpos.y];drawbmp(x,y,chessfile[n]);if(board[blackcurpos.x][blackcurpos.y]=RED_JIANG){winner=BLACK;finish=l;return;}board[blackcurpos.x][blackcurpos.y]=n: board[blacko!dpos.x][blackoldpos.y]=0; for(i=0;i<=2;i++)for(j=3;j<=5;j++)if(board[i] [j]=BLACKJIANG){x=i;y=j;}for(i=x+1 ,j=y,n=0;iv=9;i++){if(board [ i ] fj ]=RED_J IANG&&n=0) {winner=RED;finish= 1:break:} else if(board[i][j]!=0) n++;turn=RED: redstate=SELECT; drawcursor(redcurpos); drawbmp(30.43&”bmp\\rzq・wfb”);严转交控制权给红方勺}blackundo(){int xyn;if(b!ackstate==MOVE){x=position[blackoldpos.x][blackoldpos.y].x; y=position[blackoldpos.x][blackoldpos.y].y;n=board[blackoldpos.x][blackoldpos.y]: drawbmp(x,yxhessfile[n]);blackoldpos.x=blackcurpos.x;blackoldpos.y=blackcurpos.y; drawcursor(blackcurpos); blackstate=SELECT;}}/* ----------------------------------------------------- */start(){drawcursor(blackcurpos);drawbmp(30,43&”bmp\\bzq.wfb”);while(Jfinish){key=getkey();switch(key){case RED_UP:if(turn==RED) redupO;break;case RED_DOWN: if(turn==RED) reddown();break;case RED_LEFT: if(turn==RED) redleft();break;case RED_RIGHT:if(turn==RED) redright();break;case RED_DO: if(turn==RED) reddo();break;case RED_UNDO:if(turn==RED) redundo();break;case BLACK_UP:if(turn==BLACK)blackupO;break;case BLACK_DOWN:if(turn==BLACK)blackdown();break;case BLACK_LEFT: if(turn==BLACK) blackleft();break;case BLACK.RIGHT: if(turn==BLACK) blackrightO; break;case BLACK_DO: if(turn=BLACK) blackdo();break;case BLACK.UNDO: if(turn=BLACK) blackundo();break;case ESCAPE: finish=l;break;}main()init();initpos();initchessmapO;drawbmp(0.0/bmp\\board.wfb M); initdrawchess();/*初始化光标位苣*/redcurpos.x=redoldpos.x=redtenippos.x=9;redcurpos.y=redoldpos.y=redtemppos.y=8;blackcurpos.x=blackoldpos.x=blacktemppos.x=0; blackcurpos.y=blacko!dpos.y=blacktemppos.y=0; /*开始*/ start();if(winner==RED)drawbmp(2OO,2OO;,bmp\\redwin.wfb M);else if(winner==BLACK)drawbmp(2OO,2OO,H bmp\\blackwin.wfb H);elsedrawbmp(2OO,2OO;,bmp\\exit.wfb H); getch();end();}。
C语⾔实现⼀字棋游戏实验5 编程实现⼀字棋游戏1实验⽬的:(1)理解和掌握博弈树的启发式搜索过程;α-过程;(2)熟悉博弈中两种最基本的搜索⽅法——极⼤极⼩过程和β(3)能够⽤VC编程语⾔设计简单的博弈游戏。
2实验要求:⽤VC 编程实现⼀字棋,根据实验结果写出总结。
3 实验结果分析:参考⽰例代码:#include "StdAfx.h"#include#include#include#include#includeusing namespace std;#define MAX_NUM 1000 //计算机获胜的标志#define NO_BLANK -1001//⼈获胜的标志#define TREE_DEPTH 3 //递归深度#define NIL 1001 //根节点的函数⾛步评估值class State //棋盘状态节点,⼀个State实例就是⼀个棋盘的状态节点,从⽽形成⼀颗树状结构{public:int QP[3][3]; //当前棋盘数组int e_fun; //评分结果int child[9]; //当前棋盘状态下的后⼀步的所有状态节点int parent; //当前棋盘状态下的⽗母节点下标int bestChild;//在child[9]⾥e_fun最优的节点下标};class Tic{public:State States[MAX_NUM];//棋盘状态节点数组Tic(){}void init() //初始化棋盘,将各个位置的棋盘都置为0{s_count=0;for(int i=0;i<3;i++)for(int j=0;j<3;j++){States[0].QP[i][j] = 0;}States[0].parent = NIL;}void PrintQP()//棋盘界⾯显⽰{for(int i=0;i<3;i++){for(int j=0;j<3;j++){cout<}cout<}}int IsWin(State s) //判断当前的棋盘状态是否有令任何⼀⽅获胜{int i = 0;for(i=0;i<3;i++){if(s.QP[i][0]==1&&s.QP[i][1]==1&&s.QP[i][2]==1)return 1;if(s.QP[i][0]==-1&&s.QP[i][1]==-1&&s.QP[i][2]==-1)return -1;}for(i=0;i<3;i++)if(s.QP[0][i]==1&&s.QP[1][i]==1&&s.QP[2][i]==1)return 1;if(s.QP[0][i]==-1&&s.QP[1][i]==-1&&s.QP[2][i]==-1)return -1;}if((s.QP[0][0]==1&&s.QP[1][1]==1&&s.QP[2][2]==1)||(s.QP[2][0]==1&&s.QP[1][1]==1&&s.QP[0][2]==1))return 1;if((s.QP[0][0]==-1&&s.QP[1][1]==-1&&s.QP[2][2]==-1)||(s.QP[2][0]==-1&&s.QP[1][1]==-1&&s.QP[0][2]==-1))ret urn -1; return 0;}int e_fun(State s)//机器智能判定评价函数{bool flag=true;int i = 0;for( i=0;i<3;i++)for(int j=0;j<3;j++)if(s.QP[i][j]==0)flag=false;if(flag)return NO_BLANK;if(IsWin(s)==-1)return -MAX_NUM;if(IsWin(s)==1)return MAX_NUM;int count=0;for(i=0;i<3;i++)for(int j=0;j<3;j++)if(s.QP[i][j]==0)tmpQP[i][j]=1;else tmpQP[i][j]=s.QP[i][j];for(i=0;i<3;i++)count+=(tmpQP[i][0]+tmpQP[i][1]+tmpQP[i][2])/3;for(i=0;i<3;i++)count+=(tmpQP[0][i]+tmpQP[1][i]+tmpQP[2][i])/3;count+=(tmpQP[0][0]+tmpQP[1][1]+tmpQP[2][2])/3;count+=(tmpQP[2][0]+tmpQP[1][1]+tmpQP[0][2])/3;for( i=0;i<3;i++)for(int j=0;j<3;j++)if(s.QP[i][j]==0)tmpQP[i][j]=-1;else tmpQP[i][j]=s.QP[i][j];for(i=0;i<3;i++)count+=(tmpQP[i][0]+tmpQP[i][1]+tmpQP[i][2])/3;count+=(tmpQP[0][i]+tmpQP[1][i]+tmpQP[2][i])/3;count+=(tmpQP[0][0]+tmpQP[1][1]+tmpQP[2][2])/3;count+=(tmpQP[2][0]+tmpQP[1][1]+tmpQP[0][2])/3;return count;}virtual bool AutoDone(){return false;}void UserInput()//获取⽤户的输⼊{int pos,x,y;L1: cout<<"请输⼊棋⼦的坐标 (xy): ";cin>>pos;x=pos/10,y=pos%10;if(x>0&&x<4&&y>0&&y<4&&States[0].QP[x-1][y-1]==0) States[0].QP[x-1][y-1]=-1;else{cout<<"⾮法输⼊!";goto L1;}}};int Tic::s_count = 0;//初始化棋盘状态节点总数,刚开始置为0 class demo : public Tic{public:demo(){}bool Judge(){int i,j,a=0;for(j=0;j<3;j++)if(States[0].QP[i][j]==0) a++;if(a==0)return true;return false;}virtual bool AutoDone(){ int a,b,i,j,m,n,max,min,x,y;if(IsWin(States[0])==-1){cout<<"恭喜您获胜!"<return true;}a=0,b=0;max=-10000;for(x=0;x<3;x++)for(y=0;y<3;y++)States[11].QP[x][y]=States[0].QP[x][y]; for(i=0;i<3;i++)for(j=0;j<3;j++){if(States[0].QP[i][j]==0){ a=1;for(x=0;x<3;x++)for(y=0;y<3;y++)States[a].QP[x][y]=States[0].QP[x][y]; States[a].QP[i][j]=1;min=10000;for(m=0;m<3;m++)for(n=0;n<3;n++){if(States[a].QP[m][n]==0){ b=1;for(x=0;x<3;x++)for(y=0;y<3;y++)States[10].QP[m][n]=-1;States[10].e_fun=e_fun(States[10]); if(States[10].e_fun}}States[a].e_fun=min;if(States[a].e_fun>max){ max=States[a].e_fun;for(x=0;x<3;x++)for(y=0;y<3;y++)States[11].QP[x][y]=States[a].QP[x][y]; }}}for(x=0;x<3;x++)for(y=0;y<3;y++)States[0].QP[x][y]=States[11].QP[x][y]; cout<<"计算机⾛棋"<PrintQP();if(IsWin(States[0])==1){cout<<"抱歉你输了,计算机获胜!"< return true;}else if(IsWin(States[0])==-1){cout<<"恭喜您获胜!"<return true;}return false;}};void main(){system("color b1");char IsFirst;bool IsFinish;cout<<"若您为先⼿,请输⼊'y':"<cin>>IsFirst;demo *p=new demo();p->init();cout<<"棋盘的初始状态:"<p->PrintQP();do{ if(!p->Judge()){if(IsFirst=='y'){p->UserInput();p->PrintQP();if(!p->Judge()){IsFinish=p->AutoDone();}}else{ IsFinish=p->AutoDone();if(!p->Judge()){if(!IsFinish) {p->UserInput();p->PrintQP();}} } }if(p->Judge()) IsFinish=true;}while (!IsFinish);if((p->IsWin(p->States[0])==0)&&p->Judge()) {cout<<"平局"<}}。
import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.*;import java.io.*;public class Chess{public static void main(String args[]){new ChessMainFrame("中国象棋:观棋不语真君子,棋死无悔大丈夫");}}class ChessMainFrame extends JFrame implements ActionListener,MouseListener,Runnable{//玩家JLabel play[] = new JLabel[32];//棋盘JLabel image;//窗格Container con;//工具栏JToolBar jmain;//重新开始JButton anew;//悔棋JButton repent;//退出JButton exit;//当前信息JLabel text;//保存当前操作Vector Var;//规则类对象(使于调用方法)ChessRule rule;/**** 单击棋子** chessManClick = true 闪烁棋子并给线程响应** chessManClick = false 吃棋子停止闪烁并给线程响应*/boolean chessManClick;/**** 控制玩家走棋** chessPlayClick=1 黑棋走棋** chessPlayClick=2 红棋走棋默认红棋** chessPlayClick=3 双方都不能走棋*/int chessPlayClick=2;//控制棋子闪烁的线程Thread tmain;//把第一次的单击棋子给线程响应static int Man,i;ChessMainFrame(){new ChessMainFrame("中国象棋");}/**** 构造函数** 初始化图形用户界面*/ChessMainFrame(String Title){//获行客格引用con = this.getContentPane();con.setLayout(null);//实例化规则类rule = new ChessRule();Var = new Vector();//创建工具栏jmain = new JToolBar();text = new JLabel("欢迎使用象棋对弈系统");//当鼠标放上显示信息text.setToolTipText("信息提示");anew = new JButton(" 新游戏 ");anew.setToolTipText("重新开始新的一局");exit = new JButton(" 退出 ");exit.setToolTipText("退出象棋程序程序");repent = new JButton(" 悔棋 ");repent.setToolTipText("返回到上次走棋的位置");//把组件添加到工具栏jmain.setLayout(new GridLayout(0,4));jmain.add(anew);jmain.add(repent);jmain.add(exit);jmain.add(text);jmain.setBounds(0,0,558,30);con.add(jmain);//添加棋子标签drawChessMan();//注册按扭监听anew.addActionListener(this);repent.addActionListener(this);exit.addActionListener(this);//注册棋子移动监听for (int i=0;i<32;i++){con.add(play[i]);play[i].addMouseListener(this);}//添加棋盘标签con.add(image = new JLabel(new ImageIcon("image\\Main.GIF")));image.setBounds(0,30,558,620);image.addMouseListener(this);//注册窗体关闭监听this.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent we){System.exit(0);}});//窗体居中Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();Dimension frameSize = this.getSize();if (frameSize.height > screenSize.height){frameSize.height = screenSize.height;}if (frameSize.width > screenSize.width){frameSize.width = screenSize.width;}this.setLocation((screenSize.width - frameSize.width) / 2 - 280 ,(screenSize.height - frameSize.height ) / 2 - 350);//设置this.setIconImage(new ImageIcon("image\\红将.GIF").getImage());this.setResizable(false);this.setTitle(Title);this.setSize(558,670);this.show();}/**** 添加棋子方法*/public void drawChessMan(){//流程控制int i,k;//图标Icon in;//黑色棋子//车in = new ImageIcon("image\\黑车.GIF");for (i=0,k=24;i<2;i++,k+=456){play[i] = new JLabel(in);play[i].setBounds(k,56,55,55);play[i].setName("车1");}//马in = new ImageIcon("image\\黑马.GIF");for (i=4,k=81;i<6;i++,k+=342){play[i] = new JLabel(in);play[i].setBounds(k,56,55,55);play[i].setName("马1");}//相in = new ImageIcon("image\\黑象.GIF");for (i=8,k=138;i<10;i++,k+=228){play[i] = new JLabel(in);play[i].setBounds(k,56,55,55);play[i].setName("象1");}//士in = new ImageIcon("image\\黑士.GIF"); for (i=12,k=195;i<14;i++,k+=114){ play[i] = new JLabel(in);play[i].setBounds(k,56,55,55);play[i].setName("士1");}//卒in = new ImageIcon("image\\黑卒.GIF"); for (i=16,k=24;i<21;i++,k+=114){ play[i] = new JLabel(in);play[i].setBounds(k,227,55,55);play[i].setName("卒1" + i);}//炮in = new ImageIcon("image\\黑炮.GIF"); for (i=26,k=81;i<28;i++,k+=342){ play[i] = new JLabel(in);play[i].setBounds(k,170,55,55);play[i].setName("炮1" + i);}//将in = new ImageIcon("image\\黑将.GIF"); play[30] = new JLabel(in);play[30].setBounds(252,56,55,55);play[30].setName("将1");//红色棋子//车in = new ImageIcon("image\\红车.GIF"); for (i=2,k=24;i<4;i++,k+=456){play[i] = new JLabel(in);play[i].setBounds(k,569,55,55);play[i].setName("车2");}//马in = new ImageIcon("image\\红马.GIF"); for (i=6,k=81;i<8;i++,k+=342){play[i] = new JLabel(in);play[i].setBounds(k,569,55,55);play[i].setName("马2");}//相in = new ImageIcon("image\\红象.GIF"); for (i=10,k=138;i<12;i++,k+=228){ play[i] = new JLabel(in);play[i].setBounds(k,569,55,55);play[i].setName("象2");}//士in = new ImageIcon("image\\红士.GIF"); for (i=14,k=195;i<16;i++,k+=114){ play[i] = new JLabel(in);play[i].setBounds(k,569,55,55);play[i].setName("士2");}//兵in = new ImageIcon("image\\红卒.GIF"); for (i=21,k=24;i<26;i++,k+=114){ play[i] = new JLabel(in);play[i].setBounds(k,398,55,55);play[i].setName("卒2" + i);}//炮in = new ImageIcon("image\\红炮.GIF"); for (i=28,k=81;i<30;i++,k+=342){ play[i] = new JLabel(in);play[i].setBounds(k,455,55,55);play[i].setName("炮2" + i);}//帅in = new ImageIcon("image\\红将.GIF"); play[31] = new JLabel(in);play[31].setBounds(252,569,55,55);play[31].setName("帅2");}/**** 线程方法控制棋子闪烁*/public void run(){while (true){//单击棋子第一下开始闪烁if (chessManClick){play[Man].setVisible(false);//时间控制try{tmain.sleep(200);}catch(Exception e){}play[Man].setVisible(true);}//闪烁当前提示信息以免用户看不见else {text.setVisible(false);//时间控制try{tmain.sleep(250);}catch(Exception e){}text.setVisible(true);}try{tmain.sleep(350);}catch (Exception e){}}}/**** 单击棋子方法*/public void mouseClicked(MouseEvent me){System.out.println("Mouse");//当前坐标int Ex=0,Ey=0;//启动线程if (tmain == null){tmain = new Thread(this);tmain.start();}//单击棋盘(移动棋子)if (me.getSource().equals(image)){//该红棋走棋的时候if (chessPlayClick == 2 && play[Man].getName().charAt(1) == '2'){Ex = play[Man].getX();Ey = play[Man].getY();//移动卒、兵if (Man > 15 && Man < 26){rule.armsRule(Man,play[Man],me);}//移动炮else if (Man > 25 && Man < 30){rule.cannonRule(play[Man],play,me);}//移动车else if (Man >=0 && Man < 4){rule.cannonRule(play[Man],play,me);}//移动马else if (Man > 3 && Man < 8){rule.horseRule(play[Man],play,me);}//移动相、象else if (Man > 7 && Man < 12){rule.elephantRule(Man,play[Man],play,me);}//移动仕、士else if (Man > 11 && Man < 16){rule.chapRule(Man,play[Man],play,me);}//移动将、帅else if (Man == 30 || Man == 31){rule.willRule(Man,play[Man],play,me);}//是否走棋错误(是否在原地没有动)if (Ex == play[Man].getX() && Ey == play[Man].getY()){text.setText(" 红棋走棋");chessPlayClick=2;}else {text.setText(" 黑棋走棋");chessPlayClick=1;}}//if//该黑棋走棋的时候else if (chessPlayClick == 1 && play[Man].getName().charAt(1) == '1'){Ex = play[Man].getX();Ey = play[Man].getY();//移动卒、兵if (Man > 15 && Man < 26){rule.armsRule(Man,play[Man],me);}//移动炮else if (Man > 25 && Man < 30){rule.cannonRule(play[Man],play,me);}//移动车else if (Man >=0 && Man < 4){rule.cannonRule(play[Man],play,me);}//移动马else if (Man > 3 && Man < 8){rule.horseRule(play[Man],play,me);}//移动相、象else if (Man > 7 && Man < 12){rule.elephantRule(Man,play[Man],play,me);}//移动仕、士else if (Man > 11 && Man < 16){rule.chapRule(Man,play[Man],play,me);}//移动将、帅else if (Man == 30 || Man == 31){rule.willRule(Man,play[Man],play,me);}//是否走棋错误(是否在原地没有动)if (Ex == play[Man].getX() && Ey == play[Man].getY()){ text.setText(" 黑棋走棋");chessPlayClick=1;}else {text.setText(" 红棋走棋");chessPlayClick=2;}}//else if//当前没有操作(停止闪烁)chessManClick=false;}//if//单击棋子else{//第一次单击棋子(闪烁棋子)if (!chessManClick){for (int i=0;i<32;i++){//被单击的棋子if (me.getSource().equals(play[i])){//告诉线程让该棋子闪烁Man=i;//开始闪烁chessManClick=true;break;}}//for}//if//第二次单击棋子(吃棋子)else if (chessManClick){//当前没有操作(停止闪烁)chessManClick=false;for (i=0;i<32;i++){//找到被吃的棋子if (me.getSource().equals(play[i])){//该红棋吃棋的时候if (chessPlayClick == 2 && play[Man].getName().charAt(1) == '2'){Ex = play[Man].getX();Ey = play[Man].getY();//卒、兵吃规则if (Man > 15 && Man < 26){rule.armsRule(play[Man],play[i]);}//炮吃规则else if (Man > 25 && Man < 30){rule.cannonRule(0,play[Man],play[i],play,me);}//车吃规则else if (Man >=0 && Man < 4){rule.cannonRule(1,play[Man],play[i],play,me);}//马吃规则else if (Man > 3 && Man < 8){rule.horseRule(play[Man],play[i],play,me);}//相、象吃规则else if (Man > 7 && Man < 12){rule.elephantRule(play[Man],play[i],play);}//士、仕吃棋规则else if (Man > 11 && Man < 16){rule.chapRule(Man,play[Man],play[i],play);}//将、帅吃棋规则else if (Man == 30 || Man == 31){rule.willRule(Man,play[Man],play[i],play);play[Man].setVisible(true);}//是否走棋错误(是否在原地没有动)if (Ex == play[Man].getX() && Ey == play[Man].getY()){text.setText(" 红棋走棋");chessPlayClick=2;break;}else{text.setText(" 黑棋走棋");chessPlayClick=1;break;}}//if//该黑棋吃棋的时候else if (chessPlayClick == 1 &&play[Man].getName().charAt(1) == '1'){Ex = play[Man].getX();Ey = play[Man].getY();//卒吃规则if (Man > 15 && Man < 26){rule.armsRule(play[Man],play[i]);}//炮吃规则else if (Man > 25 && Man < 30){rule.cannonRule(0,play[Man],play[i],play,me);}//车吃规则else if (Man >=0 && Man < 4){rule.cannonRule(1,play[Man],play[i],play,me);}//马吃规则else if (Man > 3 && Man < 8){rule.horseRule(play[Man],play[i],play,me);}//相、象吃规则else if (Man > 7 && Man < 12){rule.elephantRule(play[Man],play[i],play);}//士、仕吃棋规则else if (Man > 11 && Man < 16){rule.chapRule(Man,play[Man],play[i],play);}//将、帅吃棋规则else if (Man == 30 || Man == 31){rule.willRule(Man,play[Man],play[i],play);play[Man].setVisible(true);}//是否走棋错误(是否在原地没有动)if (Ex == play[Man].getX() && Ey == play[Man].getY()){text.setText(" 黑棋走棋");chessPlayClick=1;break;}else {text.setText(" 红棋走棋");chessPlayClick=2;break;}}//else if}//if}//for//是否胜利if (!play[31].isVisible()){JOptionPane.showConfirmDialog(this,"黑棋胜利","玩家一胜利",JOptionPane.DEFAULT_OPTION,JOptionPane.WARNING_MESSAGE);//双方都不可以在走棋了chessPlayClick=3;text.setText(" 黑棋胜利");}//ifelse if (!play[30].isVisible()){JOptionPane.showConfirmDialog(this,"红棋胜利","玩家二胜利",JOptionPane.DEFAULT_OPTION,JOptionPane.WARNING_MESSAGE);chessPlayClick=3;text.setText(" 红棋胜利");}//else if}//else}//else}public void mousePressed(MouseEvent me){}public void mouseReleased(MouseEvent me){}public void mouseEntered(MouseEvent me){}public void mouseExited(MouseEvent me){}/**** 定义按钮的事件响应*/public void actionPerformed(ActionEvent ae) { //重新开始按钮if (ae.getSource().equals(anew)){int i,k;//重新排列每个棋子的位置//黑色棋子//车for (i=0,k=24;i<2;i++,k+=456){play[i].setBounds(k,56,55,55);}//马for (i=4,k=81;i<6;i++,k+=342){play[i].setBounds(k,56,55,55);}//相for (i=8,k=138;i<10;i++,k+=228){play[i].setBounds(k,56,55,55);}//士for (i=12,k=195;i<14;i++,k+=114){play[i].setBounds(k,56,55,55);}//卒for (i=16,k=24;i<21;i++,k+=114){ play[i].setBounds(k,227,55,55); }//炮for (i=26,k=81;i<28;i++,k+=342){ play[i].setBounds(k,170,55,55); }//将play[30].setBounds(252,56,55,55);//红色棋子//车for (i=2,k=24;i<4;i++,k+=456){ play[i].setBounds(k,569,55,55); }//马for (i=6,k=81;i<8;i++,k+=342){ play[i].setBounds(k,569,55,55); }//相for (i=10,k=138;i<12;i++,k+=228){ play[i].setBounds(k,569,55,55); }//士for (i=14,k=195;i<16;i++,k+=114){ play[i].setBounds(k,569,55,55); }//兵for (i=21,k=24;i<26;i++,k+=114){ play[i].setBounds(k,398,55,55); }//炮for (i=28,k=81;i<30;i++,k+=342){ play[i].setBounds(k,455,55,55); }//帅play[31].setBounds(252,569,55,55);chessPlayClick = 2;text.setText(" 红棋走棋");for (i=0;i<32;i++){play[i].setVisible(true);}//清除Vector中的容Var.clear();}//悔棋按钮else if (ae.getSource().equals(repent)){try{//获得setVisible属性值String S = (String)Var.get(Var.size()-4);//获得X坐标int x = Integer.parseInt((String)Var.get(Var.size()-3));//获得Y坐标int y = Integer.parseInt((String)Var.get(Var.size()-2));//获得索引int M = Integer.parseInt((String)Var.get(Var.size()-1));//赋给棋子play[M].setVisible(true);play[M].setBounds(x,y,55,55);if (play[M].getName().charAt(1) == '1'){text.setText(" 黑棋走棋");chessPlayClick = 1;}else{text.setText(" 红棋走棋");chessPlayClick = 2;}//删除用过的坐标Var.remove(Var.size()-4);Var.remove(Var.size()-3);Var.remove(Var.size()-2);Var.remove(Var.size()-1);//停止旗子闪烁chessManClick=false;}catch(Exception e){}}//退出else if (ae.getSource().equals(exit)){int j=JOptionPane.showConfirmDialog(this,"真的要退出吗?","退出",JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE);if (j == JOptionPane.YES_OPTION){System.exit(0);}}}/*定义中国象棋规则的类*/class ChessRule {/**卒子的移动规则*/public void armsRule(int Man,JLabel play,MouseEvent me){ //黑卒向下if (Man < 21){//向下移动、得到终点的坐标模糊成合法的坐标if ((me.getY()-play.getY()) > 27 && (me.getY()-play.getY()) < 86 && (me.getX()-play.getX()) < 55 && (me.getX()-play.getX()) > 0){//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));play.setBounds(play.getX(),play.getY()+57,55,55);}//向右移动、得到终点的坐标模糊成合法的坐标、必须过河else if (play.getY() > 284 && (me.getX() - play.getX()) >= 57 && (me.getX() - play.getX()) <= 112){play.setBounds(play.getX()+57,play.getY(),55,55);}//向左移动、得到终点的坐标模糊成合法的坐标、必须过河else if (play.getY() > 284 && (play.getX() - me.getX()) >= 2 && (play.getX() - me.getX()) <=58){//模糊坐标play.setBounds(play.getX()-57,play.getY(),55,55);}}//红卒向上else{//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));//向上移动、得到终点的坐标模糊成合法的坐标if ((me.getX()-play.getX()) >= 0 && (me.getX()-play.getX()) <= 55 && (play.getY()-me.getY()) >27 && play.getY()-me.getY() < 86){play.setBounds(play.getX(),play.getY()-57,55,55);}//向右移动、得到终点的坐标模糊成合法的坐标、必须过河else if (play.getY() <= 341 && (me.getX() - play.getX()) >= 57 && (me.getX() - play.getX()) <= 112){play.setBounds(play.getX()+57,play.getY(),55,55);}//向左移动、得到终点的坐标模糊成合法的坐标、必须过河else if (play.getY() <= 341 && (play.getX() - me.getX()) >= 3 && (play.getX() - me.getX()) <=58){play.setBounds(play.getX()-57,play.getY(),55,55);}}}//卒移动结束/**卒吃棋规则*/public void armsRule(JLabel play1,JLabel play2){//向右走if ((play2.getX() - play1.getX()) <= 112 && (play2.getX() - play1.getX()) >= 57 && (play1.getY() - play2.getY()) < 22 && (play1.getY() - play2.getY()) > -22 && play2.isVisible() && play1.getName().charAt(1)!=play2.getName().charAt(1)){//黑棋要过河才能右吃棋if (play1.getName().charAt(1) == '1' && play1.getY() > 284 && play1.getName().charAt(1) != play2.getName().charAt(1)){play2.setVisible(false);//把对方的位置给自己play1.setBounds(play2.getX(),play2.getY(),55,55);}//红棋要过河才左能吃棋else if (play1.getName().charAt(1) == '2' && play1.getY() < 341 && play1.getName().charAt(1) != play2.getName().charAt(1)){play2.setVisible(false);//把对方的位置给自己play1.setBounds(play2.getX(),play2.getY(),55,55);}}//向左走else if ((play1.getX() - play2.getX()) <= 112 && (play1.getX() - play2.getX()) >= 57 && (play1.getY() - play2.getY()) < 22 && (play1.getY() - play2.getY()) > -22 && play2.isVisible() && play1.getName().charAt(1)!=play2.getName().charAt(1)){//黑棋要过河才能左吃棋if (play1.getName().charAt(1) == '1' && play1.getY() > 284 && play1.getName().charAt(1) != play2.getName().charAt(1)){play2.setVisible(false);//把对方的位置给自己play1.setBounds(play2.getX(),play2.getY(),55,55);}//红棋要过河才能右吃棋else if (play1.getName().charAt(1) == '2' && play1.getY() < 341 && play1.getName().charAt(1) != play2.getName().charAt(1)){play2.setVisible(false);//把对方的位置给自己play1.setBounds(play2.getX(),play2.getY(),55,55);}}//向上走else if (play1.getX() - play2.getX() >= -22 && play1.getX() - play2.getX() <= 22 && play1.getY() - play2.getY() >= -112 && play1.getY() - play2.getY() <= 112){//黑棋不能向上吃棋if (play1.getName().charAt(1) == '1' && play1.getY() < play2.getY() && play1.getName().charAt(1) != play2.getName().charAt(1)){play2.setVisible(false);//把对方的位置给自己play1.setBounds(play2.getX(),play2.getY(),55,55);}//红棋不能向下吃棋else if (play1.getName().charAt(1) == '2' && play1.getY() > play2.getY() && play1.getName().charAt(1) != play2.getName().charAt(1)){play2.setVisible(false);//把对方的位置给自己play1.setBounds(play2.getX(),play2.getY(),55,55);}}//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play1.isVisible()));Var.add(String.valueOf(play1.getX()));Var.add(String.valueOf(play1.getY()));Var.add(String.valueOf(Man));//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play2.isVisible()));Var.add(String.valueOf(play2.getX()));Var.add(String.valueOf(play2.getY()));Var.add(String.valueOf(i));}//卒吃结束/**炮、车移动规则*/public void cannonRule(JLabel play,JLabel playQ[],MouseEventme){//起点和终点之间是否有棋子int Count = 0;//上、下移动if (play.getX() - me.getX() <= 0 && play.getX() - me.getX() >= -55){//指定所有模糊Y坐标for (int i=56;i<=571;i+=57){//移动的Y坐标是否有指定坐标相近的if (i - me.getY() >= -27 && i - me.getY() <= 27){//所有的棋子for (int j=0;j<32;j++){//找出在同一条竖线的所有棋子、并不包括自己if (playQ[j].getX() - play.getX() >= -27 && playQ[j].getX() - play.getX() <= 27 && playQ[j].getName()!=play.getName() && playQ[j].isVisible()){//从起点到终点(从左到右)for (int k=play.getY()+57;k<i;k+=57){//大于起点、小于终点的坐标就可以知道中间是否有棋子if (playQ[j].getY() < i && playQ[j].getY() > play.getY()){//中间有一个棋子就不可以从这条竖线过去Count++;break;}}//for//从起点到终点(从右到左)for (int k=i+57;k<play.getY();k+=57){//找起点和终点的棋子if (playQ[j].getY() < play.getY() && playQ[j].getY() > i){Count++;break;}}//for}//if}//for//起点和终点没有棋子就可以移动了if (Count == 0){//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));play.setBounds(play.getX(),i,55,55);break;}}//if}//for}//if//左、右移动else if (play.getY() - me.getY() >=-27 && play.getY() - me.getY() <= 27){//指定所有模糊X坐标for (int i=24;i<=480;i+=57){//移动的X坐标是否有指定坐标相近的if (i - me.getX() >= -55 && i-me.getX() <= 0){//所有的棋子for (int j=0;j<32;j++){//找出在同一条横线的所有棋子、并不包括自己if (playQ[j].getY() - play.getY() >= -27 && playQ[j].getY() - play.getY() <= 27 && playQ[j].getName()!=play.getName() && playQ[j].isVisible()){//从起点到终点(从上到下)for (int k=play.getX()+57;k<i;k+=57){//大于起点、小于终点的坐标就可以知道中间是否有棋子if (playQ[j].getX() < i && playQ[j].getX() > play.getX()){//中间有一个棋子就不可以从这条横线过去Count++;break;}}//for//从起点到终点(从下到上)for (int k=i+57;k<play.getX();k+=57){//找起点和终点的棋子if (playQ[j].getX() < play.getX() && playQ[j].getX() > i){Count++;break;}}//for}//if}//for//起点和终点没有棋子if (Count == 0){//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));play.setBounds(i,play.getY(),55,55);break;}}//if}//for}//else}//炮、车移动方法结束/**炮、车吃棋规则*/public void cannonRule(int Chess,JLabel play,JLabel playTake,JLabel playQ[],MouseEvent me){//起点和终点之间是否有棋子int Count = 0;//所有的棋子for (int j=0;j<32;j++){//找出在同一条竖线的所有棋子、并不包括自己if (playQ[j].getX() - play.getX() >= -27 && playQ[j].getX() - play.getX() <= 27 && playQ[j].getName()!=play.getName() && playQ[j].isVisible()){//自己是起点被吃的是终点(从上到下)for (int k=play.getY()+57;k<playTake.getY();k+=57){//大于起点、小于终点的坐标就可以知道中间是否有棋子if (playQ[j].getY() < playTake.getY() && playQ[j].getY() > play.getY()){//计算起点和终点的棋子个数Count++;break;}}//for//自己是起点被吃的是终点(从下到上)for (int k=playTake.getY();k<play.getY();k+=57){//找起点和终点的棋子if (playQ[j].getY() < play.getY() && playQ[j].getY() > playTake.getY()){Count++;break;}}//for}//if//找出在同一条竖线的所有棋子、并不包括自己else if (playQ[j].getY() - play.getY() >= -10 && playQ[j].getY() - play.getY() <= 10 && playQ[j].getName()!=play.getName() && playQ[j].isVisible()){//自己是起点被吃的是终点(从左到右)for (int k=play.getX()+50;k<playTake.getX();k+=57){//大于起点、小于终点的坐标就可以知道中间是否有棋子if (playQ[j].getX() < playTake.getX() && playQ[j].getX() > play.getX()){Count++;break;}}//for//自己是起点被吃的是终点(从右到左)for (int k=playTake.getX();k<play.getX();k+=57){//找起点和终点的棋子if (playQ[j].getX() < play.getX() && playQ[j].getX() > playTake.getX()){Count++;break;}}//for}//if}//for//起点和终点之间要一个棋子是炮的规则、并不能吃自己的棋子if (Count == 1 && Chess == 0 && playTake.getName().charAt(1) != play.getName().charAt(1)){//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(playTake.isVisible()));Var.add(String.valueOf(playTake.getX()));Var.add(String.valueOf(playTake.getY()));Var.add(String.valueOf(i));playTake.setVisible(false);play.setBounds(playTake.getX(),playTake.getY(),55,55);}//起点和终点之间没有棋子是车的规则、并不能吃自己的棋子else if (Count ==0 && Chess == 1 && playTake.getName().charAt(1) != play.getName().charAt(1)){//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(playTake.isVisible()));Var.add(String.valueOf(playTake.getX()));Var.add(String.valueOf(playTake.getY()));Var.add(String.valueOf(i));playTake.setVisible(false);play.setBounds(playTake.getX(),playTake.getY(),55,55);}}//炮、车吃棋方法结束/**马移动规则*/public void horseRule(JLabel play,JLabel playQ[],MouseEvent me){ //保存坐标和障碍int Ex=0,Ey=0,Move=0;//上移、左边if (play.getX() - me.getX() >= 2 && play.getX() - me.getX() <= 57 && play.getY() - me.getY() >= 87 && play.getY() - me.getY() <= 141){ //合法的Y坐标for (int i=56;i<=571;i+=57){//移动的Y坐标是否有指定坐标相近的if (i - me.getY() >= -27 && i - me.getY() <= 27){Ey = i;break;}}//合法的X坐标for (int i=24;i<=480;i+=57){//移动的X坐标是否有指定坐标相近的if (i - me.getX() >= -55 && i-me.getX() <= 0){Ex = i;break;}}//正前方是否有别的棋子for (int i=0;i<32;i++){if (playQ[i].isVisible() && play.getX() - playQ[i].getX() == 0 && play.getY() - playQ[i].getY() == 57 ){Move = 1;break;}}//可以移动该棋子if (Move == 0){//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));play.setBounds(Ex,Ey,55,55);}}//if//左移、上边else if (play.getY() - me.getY() >= 27 && play.getY() - me.getY() <= 86 && play.getX() - me.getX() >= 70 && play.getX() - me.getX() <= 130){//Yfor (int i=56;i<=571;i+=57){if (i - me.getY() >= -27 && i - me.getY() <= 27){Ey = i;}}//Xfor (int i=24;i<=480;i+=57){if (i - me.getX() >= -55 && i-me.getX() <= 0){Ex = i;}}//正左方是否有别的棋子for (int i=0;i<32;i++){if (playQ[i].isVisible() && play.getY() - playQ[i].getY() == 0 && play.getX() - playQ[i].getX() == 57 ){Move = 1;break;}}if (Move == 0){//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));play.setBounds(Ex,Ey,55,55);}}//else//下移、右边else if (me.getY() - play.getY() >= 87 && me.getY() - play.getY() <= 141 && me.getX() - play.getX() <= 87 && me.getX() - play.getX() >= 2 ){//Yfor (int i=56;i<=571;i+=57){if (i - me.getY() >= -27 && i - me.getY() <= 27){Ey = i;}}//Xfor (int i=24;i<=480;i+=57){if (i - me.getX() >= -55 && i-me.getX() <= 0){Ex = i;}}//正下方是否有别的棋子for (int i=0;i<32;i++){if (playQ[i].isVisible() && play.getX() - playQ[i].getX() == 0 && playQ[i].getY() - play.getY() == 57 ){Move = 1;break;}}if (Move == 0){//当前记录添加到集合(用于悔棋)Var.add(String.valueOf(play.isVisible()));Var.add(String.valueOf(play.getX()));Var.add(String.valueOf(play.getY()));Var.add(String.valueOf(Man));play.setBounds(Ex,Ey,55,55);}}//else//上移、右边else if (play.getY() - me.getY() >= 87 && play.getY() - me.getY() <= 141 && me.getX() - play.getX() <= 87 && me.getX() - play.getX() >= 30 ){//合法的Y坐标for (int i=56;i<=571;i+=57){if (i - me.getY() >= -27 && i - me.getY() <= 27){。
人工智能大作业——极大极小算法实现一字棋学院:计算机学院班级:姓名:学号:辅导老师:日期:目录一、实验目的 (3)二、实验环境 (3)三、实验原理 (3)3.1 游戏规则 (3)3.2 极小极大分析法 (3)3.3 α -β剪枝算法.............................................................................. 错误!未定义书签。
3.4 输赢判断算法设计 (4)四、数据结构 (5)4.1 程序流程 (5)4.2 主要成员函数 (6)4.2.1 估值函数........................................................................... 错误!未定义书签。
4.2.2 Alpha-Beta 剪枝算法....................................................... 错误!未定义书签。
4.2.3 判断胜负........................................................................... 错误!未定义书签。
4.2.4 鼠标左键响应................................................................... 错误!未定义书签。
4.2.5 Draw 系列函数................................................................... 错误!未定义书签。
4.2.6 COMPUTER or PLAYER 先走............................................... 错误!未定义书签。
五、实验内容 (6)5.1 基本功能简介 (6)5.2 流程图.......................................................................................... 错误!未定义书签。
#include<iostream>using namespace std;void check(int i,int j); //检查每条直线上的各方棋子的数量int other(int b,int c);void check_win(); //检查是否胜利void begin(char ch);void computer(); //电脑下棋void user(); //用户下棋int a[4][4],deep;int line[3][3][2]; //全局变量,用来存放每条直线上的各方棋子数!//第一维下标表示是行列还是对角线,第二维下标表示第几条直线//第三维下标表示各方的棋子数!void main(){char ch;cout<<"欢迎与本机下#字棋!您的棋子将用#表示,电脑的棋子用X表示\n请选择先后手,输入u则您先手,输入c则电脑先手!(小写)\n"<<endl;do{cin>>ch;if(ch!='u'&&ch!='c') cout<<"您输入的数据不合法,请重新输入!"<<endl;}while(ch!='u'&&ch!='c'); //非法处理if(ch=='u') cout<<"您选择了您先手!\n"<<endl;else if(ch=='c') cout<<"您选择了电脑先手\n"<<endl;begin(ch);}void begin(char ch){int i,j,k;a[1][1]=1;cout<<"\n 1 | 2 | 3 \n ——————\n 4 | 5 | 6 \n ——————\n 7 | 8 | 9for(i=1;i<4;i++)for(j=1;j<4;j++){if(j==1)if(i==1);else a[i][j]=a[i-1][3]+1;else a[i][j]=a[i][j-1]+1;} //初始化棋盘for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)line[i][j][k]=0;deep=0;if(ch=='u') user();else computer();}void computer(){int i,j,flag=0,m; //flag判断是否落子for(i=0;i<3;i++)for(j=0;j<3;j++){if (line[i][j][0]==2&&line[i][j][1]==0&&flag==0){m=other(i,j);if(m%3==0) {a[m/3][3]=40;check(m/3,3);}else {a[m/3+1][m%3]=40; check(m/3+1,m%3);} //40是#的ASCII码减48flag=1;} //当某条直线上用户有两棋子而我方无棋子时,在该直线的另一点落子if (line[i][j][1]==2&&line[i][j][0]==0&&flag==0){m=other(i,j);if(m%3==0) {a[m/3][3]=40;check(m/3,3);}else {a[m/3+1][m%3]=40; check(m/3+1,m%3);} //当某条直线上我方有两棋子而对方无棋子时,在该直线的另一点落子flag=1;}if (line[i][j][1]==1&&line[i][j][0]==0&&flag==0){m=other(i,j);if(m%3==0) {a[m/3][3]=40;check(m/3,3);}else {a[m/3+1][m%3]=40; check(m/3+1,m%3);} //当某条直线上我方有一棋子而对方无棋子时,在该直线的另一点落子flag=1;}}if(flag==0)if (a[2][2]==5){a[2][2]=72;flag=1;check(2,2);} //优先下第5个位置else{for(i=2;i<9&&flag==0&&a[i][j]==(i-1)*3+j;i+=2){if(i%3==0) {a[i/3][3]=40;check(i/3,3);}else {a[i/3+1][i%3]=40; check(i/3+1,i%3);}flag=1;} //2,4,6,8其次for(i=1;i<9&&flag==0&&a[i][j]==(i-1)*3+j;i+=2){if(i%3==0) {a[i/3][3]=40;check(i/3,3);}else {a[i/3+1][i%3]=40; check(i/3+1,i%3);}flag=1;} //1,3,7,9再次for(i=1;i<=3;i++){cout<<" ";for(j=1;j<=3;j++)cout<<" "<<char(a[i][j]+48)<<" |";cout<<"\n ——————"<<endl;}deep++;if(flag==1) user();else check_win();}void user(){int down;cout<<"\n轮到您下了,请输入您要下的棋子位置:"<<endl;do{cin>>down;if(down<1||down>9)cout<<"数字不合法,请重新输入\n"<<endl;if ((down%3==0&&a[down/3][3]!=down)||(down%3!=0&&a[down/3+1][down%3]!=down)) cout<<"您所输入的位置已经有棋子了,请重新输入\n"<<endl;}while(down<1||down>9||((down%3==0&&a[down/3][3]!=down)||(down%3!=0&&a[down/3+ 1][down%3]!=down)));//判断输入是否异常if(down%3==0) {a[down/3][3]=-13; check(down/3,3);}else {a[down/3+1][down%3]=-13;check(down/3+1,down%3);} //-13是X的ASCII码减48deep++;computer();}int other(int b,int c)int i,m;if(b<2){if (b==0)m=3*c+1;if (b==1)m=c+1;for(i=m;i<m+3;i++){if(i%3==0)if(a[i/3][3]==i) return i;else;else if(a[i/3+1][i%3]) return i;}} //水平与垂直直线的情况 if(b==2){if(c==0){if(a[1][1]==1) return 1;if(a[2][2]==5) return 5;if(a[3][3]==9) return 9;}if(c==1){if(a[1][3]==3) return 3;if(a[2][2]==5) return 5;if(a[3][1]==7) return 7;}} //对角线的情况}void check(int i,int j){if(a[i][j]==-13)line[0][i-1][0]++;line[1][j-1][0]++;if((i==1&&j==1)||(i==3&&j==3)||(i==2&&j==2))line[2][0][0]++;if((i==1&&j==3)||(i==3&&j==1)||(i==2&&j==2))line[2][1][0]++;}if(a[i][j]==40){line[0][i-1][1]++;line[1][j-1][1]++;if((i==1&&j==1)||(i==3&&j==3)||(i==2&&j==2))line[2][0][1]++;if((i==1&&j==3)||(i==3&&j==1)||(i==2&&j==2))line[2][1][1]++;}check_win();}void check_win(){int i,j,k;bool end=false;char ch;for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<2;k++)if(line[i][j][k]==3){if(k==1) cout<<"您失败了,电脑获得了胜利"<<endl;if(k==0) cout<<"恭喜您,您获得了胜利"<<endl;end=true;}if(deep>=9) {cout<<"和棋!"<<endl;end=true;}if(end){cout<<"\n您是否继续是输入Y,按其余任意键结束本游戏!:"<<endl;cin>>ch;if(ch!='y') exit(0);else{cout<<"\n请选择先后手,输入U则您先手,输入C则电脑先手!\n"<<endl;do{cin>>ch;if(ch!='u'&&ch!='c') cout<<"您输入的数据不合法,请重新输入!"<<endl;}while(ch!='u'&&ch!='c'); //非法处理if(ch=='u') cout<<"您选择了您先手!\n"<<endl;else if(ch=='c') cout<<"您选择了电脑先手\n"<<endl;begin(ch);}}}。
#include<graphics.h>#include<conio.h>#include<string.h>#include<bios.h>#include<stdlib.h>#include"c:\tc\LIB\1.c"#define W 119#define S 115#define A 97#define D 100#define space 32#define UP 72#define DOWN 80#define LEFT 75#define RIGHT 77#define ENTER 13void qipan();void jiemian(int);void guangbiao1(int,int);void guangbiao2(int,int);void xuanzhong(int,int);void gaizi(int,int);char array(int,int);void xiazi(int,int,int,int);/*int panding(char,int,int,int,int);*/main(){int gdriver,gmode,i=0,c=0,x=190,y=190,m,n; char p;FILE *fp;gdriver=DETECT;gmode=0;if((fp=fopen("file.txt","at")) == NULL) {printf("Cannot open file!");system("pause");exit(0);}printf("%d,%d",gdriver,gmode); registerbgidriver(EGAVGA_driver);initgraph(&gdriver,&gmode,"c:\\tc"); cleardevice();while(c!=27){c=getch();clrscr();jiemian(i);if(c==80){fputs("down ",fp);i++;if(i==4){i=0;}}if(i==1){if(c==13){fputs("enter ",fp);qipan();c=getch();while(c!=27){c=getch();if(c==115){fputs("S ",fp);y=y+40;guangbiao1(x,y);guangbiao2(x,y-40);}if(c==119){fputs("W ",fp);y=y-40;guangbiao1(x,y);guangbiao2(x,y+40);}if(c==97){ fputs("A\n",fp);x=x-40;guangbiao1(x,y);guangbiao2(x+40,y);}if(c==100){ fputs("D\n",fp);x=x+40;guangbiao1(x,y);guangbiao2(x-40,y);}if(c==13){fputs("enter\n",fp);xuanzhong(x,y);m=x;n=y;}if(c==32){fputs("space\n",fp);xiazi(m,n,x,y);fputs("gaizi\n",fp);gaizi(m,n);}if(x>350||y>390||x<30||y<30){x=190;y=30;}}}}}getch();closegraph();fclose(fp);restorecrtmode();return 0;}void qipan(){int i,j;setbkcolor(GREEN);cleardevice();setlinestyle(0,0,3);setcolor(1);rectangle(10,10,370,410);rectangle(30,30,350,390);for(i=1;i<8;i++){setlinestyle(0,0,3);line(i*40+30,30,i*40+30,190);line(i*40+30,230,i*40+30,390);}for(j=1;j<9;j++){setlinestyle(0,0,3);line(30,j*40+30,350,j*40+30);}setlinestyle(3,0,3);line(150,30,230,110);line(230,30,150,110);line(150,310,230,390);line(230,310,150,390); setusercharsize(4,1,2,1); settextstyle(1,0,4);outtextxy(70,195,"chinese chess"); red_shuai(190,30);red_shi(150,30);red_shi(230,30);red_xiang(110,30);red_xiang(270,30);red_ma(70,30);red_ma(310,30);red_ju(30,30);red_ju(350,30);red_pao(70,110);red_pao(310,110);red_bing(30,150);red_bing(110,150);red_bing(190,150);red_bing(270,150);red_bing(350,150);black_jiang(190,390);black_shi(150,390);black_shi(230,390);black_xiang(110,390);black_xiang(270,390);black_ma(70,390);black_ma(310,390);black_ju(30,390);black_ju(350,390);black_pao(70,310);black_pao(310,310);black_zu(30,270);black_zu(110,270);black_zu(190,270);black_zu(270,270);black_zu(350,270);setcolor(BLUE);rectangle(400,30,600,320);setcolor(4);settextstyle(1,0,2);outtextxy(420,50,"A->shuai B->shi"); outtextxy(420,80,"C->xiang D->ma"); outtextxy(420,110,"E->ju F->pao"); outtextxy(420,140,"G->bing"); setcolor(8);outtextxy(420,200,"H->jiang I->shi"); outtextxy(420,230,"J->xiang K->ma"); outtextxy(420,260,"L->ju M->pao"); outtextxy(420,290,"N->zu");}void jiemian(int i){setbkcolor(GREEN); cleardevice();settextstyle(1,0,8);setcolor(BLUE);outtextxy(50,70,"chinese chess"); settextstyle(0,0,3);setcolor(RED);outtextxy(260,215,"start"); outtextxy(260,255,"again"); outtextxy(260,295,"undo"); outtextxy(260,335,"exit"); rectangle(250,210+i*40,390,240+i*40); }void guangbiao1(int x,int y){setcolor(WHITE);setlinestyle(0,0,3);line(x-17,y-7,x-17,y-17);line(x-7,y-17,x-17,y-17);line(x+7,y-17,x+17,y-17);line(x+17,y-7,x+17,y-17);line(x-7,y+17,x-17,y+17);line(x-17,y+7,x-17,y+17);line(x+17,y+7,x+17,y+17);line(x+7,y+17,x+17,y+17);}void guangbiao2(int x,int y){setcolor(GREEN);setlinestyle(0,0,3);line(x-17,y-7,x-17,y-17);line(x-7,y-17,x-17,y-17);line(x+7,y-17,x+17,y-17);line(x+17,y-7,x+17,y-17);line(x-7,y+17,x-17,y+17);line(x-17,y+7,x-17,y+17);line(x+17,y+7,x+17,y+17);line(x+7,y+17,x+17,y+17);}void xuanzhong(int x,int y){setcolor(CYAN);setlinestyle(0,0,3);circle(x,y,15);}void gaizi(int x1,int y1){setlinestyle(0,0,3);setcolor(GREEN);circle(x1,y1,15);setfillstyle(0,3);floodfill(x1,y1,GREEN);setcolor(1);setlinestyle(0,0,3);if((30<x1<350)&&((y1==30)||(y1==230))) {line(x1-18,y1,x1+18,y1);line(x1,y1,x1,y1+18);if((30<x1<350)&&(y1==390||y1==190)) {line(x1-18,y1,x1+18,y1);line(x1,y1-18,x1,y1);}if((30<y1<390)&&x1==30){line(x1,y1,x1+18,y1);line(x1,y1-18,x1,y1+18);}if((30<y1<390)&&(x1==350)){line(x1-18,y1,x1,y1);line(x1,y1-18,x1,y1+18);}if((x1==30)&&(y1==30)){line(x1,y1,x1+18,y1);line(x1,y1,x1,y1+18);}if((x1==350)&&(y1==30)){line(x1-18,y1,x1,y1);line(x1,y1,x1,y1+18);}if((x1==30)&&(y1==390)){line(x1,y1,x1+18,y1);line(x1,y1,x1,y1-18);}if((x1==350)&&(y1==390)){line(x1,y1,x1-18,y1);line(x1,y1,x1,y1-18);}else{line(x1-18,y1,x1+18,y1);line(x1,y1-18,x1,y1+18);}}char array(int i,int j)char a[13][13];int c,b;c=i;b=j;for(c=1;c<10;c++){for(b=1;b<11;b++){a[c][b]='Z';}}a[1][5]='A';a[1][4]='B';a[1][6]='B';a[1][3]='C';a[1][7]='C';a[1][2]='D';a[1][8]='D';a[1][1]='E';a[1][9]='E';a[3][2]='F';a[3][8]='F';a[4][1]=a[4][3]=a[4][5]=a[4][7]=a[4][9]='G';a[10][5]='H';a[10][4]='I';a[10][6]='I';a[10][3]='J';a[10][7]='J';a[10][2]='K';a[10][8]='K';a[10][1]='L';a[10][ 9]='L';a[2][3]='M';a[8][3]='M';a[7][1]=a[7][3]=a[7][5]=a[7][7]=a[7][9]='N';return a[i][j];}void xiazi(int x6,int y6,int x7,int y7){switch(array(y6/40+1,x6/40+1)){case 'A':red_shuai(x7,y7);break;case 'B':red_shi(x6,y7);break;case 'C':red_xiang(x7,y7);break;case 'D':red_ma(x7,y7);break;case 'E':red_ju(x7,y7);break;case 'F':red_pao(x7,y7);break;case 'G':red_bing(x7,y7);break;case 'H':black_jiang(x7,y7);break;case 'I':black_shi(x7,y7);break;case 'J':black_xiang(x7,y7);break;case 'K':black_ma(x7,y7);break;case 'L':black_ju(x7,y7);break;case 'M':black_pao(x7,y7);break;case 'N':black_zu(x7,y7);break;case 'Z':gaizi(x6,x6);break;}}/*int panding(char q,int x,int y,int a,int b){switch(q){case 'A':if(y>110||x>230||x<150||(a-x)>40||(x-a)>40||(y-b)>40||(b-y)>40)return 0;elsereturn 1;break;case'B':if(((x-a)==40&&(y-b)==40)&&y<=110&&230<x<150||((a-x)==40&&(b-y)==40)&&y<=110& &230>x>150)return 1;elsereturn 0;break;case'C':if((((x-a)==80&&(y-b)==80)&&y<=190)&&(array((y+b)/2/40+1,(x+a)/2/40+1,)=='Z')))||(((a-x)==80&&(b-y)==80)&&y<=190)&&(array((y+b)/2/40+1,(x+a)/2/40+1)=='Z'))))return 1;elsereturn 0;break;case'D':if((((x-a)==80&&(y-b)==40&&(array(y/40+1,(x-40)/40+1)=='Z'))||(((a-x)==80&&(b-y)==40)&&(array(y/40+1,(x+40)/40+1)=='Z'))||(((x-a)==40&&(y-b)==80)(array((y-40)/40+1,x/40+1)==' Z'))||(((a-x)==40&&(b-y)==80)&&(array((y+40)/40+1,x/40+1)=='z'))))return 1;elsereturn 0;break;case 'E':return 1;break;case 'F':return 1;break;case 'G':if(y<190){if(y>b||x!=a){return 0;}elsereturn 1;}else{if((b-y)>40||(a-x)>40||(x-a)>40||y>b){return 0;}elsereturn 1;}break;case 'H':if(y<310||x>230||x<150||(a-x)>40||(x-a)>40||(y-b)>40||(b-y)>40)return 0;elsereturn 1;break;case'I':if(((x-a)==40&&(y-b)==40)&&y>=310&&230<x<150||((a-x)==40&&(b-y)==40)&&y>310&& 230>x>150)return 1;elsereturn 0;break;case可编辑'J':if(((((x-a)==80&&(y-b)==80)&&y>=230)&&array(((y+b)/2/40+1,(x+a)/2/40+1)=='Z')))||(((a-x )==80&&(b-y)==80)&&y>=230)&&(array((y+b)/2/40+1,(x+a)/2/40+1)=='Z'))))return 1;elsereturn 0;break;case'K':if((((x-a)==80&&(y-b)==40&&(array(y/40+1,(x-40)/40+1)=='Z'))||(((a-x)==80&&(b-y)==40) &&(array(y/40+1,(x+40)/40+1)=='Z'))||(((x-a)==40&&(y-b)==80)(array((y-40)/40+1,x/40+1)==' Z'))||(((a-x)==40&&(b-y)==80)&&(array((y+40)/40+1,x/40+1)=='Z'))return 1;elsereturn 0;break;case 'L':return 1;break;case 'M':return 1;break;case 'N':if(y>230){if(y<b||x!=a){return 0;}elsereturn 1;}else{if(y-b>40||(a-x)>40||(x-a)>40||y<b){return 0;}elsereturn 1;}default:return 0;}}*/.。
实验二:利用α-β搜索过程的博弈树搜索算法编写一字棋游戏(3学时)一、实验目的与要求(1)了解极大极小算法的原理和使用方法,并学会用α-β剪枝来提高算法的效率。
(2)使用C语言平台,编写一个智能井字棋游戏。
(3)结合极大极小算法的使用方法和α-β剪枝,让机器与人对弈时不但有智能的特征,而且计算的效率也比较高。
二、实验原理一字棋游戏是一个流传已久的传统游戏。
游戏由两个人轮流来下,分别用“X”和“O”来代替自身的棋子。
棋盘分9个格,双方可以在轮到自己下的时候,可以用棋子占领其中一个空的格子。
如果双方中有一方的棋子可以连成一条直线,则这一方判胜,对方判负。
当所有的格子都被占领,但双方都无法使棋子连成一条直线的话,则判和棋。
这是一个智能型的一字棋游戏,机器可以模拟人与用户对弈。
当轮到机器来下的时候,机器会根据当前棋局的形势,利用极大极小算法算出一个评价值,判断如何下才对自身最有利,同时也是对方来说对不利的,然后下在评价值最高的地方。
另外利用α-β剪枝,使机器在搜索评价值的时候不用扩展不必要的结点,从而提高机器计算的效率。
在用户界面方法,用一个3×3的井字格来显示用户与机器下的结果。
当要求用户输入数据的时候会有提示信息。
用户在下的过程中可以中途按下“0”退出。
当用户与计算机分出了胜负后,机器会显示出比赛的结果,并按任意键退出。
如果用户在下棋的过程中,输入的是非法字符,机器不会做出反应。
三、实验步骤和过程1.α-β搜索过程在极小极大搜索方法中,由于要先生成指定深度以内的所有节点,其节点数将随着搜索深度的增加承指数增长。
这极大地限制了极小极大搜索方法的使用。
能否在搜索深度不变的情况下,利用已有的搜索信息减少生成的节点数呢?设某博弈问题如下图所示,应用极小极大方法进行搜索MINIMAX过程是把搜索树的生成和格局估值这两个过程分开来进行,即先生成全部搜索树,然后再进行端节点静态估值和倒推值计算,这显然会导致低效率。
一字棋实验报告题目:一字棋学号:姓名:专业:教师:XXXX大学计算机科学与技术学院摘要:本实验的思想有别于其他实验,程序实现起来相对简单。
在人机对垒中,分别编写了计算机走步Mac函数,人走步User函数,评分value函数,判定输赢CheckWin函数,以及打印PrintQP函数和主函数。
本实验的创新点主要集中在Mac函数和value函数。
计算机在走步之前先将当前棋盘复制给临时棋盘,在此我定义了两个临时棋盘。
在临时棋盘1中计算机试探性地走了一步,相应地在临时棋盘2中的相同位置计算机帮人走了一步,接下来分别对两个临时棋盘调用CheckWin函数,根据返回的结果分别选择性地记录该走步的坐标位置。
最后计算机再将临时棋盘1送入value函数,并记录评分。
重置临时棋盘1和2,依次对所有空缺位置进行试探。
根据返回的结果选择合适的坐标位置。
而value函数实现起来相对比较简单,简化了极大极小分析法。
返回的值等于所有空格上都放上计算机的棋子后,计算机的三个棋子所组成的行、列及对角线的总数减去所有空格上都放上人的棋子后,人的三个棋子所组成的行、列及对角线的总数。
而在机机对垒中的Mac1函数和Mac2函数比较相似,其他函数类似。
关键词:极大极小分析法临时棋盘试探评价一、一字棋游戏的文字描述“一字棋”游戏(又叫“三字棋”或“井字棋”),是一款十分经典的益智小游戏。
游戏双方在一个3*3的格子上依次下入自己的棋子,任何一方首先三子连成一线即获胜利,游戏结束。
二、一字棋对垒过程计算机描述和实现首先我定义一个3*3的二维数组,作为一字棋的棋盘。
1、主函数main程序输出当前棋盘并提示判断是否玩家先走步。
然后玩家电脑依次走步,当当前棋盘能够判断输赢时,游戏结束,否则直到棋盘下满,游戏结束。
2、打印函数PrintQP打印二维数组,即当前棋盘。
3、玩家走步函数User实现玩家的走步,并判断玩家的走步是否有误,返回结果。
4、计算机走步函数Mac该函数是整个程序实现智能的关键所在,函数中定义两个临时棋盘,一个是给计算机试探走步使用,另一个是计算机替玩家走步使用,并结合其他的判断语句和评价函数value,得出一个最佳的走步坐标,并实现。
#include <iostream>#include <windows.h>#include <conio.h>#include <string>#include <ctime>using namespace std;#define MAX_NUM 1000 //计算机获胜的标志#define NO_BLANK -1001//人获胜的标志#define TREE_DEPTH 3 //递归深度#define NIL 1001 //根节点的函数走步评估值class State //棋盘状态节点,一个State实例就是一个棋盘的状态节点,从而形成一颗树状结构{public:int QP[3][3]; //当前棋盘数组int e_fun; //评分结果int child[9]; //当前棋盘状态下的后一步的所有状态节点int parent; //当前棋盘状态下的父母节点下标int bestChild;//在child[9]里e_fun最优的节点下标};class Tic{public:int tmpQP[3][3]; //用于3层递归的临时棋盘static int s_count;//叶子节点的静态总数State States[MAX_NUM];//棋盘状态节点数组Tic(){}void init() //初始化棋盘,将各个位置的棋盘都置为0{s_count=0;for(int i=0;i<3;i++)for(int j=0;j<3;j++){States[0].QP[i][j] = 0;}States[0].parent = NIL;}void PrintQP()//棋盘界面显示{for(int i=0;i<3;i++){for(int j=0;j<3;j++){cout<<States[0].QP[i][j]<<'\t';}cout<<endl;}}int IsWin(State s) //判断当前的棋盘状态是否有令任何一方获胜{for(int i=0;i<3;i++){if(s.QP[i][0]==1&&s.QP[i][1]==1&&s.QP[i][2]==1)return 1;if(s.QP[i][0]==-1&&s.QP[i][1]==-1&&s.QP[i][2]==-1)return -1;}for(i=0;i<3;i++){if(s.QP[0][i]==1&&s.QP[1][i]==1&&s.QP[2][i]==1)return 1;if(s.QP[0][i]==-1&&s.QP[1][i]==-1&&s.QP[2][i]==-1)return -1;}if((s.QP[0][0]==1&&s.QP[1][1]==1&&s.QP[2][2]==1)||(s.QP[2][0]==1&&s.QP[1][1]==1& &s.QP[0][2]==1))return 1;if((s.QP[0][0]==-1&&s.QP[1][1]==-1&&s.QP[2][2]==-1)||(s.QP[2][0]==-1&&s.QP[1][1]== -1&&s.QP[0][2]==-1))return -1;return 0;}int e_fun(State s)//机器智能判定评价函数{bool flag=true;for(int i=0;i<3;i++)for(int j=0;j<3;j++)if(s.QP[i][j]==0)flag=false;if(flag)return NO_BLANK;if(IsWin(s)==-1)return -MAX_NUM;if(IsWin(s)==1)return MAX_NUM;int count=0;for(i=0;i<3;i++)for(int j=0;j<3;j++)if(s.QP[i][j]==0)tmpQP[i][j]=1;else tmpQP[i][j]=s.QP[i][j];for(i=0;i<3;i++)count+=(tmpQP[i][0]+tmpQP[i][1]+tmpQP[i][2])/3;for(i=0;i<3;i++)count+=(tmpQP[0][i]+tmpQP[1][i]+tmpQP[2][i])/3;count+=(tmpQP[0][0]+tmpQP[1][1]+tmpQP[2][2])/3;count+=(tmpQP[2][0]+tmpQP[1][1]+tmpQP[0][2])/3;for( i=0;i<3;i++)for(int j=0;j<3;j++)if(s.QP[i][j]==0)tmpQP[i][j]=-1;else tmpQP[i][j]=s.QP[i][j];for(i=0;i<3;i++)count+=(tmpQP[i][0]+tmpQP[i][1]+tmpQP[i][2])/3;for(i=0;i<3;i++)count+=(tmpQP[0][i]+tmpQP[1][i]+tmpQP[2][i])/3;count+=(tmpQP[0][0]+tmpQP[1][1]+tmpQP[2][2])/3;count+=(tmpQP[2][0]+tmpQP[1][1]+tmpQP[0][2])/3;return count;}virtual bool AutoDone(){return false;}void UserInput()//获取用户的输入{int pos,x,y;L1: cout<<"请输入棋子的坐标(xy): ";cin>>pos;x=pos/10,y=pos%10;if(x>0&&x<4&&y>0&&y<4&&States[0].QP[x-1][y-1]==0)else{cout<<"非法输入!";goto L1;}}};int Tic::s_count = 0;//初始化棋盘状态节点总数,刚开始置为0class demo : public Tic{public:demo(){}bool Judge(){int i,j,a=0;for(i=0;i<3;i++)for(j=0;j<3;j++)if(States[0].QP[i][j]==0) a++;if(a==0)return true;return false;}virtual bool AutoDone(){ int a,b,i,j,m,n,max,min,x,y;if(IsWin(States[0])==-1){cout<<"恭喜您获胜!"<<endl;return true;}a=0,b=0;max=-10000;for(x=0;x<3;x++)for(y=0;y<3;y++)States[11].QP[x][y]=States[0].QP[x][y];for(i=0;i<3;i++)for(j=0;j<3;j++){{ a=1;for(x=0;x<3;x++)for(y=0;y<3;y++)States[a].QP[x][y]=States[0].QP[x][y];States[a].QP[i][j]=1;min=10000;for(m=0;m<3;m++)for(n=0;n<3;n++){if(States[a].QP[m][n]==0){ b=1;for(x=0;x<3;x++)for(y=0;y<3;y++)States[10].QP[x][y]=States[a].QP[x][y];States[10].QP[m][n]=-1;States[10].e_fun=e_fun(States[10]);if(States[10].e_fun<min) min=States[10].e_fun;}}States[a].e_fun=min;if(States[a].e_fun>max){ max=States[a].e_fun;for(x=0;x<3;x++)for(y=0;y<3;y++)States[11].QP[x][y]=States[a].QP[x][y];}}}for(x=0;x<3;x++)for(y=0;y<3;y++)States[0].QP[x][y]=States[11].QP[x][y];cout<<"计算机走棋"<<endl;PrintQP();if(IsWin(States[0])==1){cout<<"抱歉你输了,计算机获胜!"<<endl;return true;}else if(IsWin(States[0])==-1){cout<<"恭喜您获胜!"<<endl;return true;}return false;}};void main(){system("title #子棋智能小游戏");system("color b1");char IsFirst;bool IsFinish;cout<<"若您为先手,请输入'y':"<<endl;cin>>IsFirst;demo *p=new demo();p->init();cout<<"棋盘的初始状态:"<<endl;p->PrintQP();do{ if(!p->Judge()){if(IsFirst=='y'){p->UserInput();p->PrintQP();if(!p->Judge()){IsFinish=p->AutoDone();}}else{ IsFinish=p->AutoDone();if(!p->Judge()){if(!IsFinish) {p->UserInput();p->PrintQP();}} }}if(p->Judge()) IsFinish=true;}while (!IsFinish);if((p->IsWin(p->States[0])==0)&&p->Judge()){cout<<"平局"<<endl;}}。