五子棋实现悔棋功能的代码(五子棋作弊)

http://www.itjxue.com  2023-03-05 21:37  来源:未知  点击次数: 

C/C++五子棋问题,高手请指教

#include?Windows.h

#include?string

#include?list

using?namespace?std;

//函数声明

LRESULT?CALLBACK?WindowProcedure(HWND,UINT,WPARAM,LPARAM);

void?InitChess(); //初始化棋盘

void?ComputerMove(); //电脑落子

bool?CheckChess(); //检查棋盘是否有空余位置

bool?WinCheck(); //胜利检查

int?P(int); //返回某点棋子

int?P(int,?int); //返回某点棋子

int?P2I(int,int); //转换二维索引为一维索引

int?GetN(int?i,int?d); //获取一个棋子的某一个方向上的棋子坐标。

char?ge(int?a,int?p); //判断是己方棋子(1)还是障碍(2,对方棋子或棋盘外围)还是空位(0),a为待判断棋子,p为己方棋子。

int?CountV(int?i,?int?d,?int?pl); //计数一个落子处某个方向上的权重值。

int?GetBest(); //获取最佳落子点

//定义变量

char?szClassName[]?=?"CFive"; //Class?Name

int?chess[225]; //1为玩家棋子,-1为电脑棋子,0为空。

listint?fallen; //已落棋子,用于后期添加悔棋功能。

listint?r; //列表用于保存所有拥有相同最大权值的点用于随机抽取

listint::iterator?it; //迭代器

int?state?=?1; //表示当前状态,1:玩家下棋,2:电脑下棋,3:胜利,4:失败

//画刷

HBRUSH?hbr?=?CreateSolidBrush(0x0000ff); //红色画刷(标记上次落子)

HBRUSH?hbw?=?CreateSolidBrush(0xffffff); //白色画刷(画白棋)

HBRUSH?hbb?=?CreateSolidBrush(0x000000); //黑色画刷(画黑棋)

HPEN?hp?=?CreatePen(PS_SOLID,?1,?0x000000); //1宽度黑色画笔(画棋盘,棋子边框)

HPEN?hp2?=?CreatePen(PS_SOLID,?2,?0x000000); //2宽度黑色画笔(画棋盘边框)

//核心数据,影响整个AI判断

//棋型列表

string?cl[]?=?{"11111",?"011110",?"11110",?"11101",?"11011",?"011100",?"011010",?"11100",?"10110",?"11010",?"10101",?"001100",?"011000",?"010100",?"01100",?"010010",?"11000",?"10100"};

//电脑对应棋型的权重

int?cv[]?=?{1000000,?100000,?2500,?2800,?2600,?3100,?3000,?550,?800,?550,?570,?650,?600,?450,?300,?200,?120,?120};

//玩家对应棋型的权重

int?pv[]?=?{900000,?90000,?2500,?2450,?2600,?2850,?2800,?450,?700,?460,?490,?600,?500,?350,?200,?40,?40,?40};

int?WINAPI?WinMain(HINSTANCE?hThisInstance,

???HINSTANCE?hPrevInstance,

???LPSTR?lpszArgument,

???int?nFunsterStil)

{

HWND?hwnd; //窗口句柄

MSG?messages;

WNDCLASSEX?wincl;

wincl.hInstance?=?hThisInstance;

wincl.lpszClassName?=?szClassName;

wincl.lpfnWndProc?=?WindowProcedure;

wincl.style?=?CS_DBLCLKS;

wincl.cbSize?=?sizeof(WNDCLASSEX);

wincl.hIcon?=?LoadIcon(NULL,?IDI_APPLICATION);

wincl.hIconSm?=?LoadIcon(NULL,?IDI_APPLICATION);

wincl.hCursor?=?LoadCursor(NULL,?IDC_ARROW);

wincl.lpszMenuName?=?NULL;

wincl.cbClsExtra?=?0;

wincl.cbWndExtra?=?0;

wincl.hbrBackground?=??(HBRUSH)COLOR_BACKGROUND; //窗体背景色

InitChess(); //初始化棋盘

if(!RegisterClassEx(wincl))

return?-1; //注册失败

hwnd?=?CreateWindowEx(

0,

szClassName, //窗体类名

"五子棋", //窗体标题

WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, //窗体样式

CW_USEDEFAULT, //左坐标

CW_USEDEFAULT, //顶坐标

340, //宽

360, //高

HWND_DESKTOP, //父窗体

NULL, //菜单

hThisInstance, //实例句柄

NULL

);

ShowWindow(hwnd,?nFunsterStil);

//消息循环

while(GetMessage(messages,NULL,0,0)){

TranslateMessage(messages);

DispatchMessage(messages);

}

return?messages.wParam;

}

LRESULT?CALLBACK?WindowProcedure(HWND?hwnd,?UINT?message,?WPARAM?wParam,?LPARAM?lParam)

{

HDC?hdc; //设备上下文句柄

PAINTSTRUCT?ps;

char?str[3]; //坐标轴上的文字

//x,y分别为相对棋盘的坐标

int?x?=?(LOWORD(lParam)-15)/20;

int?y?=?(HIWORD(lParam)-15)/20;

switch(message)

{

case?WM_DESTROY:

PostQuitMessage(0);

break;

case?WM_PAINT:

hdc?=?BeginPaint(hwnd,?ps);

SetBkMode(hdc,TRANSPARENT);

SelectObject(hdc,hp2);

MoveToEx(hdc,21,21,NULL);

LineTo(hdc,21,308);

LineTo(hdc,308,308);

LineTo(hdc,308,21);

LineTo(hdc,21,21); //棋盘边框

SelectObject(hdc,hp);

SelectObject(hdc,hbb);

Ellipse(hdc,82,82,87,87);

Ellipse(hdc,242,82,247,87);

Ellipse(hdc,242,242,247,247);

Ellipse(hdc,82,242,87,247);

Ellipse(hdc,162,162,167,167);

for(int?i=0;i15;i++){

str[0]=i+65;

TextOut(hdc,i*20+20,5,str,1); //画出字母序号

_ltoa_s(i+1,str,10);

TextOut(hdc,i=9?1:10,i*20+20,str,(i+1)/10+1); //画出数字序号

MoveToEx(hdc,24,i*20+24,NULL);

LineTo(hdc,304,i*20+24);

MoveToEx(hdc,i*20+24,24,NULL);

LineTo(hdc,i*20+24,304); //画出棋盘

}

for(int?i=0;i15;i++) //遍历棋盘,画出棋子

for(int?j=0;j15;j++){

switch(P(i,j)){

case?1: //黑棋

SelectObject(hdc,hbb);

Ellipse(hdc,i*20+15,j*20+15,i*20+18+15,j*20+18+15);

break;

case?-1: //白棋

SelectObject(hdc,hbw);

Ellipse(hdc,i*20+15,j*20+15,i*20+18+15,j*20+18+15);

break;

}

if(!fallen.empty()fallen.back()==P2I(i,j)){

SelectObject(hdc,hbr);

Ellipse(hdc,i*20+19,j*20+19,i*20+10+19,j*20+10+19);

}

}

SelectObject(hdc,CreateFont(30,0,0,0,FW_BLACK,false,false,false,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH,"宋体"));

if(state2)TextOut(hdc,100,30,state==3?"玩家获胜!":"电脑获胜!",10);

SelectObject(hdc,CreateFont(20,0,0,0,FW_BLACK,false,false,false,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH,"宋体"));

if(state2)TextOut(hdc,105,60,"单击以继续...",13);

EndPaint(hwnd,ps); //结束绘制

if(state==2){ //轮到电脑落子

ComputerMove();

state=WinCheck()?4:1; //更新状态

InvalidateRect(hwnd,NULL,true); //重绘窗体

}

break;

case?WM_LBUTTONUP:

switch(state){

case?3:

case?4:

state=1; //单击以继续

InitChess(); //初始化

InvalidateRect(hwnd,NULL,true); //重绘

break;

case?1:

if(x=0x15y=0y15P(x,y)==0){

chess[x*15+y]=1; //更改棋盘

fallen.push_back(x*15+y); //加入已落棋子列表

state=WinCheck()?3:2;

InvalidateRect(hwnd,NULL,true);

}

}

break;

default:

return?DefWindowProc(hwnd,?message,?wParam,?lParam); //默认消息处理

}

return?0;

}

//初始化棋盘

void?InitChess()

{

for(int?i=0;i225;i++)chess[i]=0; //全部棋子置空

fallen.clear(); //清空已落棋子列表

}

//电脑走棋

void?ComputerMove()

{

int?r=GetBest();

chess[r]=-1;

fallen.push_back(r);

}

//检查棋盘是否有空位

bool?CheckChess()

{

for(int?i=0;i15*15;i++)if(!chess[i])return?true;

return?false;

}

//转换二维索引为一维索引

int?P2I(int?x,int?y)

{

if(x0||y0||x14||y14)return?255;

return?x*15+y;

}

//获取整数的符号

int?sign(int?n)

{

return?n0?1:n0?-1:0;

}

//获取一个棋子的某一个方向上的棋子坐标。方向:1-右;2-右下;3-下;4-左下。其它方向负数。

int?GetN(int?i,int?d) //比如(3,4)的右边为(4,4),不过本函数以一维坐标表示

{

????int?x?=?i?/?15;

????int?y?=?i?%?15;

????switch(abs(d)){

case?1:

return?P2I(x?+?sign(d),?y);

case?2:

????????return?P2I(x?+?sign(d),?y?+?sign(d));

case?3:

????????return?P2I(x,?y?+?sign(d));

case?4:

????????return?P2I(x?-?sign(d),?y?+?sign(d));

default:

????????return?P2I(x,?y);

}

}

//返回某点棋子

int?P(int?x,?int?y)

{

if(x0||y0||x14||y14)

return?3;

else?if(x==-1||x==15||y==-1||y==15)

return?2;

else

return?chess[x*15+y];

}

//返回某点棋子

int?P(int?n)

{

return?P(n?/?15,?n?%?15);

}

//判断是己方棋子(1)还是障碍(2,对方棋子或棋盘外围)还是空位(0),a为待判断棋子,p为己方棋子。

char?ge(int?a,int?p)

{

if(a==p)

return?'1';

else?if(a==-p)

return?'2';

else

return?(char)(a+48);

}

//计数一个落子处某个方向上的权重值。

int?CountV(int?i,?int?d,?int?pl)

{

string?str=""; //用于保存棋型

int?tmp?=?i;

for(int?j=1;j5;j++){ //前4格

tmp=GetN(tmp,-d);

str=ge(P(tmp),pl)+str;

if(P(tmp)==2)break; //遇到阻挡的就退出循环

}

str?+=?'1'; //自身

for(int?j=1;j5;j++){ //后4格

i=GetN(i,d);

str?+=?ge(P(i),pl);

if(P(tmp)==2)break;

}

for(int?j=0;j18;j++) //挨个比较棋型,藉此获得权重值

if(str.find(cl[j])!=str.npos||str.find(string(cl[j].rbegin(),cl[j].rend()))!=str.npos)

return?pl==1?pv[j]:cv[j];

return?0;

}

//计算一个落子处的价值

int?GetValue(int?i)

{

int?n=0;

for(int?j=1;j5;j++){

n+=CountV(i,j,1); //对玩家的价值

n+=CountV(i,j,-1); //对电脑的价值

}

return?n;

}

//获取最优落子点

int?GetBest()

{

int?n=0,tmp; //n保存最大值,tmp临时变量

r.clear();

for(int?i=0;i225;i++){

if(P(i)==0){

tmp=GetValue(i);

if(tmpn){ //如果比已存的数大,就清空列表,并替换值

r.clear();

r.push_back(i);

n=tmp;

}else?if(tmp==n) //如果相等,就添加

r.push_back(i);

if(r.front()=1000000)?return?r.front(); //如果遇到连成5子的就直接选它了

}

}

it=r.begin();

tmp=rand()%r.size();

for(int?i=1;itmp;i++)it++;

return?*it; //随机从列表中返回一个位置

}

//计数一个棋子某个方向上的连子数。i,棋子坐标。d,方向。1-右;2-右下;3-下;4-左下。其它方向负数。

int?Count(int?i,int?d)

{

int?n=i;

int?c=0;

while(P(n)==P(i)){

n=GetN(n,d);

c++;

}

return?c-1;

}

//检查是否连成五子

bool?WinCheck()

{

int?i=fallen.back(); //检查最后一个落子的周围即可

for(int?j=1;j=4;j++) //依次判断4个方向

if(Count(i,j)+Count(i,-j)=4)

return?true;

return?false;

}

上面是完整代码,请参考。

用C++编写双人五子棋游戏时,如何才能做到悔棋的功能啊(可悔多步),用动态链可以实现么?求高人指点啊!

每下一步,放棋的位置全压栈,悔几步就弹出几下。动态链是可以实现的。

C++MFC五子棋悔棋的功能怎么做

提示:你的棋局记录方法必须能够追溯行棋过程,这样才能实现悔棋(倒退)

如果你的棋局记录方法是只记录棋子位置的话,是不能实现悔棋的。

求五子棋c或c++代码

五子棋C原码

/*turboc2.0下编译通过*/

#i nclude graphics.h

#i nclude stdlib.h

#i nclude stdio.h

#i nclude conio.h

#define N 15

#define B 7

#define STOP -10000

#define OK 1

#define NO 0

#define UP 328

#define DOWN 336

#define LEFT 331

#define RIGHT 333

/*定义了两个数,n为棋盘的大小。b为背景颜色的数值*/

int a[N+1][N+1];

int zx,zy;

int write=1,biaoji=0;

struct zn{

long sum;

int y;

int x;

}w[N+1][N+1],max,max1;

void cbar(int i,int x,int y,int r);

void map(int a[][]);

int getkey();

int key();

void zuobiao(int x,int y,int i);

int tu(int a[][],int write);

int wtu(int a[][],int write);

int zhineng(int a[][]);

int zh5(int y,int x,int a[][]);

long zzh5(int b[][],int i);

main()

{

int i,j;

int gdriver=DETECT;

int gmode;

initgraph(gdriver,gmode,"");

zx=(N+1)/2;

zy=(N+1)/2;

for(i=1;i=N;i++)

for(j=1;j=N;j++)

a[i][j]=0;

map(a);

i=1;

while(i)

{

int k,n;

k=wtu(a,write);

if(k==STOP) goto end;

map(a);

n=zhineng(a);

if(n==STOP) goto end;

map(a);

}

end:

;

}

/* 实现对局的程序 ,计算全部N*N个格中,最应该填的格子 */

int zhineng(int a[N+1][N+1])

{

int i,j;

int k;

max.sum=-1;

for(i=0;i=N;i++)

for(j=0;j+N;j++)

{

w[i][j].sum=0;

w[i][j].x=i;

w[i][j].y=j;

}

for(i=1;i=N-4;i++)

for(j=1;j=N-4;j++)

{

k=zh5(i,j,a);

if(k==STOP) return (STOP);

}

for(i=1;i=N;i++)

for(j=1;j=N;j++)

{

if(max.sumw[i][j].sum)

{

max.sum=w[i][j].sum;

max.y=i;

max.x=j;

}

else if(max.sum==w[i][j].sum)

{

if(((max.y-zy)*(max.y-zy)+(max.x-zx)*(max.x-zx))((i-zy)*(i-zy)+(j-zx)*(j-zx)))

max.sum=w[i][j].sum;

max.y=i;

max.x=j;

}

}

if(a[max.y][max.x]==0)

{

a[max.y][max.x]=-1;

zy=max.y;

zx=max.x;

}

}

/* 转换成5*5的数组,计算出在二十五个格子中,最应该填的格 */

int zh5(int y,int x,int a[N+1][N+1])

{

int i,j;

int b[6][6];

long c[13];

long d[6][6];

long temp;

for(i=y;i=y+4;i++)

for(j=x;j=x+4;j++)

b[i+1-y][j+1-x]=a[i][j];

c[1]=b[1][1]+b[1][2]+b[1][3]+b[1][4]+b[1][5];

c[2]=b[2][1]+b[2][2]+b[2][3]+b[2][4]+b[2][5];

c[3]=b[3][1]+b[3][2]+b[3][3]+b[3][4]+b[3][5];

c[4]=b[4][1]+b[4][2]+b[4][3]+b[4][4]+b[4][5];

c[5]=b[5][1]+b[5][2]+b[5][3]+b[5][4]+b[5][5];

c[6]=b[1][1]+b[2][1]+b[3][1]+b[4][1]+b[5][1];

c[7]=b[1][2]+b[2][2]+b[3][2]+b[4][2]+b[5][2];

c[8]=b[1][3]+b[2][3]+b[3][3]+b[4][3]+b[5][3];

c[9]=b[1][4]+b[2][4]+b[3][4]+b[4][4]+b[5][4];

c[10]=b[1][5]+b[2][5]+b[3][5]+b[4][5]+b[5][5];

c[11]=b[1][1]+b[2][2]+b[3][3]+b[4][4]+b[5][5];

c[12]=b[1][5]+b[2][4]+b[3][3]+b[4][2]+b[5][1];

for(i=1;i=12;i++)

{

switch(c[i])

{

case 5:biaoji=1;return(STOP);

case -5:biaoji=-1;return(STOP);

case -4:c[i]=100000;break;

case 4:c[i]=100000;break;

case -3:c[i]=150;break;

case 3:c[i]=150;break;

case -2:c[i]=120;break;

case 2:c[i]=100;break;

case -1:c[i]=1;break;

case 1:c[i]=1;break;

default: c[i]=0;

}

}

for(i=1;i=12;i++)

{

if(c[i]==150)

c[i]+=zzh5(b,i);

}

for(i=1;i=5;i++)

for(j=1;j=5;j++)

d[i][j]=0;

for(i=1;i=5;i++)

for(j=1;j=5;j++)

{

if(i==j) d[i][j]+=c[11];

if((i+j)==6) d[i][j]+=c[12];

d[i][j]+=c[i]+c[j+5];

}

for(i=1;i=5;i++)

for(j=1;j=5;j++)

{

if(b[i][j]!=0)

d[i][j]=-2;

}

max1.sum=-1;

max1.y=0;

max1.x=0;

for(i=1;i=5;i++)

for(j=1;j=5;j++)

{

if(max1.sumd[i][j])

{

max1.sum=d[i][j];

max1.y=i;

max1.x=j;

w[i+y-1][j+x-1].sum+=max1.sum;

}

else if(max1.sum==d[i][j])

{

if(((i+y-1-zy)*(i+y-1-zy)+(j+x-1-zx)*(j+x-1-zx))((max1.y+y-1-zy)*(max1.y+y-1-zy)+(max1.x+x-1-zx)*(max1.x+x-1-zx)))

{

max1.sum=d[i][j];

max1.y=i;

max1.x=j;

}

}

}

}

long zzh5(int b[6][6],int n)

{

int i,j,k,l,m;

switch(n)

{

case 1:i=b[1][1];j=b[1][2];k=b[1][3];l=b[1][4];m=b[1][5];break;

case 2:i=b[2][1];j=b[2][2];k=b[2][3];l=b[2][4];m=b[2][5];break;

case 3:i=b[3][1];j=b[3][2];k=b[3][3];l=b[3][4];m=b[3][5];break;

case 4:i=b[4][1];j=b[4][2];k=b[4][3];l=b[4][4];m=b[4][5];break;

case 5:i=b[5][1];j=b[5][2];k=b[5][3];l=b[5][4];m=b[5][5];break;

case 6:i=b[1][1];j=b[2][1];k=b[3][1];l=b[4][1];m=b[5][1];break;

case 7:i=b[1][2];j=b[2][2];k=b[3][2];l=b[4][2];m=b[5][2];break;

case 8:i=b[1][3];j=b[2][3];k=b[3][3];l=b[4][3];m=b[5][3];break;

case 9:i=b[1][4];j=b[2][4];k=b[3][4];l=b[4][4];m=b[5][4];break;

case 10:i=b[1][5];j=b[2][5];k=b[3][5];l=b[4][5];m=b[5][5];break;

case 11:i=b[1][1];j=b[2][2];k=b[3][3];l=b[4][4];m=b[5][5];break;

case 12:i=b[1][5];j=b[2][4];k=b[3][3];l=b[4][2];m=b[5][1];break;

}

if((i==0j==1k==1l==1m==0))

return (900);

if((i==0j==-1k==-1l==-1m==0))

return(1000);

if((i==0j==0k==1l==1m==1)||(i==1j==1k==1l==0m==0))

return(20);

if((i==0j==0k==-1l==-1m==-1)||(i==-1j==-1k==-1l==0m==0))

return(20);

if((i==-1j==1k==1l==1m==1)||(i==1j==-1k==1l==1m==1)||(i==1j==1k==-1l==1m==1)||(i==1j==1k==1l==-1m==1)||(i==1j==1k==1l==1m==-1))

return(-60);

if((i==1j==-1k==-1l==-1m==-1)||(i==-1j==1k==-1l==-1m==-1)||(i==-1j==1k==-1l==-1m==-1)||(i==-1j==-1k==-1l==1m==-1)||(i==-1j==-1k==-1l==-1m==1))

return(-60);

}

/* 循环执行坐标的选择,直到按回车,空格或ESC键 */

int wtu(int a[N+1][N+1],int write)

{

int i=1;

map(a);

zuobiao(zx,zy,1);

while(i)

{

int k;

k=tu(a,write);

if(k==OK) i=0;

if(k==STOP) return (STOP);

}

}

/*从键盘获得输入的值*/

int getkey()

{

int key,lo,hi;

key=bioskey(0);

lo=key0x00ff;

hi=(key0xff00)8;

return((lo==0) ? hi+256:lo);

}

/*对获得的值进行判断*/

/*对应的码值分别如下*/

/* 上:328 下:336 左: 331 右: 333 */

/* 回车:13 ESC键: 27 */

int key()

{

int k;

k=getkey();

switch(k)

{

case 27: return (STOP);

case 13:

case ' ': return (OK);

case 328: return (UP);

case 336: return (DOWN);

case 331: return (LEFT);

case 333: return (RIGHT);

default: return (NO);

}

}

/*用来显示坐标的位置*/

void zuobiao(int x,int y,int i)

{

int r;

if(i!=0)

{

setcolor(GREEN);

for(r=1;r=5;r++)

circle(75+25*x,25+25*y,r);

}

else

{

if(a[zy][zx]==1)

{

setcolor(8);

for(r=1;r=5;r++)

circle(75+25*x,25+25*y,r);

}

else if(a[zy][zx]==-1)

{

setcolor(WHITE);

for(r=1;r=5;r++)

circle(75+25*x,25+25*y,r);

}

else

{

setcolor(B);

for(r=1;r=5;r++)

circle(75+25*x,25+25*y,r);

setcolor(RED); line(75+25*zx-5,25+25*zy,75+25*x+5,25+25*zy);

line(75+25*zx,25+25*zy-5,75+25*zx,25+25*zy+5);

}

}

}

/*从键盘获得的值进行判断,反映在显示的图上*/

int tu(int a[N+1][N+1],int write)

{

int k;

re:

k=key();

if(k==OK)

{

if(a[zy][zx]==0)

{

a[zy][zx]=write;

}

else

goto re;

}

if(k==STOP) return(STOP);

if(k==NO) goto re;

if(k==UP)

{

int i,j;

if(zy==1) j=zy;

else j=zy-1;

zuobiao(zx,zy,0);

zuobiao(zx,j,1);

zy=j;

goto re;

}

if(k==DOWN)

{

int i,j;

if(zy==N) j=zy;

else j=zy+1;

zuobiao(zx,zy,0);

zuobiao(zx,j,1);

zy=j;

goto re;

}

if(k==LEFT)

{

int i,j;

if(zx==1) i=zx;

else i=zx-1;

zuobiao(zx,zy,0);

zuobiao(i,zy,1);

zx=i;

goto re;

}

if(k==RIGHT)

{

int i,j;

if(zx==N) i=zx;

else i=zx+1;

zuobiao(zx,zy,0);

zuobiao(i,zy,1);

zx=i;

goto re;

}

}

/* 根据数组中(存储棋子位置)各位置的数,画实心圆(画出棋子)*/

void cbar(int i,int x,int y,int r)

{

if(i!=0)

{

if(i==1)

setcolor(8);

else if(i==-1)

setcolor(WHITE);

for(i=1;i=r;i++)

{

circle(x,y,i);

}

}

}

/*画出棋盘,和各个棋子*/

void map(int a[N+1][N+1])

{

int i,j;

cleardevice();

setbkcolor(B);

setcolor(RED);

for(i=0;iN;i++)

{

line(100,50+25*i,75+N*25,50+25*i);

line(100+25*i,50,100+25*i,25+N*25);

}

for(i=1;i=N;i++)

for(j=1;j=N;j++)

cbar(a[i][j],75+25*j,25+25*i,10);

}

在线等!求一个python 五子棋源代码,最好是有“人人对弈”和“人机对弈”功能的,不胜感谢!

试试这个吧。

import numpy as np

import pygame

import sys

import traceback

import copy

from pygame.locals import *

pygame.init()

pygame.mixer.init()

#颜色

background=(201,202,187)

checkerboard=(80,80,80)

button=(52,53,44)

#音乐

play_chess_sound = pygame.mixer.Sound("music/play_chess.wav")

play_chess_sound.set_volume(0.2)

button_sound = pygame.mixer.Sound("music/button.wav")

button_sound.set_volume(0.2)

victor_sound = pygame.mixer.Sound("music/victory.wav")

victor_sound.set_volume(0.2)

#绘制棋盘

def Draw_a_chessboard(screen):

#填充背景色

screen.fill(background)

Background=pygame.image.load("background.jpg").convert_alpha()

screen.blit(Background,(0,0))

#画棋盘

for i in range(21):

pygame.draw.line(screen, checkerboard, (40*i+3, 3), (40*i+3, 803))

pygame.draw.line(screen, checkerboard, (3, 40*i+3), (803, 40*i+3))

#画边线

pygame.draw.line(screen, checkerboard, (3, 3), (803, 3),5)

pygame.draw.line(screen, checkerboard, (3, 3), (3, 803),5)

pygame.draw.line(screen, checkerboard, (803, 3), (803, 803),5)

pygame.draw.line(screen, checkerboard, (3, 803), (803, 803),5)

#画定位点

pygame.draw.circle(screen, checkerboard, (163, 163), 6)

pygame.draw.circle(screen, checkerboard, (163, 643), 6)

pygame.draw.circle(screen, checkerboard, (643, 163), 6)

pygame.draw.circle(screen, checkerboard, (643, 643), 6)

pygame.draw.circle(screen, checkerboard, (403, 403), 6)

#画‘悔棋’‘重新开始’跟‘退出’按钮

pygame.draw.rect(screen,button,[900,350,120,100],5)

pygame.draw.rect(screen,button,[900,500,200,100],5)

pygame.draw.rect(screen,button,[900,650,200,100],5)

s_font=pygame.font.Font('font.ttf',40)

text1=s_font.render("悔棋",True,button)

text2=s_font.render("重新开始",True,button)

text3=s_font.render("退出游戏",True,button)

screen.blit(text1,(920,370))

screen.blit(text2,(920,520))

screen.blit(text3,(920,670))

#绘制棋子(横坐标,纵坐标,屏幕,棋子颜色(1代表黑,2代表白))

def Draw_a_chessman(x,y,screen,color):

if color==1:

Black_chess=pygame.image.load("Black_chess.png").convert_alpha()

screen.blit(Black_chess,(40*x+3-15,40*y+3-15))

if color==2:

White_chess=pygame.image.load("White_chess.png").convert_alpha()

screen.blit(White_chess,(40*x+3-15,40*y+3-15))

#绘制带有棋子的棋盘

def Draw_a_chessboard_with_chessman(map,screen):

screen.fill(background)

Draw_a_chessboard(screen)

for i in range(24):

for j in range(24):

Draw_a_chessman(i+1,j+1,screen,map[i][j])

#定义存储棋盘的列表,

#列表为24列24行是因为判断是否胜利函数里的索引会超出19

#列表大一点不会对游戏有什么影响

map=[]

for i in range(24):

map.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])

#清零map列表

def clear():

global map

for i in range(24):

for j in range(24):

map[i][j]=0

#判断是否胜利

def win(i, j):

k = map[i][j]

p=[]

for a in range(20):

p.append(0)

for i3 in range(i-4,i+5):

for j3 in range(j-4,j+5):

if (map[i3][j3] == k and i3 - i == j3 - j and i3 = i and j3 = j):

p[0]+=1

if (map[i3][j3] == k and j3 == j and i3 = i and j3 = j):

p[1]+=1

if (map[i3][j3] == k and i3 == i and i3 = i and j3 = j):

p[2]+=1

if (map[i3][j3] == k and i3 - i == j3 - j and i3 = i and j3 = j):

p[3]+=1

if (map[i3][j3] == k and j3 == j and i3 = i and j3 = j):

p[4]+=1

if (map[i3][j3] == k and i3 == i and i3 = i and j3 = j):

p[5]+=1

if (map[i3][j3] == k and i - i3 == j3 - j and i3 = i and j3 = j):

p[6]+=1

if (map[i3][j3] == k and i3 - i == j - j3 and i3 = i and j3 = j):

p[7]+=1

if (map[i3][j3] == k and j - j3 == i - i3 and i3 = i + 1 and i3 = i - 3 and j3 = j + 1 and j3 = j - 3):

p[8]+=1

if (map[i3][j3] == k and j == j3 and i3 = i + 1 and i3 = i - 3 and j3 = j + 1 and j3 = j - 3):

p[9]+=1

if (map[i3][j3] == k and i == i3 and i3 = i + 1 and i3 = i - 3 and j3 = j + 1 and j3 = j - 3):

p[10]+=1

if (map[i3][j3] == k and j - j3 == i - i3 and i3 = i - 1 and i3 = i + 3 and j3 = j - 1 and j3 = j + 3):

p[11]+=1

if (map[i3][j3] == k and j == j3 and i3 = i - 1 and i3 = i + 3 and j3 = j - 1 and j3 = j + 3):

p[12]+=1

if (map[i3][j3] == k and i == i3 and i3 = i - 1 and i3 = i + 3 and j3 = j - 1 and j3 = j + 3):

p[13]+=1

if (map[i3][j3] == k and i - i3 == j3 - j and i3 = i + 1 and i3 = i - 3 and j3 = j - 1 and j3 = j + 3):

p[14]+=1

if (map[i3][j3] == k and i3 - i == j - j3 and i3 = i - 1 and i3 = i + 3 and j3 = j + 1 and j3 = j - 3):

p[15]+=1

if (map[i3][j3] == k and j - j3 == i - i3 and i3 = i + 2 and i3 = i - 2 and j3 = j + 2 and j3 = j - 2):

p[16]+=1

if (map[i3][j3] == k and j == j3 and i3 = i + 2 and i3 = i - 2 and j3 = j + 2 and j3 = j - 2):

p[17]+=1

if (map[i3][j3] == k and i == i3 and i3 = i + 2 and i3 = i - 2 and j3 = j + 2 and j3 = j - 2):

p[18]+=1

if (map[i3][j3] == k and i - i3 == j3 - j and i3 = i + 2 and i3 = i - 2 and j3 = j + 2 and j3 = j - 2):

p[19]+=1

for b in range(20):

if p[b]==5:

return True

return False

#绘制提示器(类容,屏幕,字大小)

def text(s,screen,x):

#先把上一次的类容用一个矩形覆盖

pygame.draw.rect(screen,background,[850,100,1200,100])

#定义字体跟大小

s_font=pygame.font.Font('font.ttf',x)

#定义类容,是否抗锯齿,颜色

s_text=s_font.render(s,True,button)

#将字放在窗口指定位置

screen.blit(s_text,(880,100))

pygame.display.flip()

#用于控制顺序

t=True

#用于结束游戏后阻止落子

running=True

#主函数

def main():

#将 t,map,running设置为可改的

global t,map,running,maps,r,h

#将map置零

clear()

#定义储存所有棋盘状态的列表(用于悔棋)

map2=copy.deepcopy(map)

maps=[map2]

#定义窗口

screen = pygame.display.set_mode([1200,806])

#定义窗口名字

pygame.display.set_caption("五子棋")

#在窗口画出棋盘,提示器以及按钮

Draw_a_chessboard(screen)

pygame.display.flip()

clock=pygame.time.Clock()

while True:

#只有running为真才能落子,主要用于游戏结束后防止再次落子

if running:

if t:

color=1

text('黑棋落子',screen,54)

else:

color=2

text('白棋落子',screen,54)

for event in pygame.event.get():

#点击x则关闭窗口

if event.type ==pygame.QUIT:

pygame.quit()

sys.exit()

#点击窗口里面类容则完成相应指令

elif event.type == MOUSEBUTTONDOWN:

if event.button == 1:

x,y=event.pos[0],event.pos[1]

for i in range(19):

for j in range(19):

#点击棋盘相应位置

if i*40+3+20xi*40+3+60 and j*40+3+20yj*40+3+60 and not map[i][j] and running:

#在棋盘相应位置落相应颜色棋子

Draw_a_chessman(i+1,j+1,screen,color)

#播放音效

play_chess_sound.play(0)

#在map里面记录落子位置

map[i][j]=color

#将map存入maps

map3=copy.deepcopy(map)

maps.append(map3)

#判断落子后是否有五子一线

if win(i,j):

if t:

text('黑棋胜利,请重新游戏',screen,30)

else:

text('白棋胜利,请重新游戏',screen,30)

#播放音效

victor_sound.play(0)

#阻止再往棋盘落子

running=False

pygame.display.flip()

t=not t

#如果点击‘重新开始’

if 900x1100 and 500y600:

#取消阻止

running=True

#播放音效

button_sound.play(0)

#重新开始

main()

#点击‘退出游戏’,退出游戏

elif 900x1100 and 650y750:

#播放音效

button_sound.play(0)

pygame.quit()

sys.exit()

#点击‘悔棋’

elif 900x1020 and 350y450 and len(maps)!=1:

#播放音效

button_sound.play(0)

#删除maps里最后一个元素

del maps[len(maps)-1]

#再将最后一个元素copy给map

map=copy.deepcopy(maps[len(maps)-1])

#切换顺序

t=not t

#将map显示出来

Draw_a_chessboard_with_chessman(map,screen)

#悔棋完成,阻止再次悔棋

x,y=0,0

clock.tick(60)

if __name__ == "__main__":

try:

main()

except SystemExit:

pass

except:

traceback.print_exc()

pygame.quit()

input()

(责任编辑:IT教学网)

更多

推荐Access文章