⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gobang.cpp

📁 linux下的五指棋的人机对战版。用QT做的。
💻 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 + -