📄 gobang.cpp
字号:
/***********************************************************
****五子棋**
**2006.11.21
*************************************************************/
#include <qpainter.h>
#include <stdlib.h>
#include <qstatusbar.h>
#include <qimage.h>
#include <qpainter.h>
#include <qprinter.h>
#include <stdio.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#include <sys/wait.h>
#include <pthread.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
#include <qbutton.h>
#include "gobang.h"
/************************************************************
*
**************宏定义***************************************
*
*************************************************************/
#define DEST_IP "10.197.8.23"
#define DEST_PORT 1234
#define MYPORT 1234
#define BACKLOG 10
#define MAXSIZE 80
#pragma pack(1)//传送包
struct pack
{
int over;
int x;
int y;
};
#pragma pack()
int BB;
/***********************************************************
****
****************类外函数定义
**
*********************************************************/
void *Message(void *arg)//接受消息函数
{
Gobang *g;
int sockfd,n;
fd_set read;
g=(Gobang *)arg;
sockfd=g->sockfd;
while (1)
{
FD_ZERO(&read);
FD_SET(sockfd,&read);
select(sockfd+1,&read,NULL,NULL,NULL);
if(FD_ISSET(sockfd,&read))
{
unsigned char rec[MAXSIZE];
n = recv(sockfd, rec, MAXSIZE,0);
pack *pack1;
pack1=new pack;
pack1=(pack *)&rec;
debug("x=%d",pack1->x);
debug("y=%d",pack1->y);
if(pack1->over==1)
{
debug("You lose!");
}
BB=pack1->over;
if(g->Button==2)
{
g->rect[pack1->x][pack1->y]=2;
}
if(g->Button==1)
{
g->rect[pack1->x][pack1->y]=3;
}
g->turn=1;
g->update(pack1->x*Rect,pack1->y*Rect,Rect,Rect);
delete pack1;
}
}
}
/*****************************************************
**
****************类函数定义
**
******************************************************/
Gobang::Gobang( QWidget *parent, const char *name ): QMainWindow( parent,name )//构造函数
{
setFixedSize(Num*Rect,Num*Rect+30);
createMenu();
Init();
}
Gobang::~Gobang()//析构函数
{
}
/******************************************************
*********************成员函数******************
*******************************************************/
void Gobang::Init()//初始化
{
int i, j,count=0,k;
Button=0;
over=false;
num[1]=num[0]=0;
BB=0;
///棋盘初始化
for( i=0;i<15;i++)
for( j=0;j<15;j++)
{
if(i==0||i==14) rect[i][j]=0;
else if(j==0||j==1) rect[i][j]=0;
else rect[i][j]=1;
}
///获胜初始化
for(i=0;i<15;i++)
{
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
Stab[i][j+k][count]=true;
Ctab[i][j+k][count]=true;
}
count++;
}
}
for(i=0;i<15;i++)
{
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
Stab[j+k][i][count]=true;
Ctab[j+k][i][count]=true;
}
count++;
}
}
for(i=0;i<11;i++)
{
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
Stab[j+k][i+k][count]=true;
Ctab[j+k][i+k][count]=true;
}
count++;
}
}
for(i=0;i<11;i++)
{
for(j=14;j>=4;j--)
{
for(k=0;k<5; k++)
{
Stab[j-k][i+k][count]=true;
Ctab[j-k][i+k][count]=true;
}
count++;
}
}
//获胜组合初始化
for(i=0;i<572;i++)
{
win[0][i]=0;
win[1][i]=0;
}
}
void Gobang::ComputerTurn()//人机对战计算机处理
{
int grades[2][15][15];
int m,n,i,max=0;
int u,v;
for(m=0;m<15;m++)
for(n=0;n<15;n++)
{
grades[0][m][n]=0;
grades[1][m][n]=0;
if(rect[m][n]==1)
{
for(i=0;i<572;i++)
{
//计算Stab的获胜分数
if(Stab[m][n][i]&&win[0][i]!=7)
{
switch(win[0][i])
{
case 0:
grades[0][m][n]+=1;
break;
case 1:
grades[0][m][n]+=200;
break;
case 2:
grades[0][m][n]+=400;
break;
case 3:
grades[0][m][n]+=2000;
break;
case 4:
grades[0][m][n]+=10000;
break;
}
}
//计算Ctab的获胜分数
if(Ctab[m][n][i]&&win[1][i]!=7)
{
switch(win[1][i])
{
case 0:
grades[1][m][n]+=1;
break;
case 1:
grades[1][m][n]+=220;
break;
case 2:
grades[1][m][n]+=420;
break;
case 3:
grades[1][m][n]+=2100;
break;
case 4:
grades[1][m][n]+=20000;
break;
}
}
}
if(max==0)
{
u=m;
v=n;
}
if(grades[0][m][n]>max)
{
max=grades[0][m][n];
u=m;
v=n;
}
else if(grades[0][m][n]==max)
{
if(grades[1][m][n]>grades[1][u][v])
{
u=m;
v=n;
}
}
if(grades[1][m][n]>max)
{
max=grades[1][m][n];
u=m;
v=n;
}
else if(grades[1][m][n]==max)
{
if(grades[0][m][n]>grades[0][u][v])
{
u=m;
v=n;
}
}
}
}
rect[u][v]=3;
QPixmap pixmapW("w.gif");//白子
QPainter paint( this );
paint.drawPixmap ( u*Rect, v*Rect, pixmapW,0, 0,-1,-1);
for(i=0;i<572;i++)
{
if(Ctab[u][v][i])
{
win[1][i]++;
Stab[u][v][i]=false;
win[0][i]=7;
if(win[1][i]==5)
{
winer=1;
over=true;
statusBar()->message("You lose!");
BB=1;
}
}
}
}
/**********************************************************
********************事件函数*********************
**********************************************************/
void Gobang::paintEvent(QPaintEvent *)
{
QPixmap pixmapBJ("bj.gif");//背景
QPixmap pixmapB("b.gif");//黑子
QPixmap pixmapW("w.gif");//白子
int i,j;
QPainter paint( this );
paint.drawPixmap ( 0, 30, pixmapBJ, 0, 0, -1, -1 ) ;
for( i=0;i<15;i++)
for( j=0;j<15;j++)
{
if(rect[i][j]==2)
paint.drawPixmap ( i*Rect, j*Rect, pixmapB,0, 0,-1,-1);
if(rect[i][j]==3)
paint.drawPixmap ( i*Rect, j*Rect, pixmapW,0, 0,-1,-1);
}
if(Button!=0)
{
if(turn==1) statusBar()->message("Return you now!");
if(turn==0) statusBar()->message("Please wait the other player!");
}
if(BB==1) statusBar()->message("You lose!");
if(BB==2) statusBar()->message("You win!");
}
void Gobang::mousePressEvent(QMouseEvent *event)
{
QPixmap pixmapB("b.gif");//黑子
QPixmap pixmapW("w.gif");//白子
int x,y,i;
debug("x=%d,y=%d",event->x(),event->y());
QPainter paint( this );
x=(int)((event->x())/Rect);
y=(int)((event->y())/Rect);
if(rect[x][y]==1&&turn==1)
{
pack *pack1;
pack1=new pack;
pack1->x=x;
pack1->y=y;
pack1->over=0;
unsigned char *sends;
if(Button==1&&!over&&BB==0)
{
rect[x][y]=2;
paint.drawPixmap ( x*Rect, y*Rect, pixmapB,0, 0,-1,-1);
turn=0;
for(i=0;i<572;i++)
{
if(Stab[x][y][i])
{
win[0][i]++;
Ctab[x][y][i]=false;
win[1][i]=7;
if(win[0][i]==5)
{
BB=2;
over=true;
}
}
}
if(over) pack1->over=1;
sends=(unsigned char *)pack1;
send(sockfd, (const char *)sends, sizeof(pack), 0);
}
if(Button==2&&BB==0)
{
rect[x][y]=3;
paint.drawPixmap ( x*Rect, y*Rect, pixmapW,0, 0,-1,-1);
turn=0;
for(i=0;i<572;i++)
{
if(Stab[x][y][i])
{
win[0][i]++;
Ctab[x][y][i]=false;
win[1][i]=7;
if(win[0][i]==5)
{
BB=2;
over=true;
statusBar()->message("You win!");
}
}
}
if(over) pack1->over=1;
sends=(unsigned char *)pack1;
send(sockfd, (const char *)sends, sizeof(pack), 0);
}
if(Button==3)
{
if(!over)
if(turn)
{
rect[x][y]=2;
num[0]++;
paint.drawPixmap ( x*Rect, y*Rect, pixmapB,0, 0,-1,-1);
for(i=0;i<572;i++)
{
if(Stab[x][y][i])
{
win[0][i]++;
Ctab[x][y][i]=false;
win[1][i]=7;
if(win[0][i]==5)
{
winer=0;
over=true;
statusBar()->message("You win!");
}
}
}
if(!over)
ComputerTurn();
}
}
delete pack1;
}
}
/****************************************************************
**************************槽函数************************
*****************************************************************/
void Gobang::createMenu()
{
QPopupMenu *popup;
QMenuBar *menubar=menuBar();
QPixmap pixmap;
popup= new QPopupMenu();
popup->insertItem("creat&Server",this,SLOT(creatServer()),ALT+Key_S);
popup->insertItem("creat&Client",this,SLOT(creatClient()),ALT+Key_C);
popup->insertItem("&Play whit computer",this,SLOT(Play_with_computer()),ALT+Key_P);
menubar->insertItem("&Play",popup);
popup= new QPopupMenu();
popup->insertItem(pixmap,this,NULL);
menubar->insertItem("&About",popup);
statusBar()->message("Welcome play gobang!");
}
void Gobang::creatServer()//创建五指棋游戏
{
Init();
Button=1;
turn=1;
int ret;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
debug("error in socket\n");
exit(1);
}
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
if (ret < 0)
{
debug("error in bind\n");
exit(1);
}
ret = listen(sockfd, BACKLOG);
if (ret < 0)
{
debug("error in listen\n");
exit(1);
}
sin_size = sizeof(struct sockaddr_in);
sockfd = accept(sockfd, (struct sockaddr *)&their_addr,(socklen_t *) &sin_size);
if (sockfd < 0)
{
debug("error in accept\n");
exit(1);
}
debug("get connected:\n");
debug("client IP address:%s\n", inet_ntoa(their_addr.sin_addr));
debug(" port :%d\n", their_addr.sin_port);
pthread_t tid1;
pthread_create(&tid1, NULL, Message, this);
}
void Gobang::creatClient()//加入五指棋游戏
{
Init();
Button=2;
turn=0;
int ret;
struct sockaddr_in dest_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&dest_addr,0,sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(DEST_PORT);
dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);
ret = ::connect(sockfd, (struct sockaddr *)&dest_addr,
sizeof(struct sockaddr));
if (ret == -1)
{
debug("error linking\n");
exit(0);
}
pthread_t tid1;
pthread_create(&tid1, NULL, Message, this);
}
void Gobang::Play_with_computer()//人机对战
{
Init();
Button=3;
turn=1;
update();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -