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

📄 gomoku.cpp

📁 应朋友邀请,写的一个纯C++的五子棋游戏,用到了windows的sdk
💻 CPP
字号:
// Gomoku.cpp: implementation of the Gomoku class.
//
//////////////////////////////////////////////////////////////////////

#include "Gomoku.h"
#include <string.h>
#include <stdio.h>

/*---------------------------------------------------
作者: 姜俊波
日期: 2005-12-19
版本: 1.0
目的: 应朋友邀请,用C++(不使用MFC)写一个windows下的五子棋程序
声明: 所有C++的爱好者均可以自由的使用和更改本软件
联系: csvj@sohu.com
---------------------------------------------------*/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Gomoku::Gomoku()
{
	
}

Gomoku::~Gomoku()
{
	list.RemoveAll();
}

Gomoku::Gomoku(int r, int c)
{
	//
	rc_continue.left  = 2;
	rc_continue.right = 100;
	rc_continue.top   = 2;
	rc_continue.bottom= 25;
	//
	rc_newgame.left  = rc_continue.right;
	rc_newgame.right = 100+rc_continue.right;
	rc_newgame.top   = 2;
	rc_newgame.bottom= 25;
	//
	rc_invite.left  = rc_newgame.right;
	rc_invite.right = 100+rc_newgame.right;
	rc_invite.top   = 2;
	rc_invite.bottom= 25;
	//
	space = 20;
	Xstart = 25;
	Ystart = 30;
	row = r;
	col = c;
	//
	invite = computer;
	cur_player = 0;//black 

	list.space = space;
	for (int i=0; i<r; i++)
	{
		for (int j=0; j<c; j++)
		{
			Play play;
			play.x = i*space+Xstart;
			play.y = j*space+Ystart;
			play.square = Empty;
			list.AddTail(play);
		}
	}

}

void Gomoku::Display(HDC &hdc)
{
	Play *p = NULL;
	for (int i=0; i<list.GetSize(); i++)
	{
		p = list.GetNext(p);
		if (p != NULL)
		{
			char dis[5];
			switch(p->square)
			{
			case Black:
				sprintf(dis,"X");
				break;
			case White:
				sprintf(dis,"O");
				break;
			default:
				sprintf(dis,".");
				break;
			}
			TextOut(hdc,p->x,p->y,dis,strlen(dis));
		}
	}
/*
 	for (i=0; i<row; i++)
 	{
 		char pos[5];
 		sprintf(pos,"%d", i);
 		TextOut(hdc,i*space+Xstart,0,pos,strlen(pos));
 	}
 	for (i=0; i<col; i++)
 	{
 		char pos[5];
 		sprintf(pos,"%d", i);
 		TextOut(hdc,0,i*space+Ystart,pos,strlen(pos));
 	}
*/
	//
	MoveToEx(hdc,rc_continue.left,rc_continue.top,NULL);
	LineTo(hdc,rc_continue.right,rc_continue.top);
	LineTo(hdc,rc_continue.right,rc_continue.bottom);
	LineTo(hdc,rc_continue.left,rc_continue.bottom);
	LineTo(hdc,rc_continue.left,rc_continue.top);
	TextOut(hdc,rc_continue.left+15,rc_continue.top+2,"continue",strlen("continue"));
	//
	MoveToEx(hdc,rc_newgame.left,rc_newgame.top,NULL);
	LineTo(hdc,rc_newgame.right,rc_newgame.top);
	LineTo(hdc,rc_newgame.right,rc_newgame.bottom);
	LineTo(hdc,rc_newgame.left,rc_newgame.bottom);
	LineTo(hdc,rc_newgame.left,rc_newgame.top);
	TextOut(hdc,rc_newgame.left+15,rc_newgame.top+2,"new game",strlen("new game"));
	//
	MoveToEx(hdc,rc_invite.left,rc_invite.top,NULL);
	LineTo(hdc,rc_invite.right,rc_invite.top);
	LineTo(hdc,rc_invite.right,rc_invite.bottom);
	LineTo(hdc,rc_invite.left,rc_invite.bottom);
	LineTo(hdc,rc_invite.left,rc_invite.top);
	if (invite == computer)
	{
		TextOut(hdc,rc_invite.left+15,rc_invite.top+2,"computer",strlen("computer"));
	}
	else
	{
		TextOut(hdc,rc_invite.left+15,rc_invite.top+2,"persion",strlen("persion"));
	}
	
}

bool Gomoku::Input(POINT point)
{
	Play *p = NULL;
	for (int i=0; i<list.GetSize(); i++)
	{
		p = list.GetNext(p);
		if (IsInRect(p->x,p->y,space,space,point) && (p->square == Empty))
		{
			if (cur_player == 0)	{
				p->square  = Black;
				cur_player = !cur_player;
				if (invite == computer)//黑子下完后由计算机下子
				{
					ComputerPlay(point);
				}
			}
			else	{
				p->square = White;
				cur_player = !cur_player;
			}
			return true;
		}
	}
	//菜单项
	//是否点击了某个菜单
	if (IsInRect(rc_continue.left,rc_continue.top,rc_continue.right-rc_continue.left,rc_continue.bottom-rc_continue.top,point))
	{
		Continue();
	}
	else if (IsInRect(rc_newgame.left,rc_newgame.top,rc_newgame.right-rc_newgame.left,rc_newgame.bottom-rc_newgame.top,point))
	{
		NewGame();
	}
	else if (IsInRect(rc_invite.left,rc_invite.top,rc_invite.right-rc_invite.left,rc_invite.bottom-rc_invite.top,point))
	{
		Invite();
	}
	return true;
}

BOOL Gomoku::IsInRect(int baseX, int baseY, int width, int high, POINT point)
{
	if ((point.x>=baseX) && (point.x<=(baseX+width)) && (point.y>=baseY) && (point.y<=baseY+high))
	{
		return TRUE;
	}
	return FALSE;
}

void Gomoku::Continue()
{
	list.RemoveAll();
	ReadFromFile();
}

void Gomoku::NewGame()
{
	Play *p = NULL;
	for (int i=0; i<list.GetSize(); i++)
	{
		p = list.GetNext(p);
		if (p != NULL)
		{
			p->square = Empty;
		}
	}
}

void Gomoku::Invite()
{
	if (invite == computer)
		invite = persion;
	else
		invite = computer;
	NewGame();
}

Square Gomoku::IsSuccess(POINT point)
{
	Play *p = list.Find(point);
	if (p == NULL)
	{
		return Empty;
	}
	//检查在八个方向上是否有连成五个的棋子,如有,则获胜
	if ((MaxChessmanNum(point,p->square,left2right) + MaxChessmanNum(point,p->square,right2left))>= 6)	{
		return p->square;
	}
	if ((MaxChessmanNum(point,p->square,up2down) + MaxChessmanNum(point,p->square,down2up))>= 6)	{
		return p->square;
	}
	if ((MaxChessmanNum(point,p->square,ldown2rup) + MaxChessmanNum(point,p->square,rup2ldown)) >= 6)	{
		return p->square;
	}
	if ((MaxChessmanNum(point,p->square,rdown2lup) + MaxChessmanNum(point,p->square,lup2rdown))>= 6)	{
		return p->square;
	}
	return Empty;
}

int Gomoku::MaxChessmanNum(POINT point, Square baseq, int dir)
{
	int res = 1;
	Play *ply;
	POINT nextp = point;

	nextp = GetNextPoint(point,dir);
	while ((ply=list.Find(nextp)) != NULL)
	{
		if (ply->square != baseq)
		{
			break;
		}
		nextp = GetNextPoint(nextp,dir);
		res ++;
	}

	return res;
}

POINT Gomoku::GetNextPoint(POINT base, int dir)
{
	POINT point = base;
	switch(dir)
	{
	case left2right:
		point.x += space;
		break;
	case right2left:
		point.x -= space;
		break;
	case up2down:
		point.y += space;
		break;
	case down2up:
		point.y -= space;
		break;
	case ldown2rup:
		point.x += space;
		point.y -= space;
		break;
	case rup2ldown:
		point.x -= space;
		point.y += space;
		break;
	case rdown2lup:
		point.x -= space;
		point.y -= space;
		break;
	case lup2rdown:
		point.x += space;
		point.y += space;
		break;
	}
	return point;
}

//该算法非常简单,可以替换的剪枝算法,深度遍历的算法
//只判断对方落子后在八个方向上,哪个方向连成的棋子最多,就去截住它
void Gomoku::ComputerPlay(POINT point)
{
	Play *p = list.Find(point);
	if (p == NULL)
	{
		return;
	}
	int max[4], num = 0;
	for (int i=0; i<8; i+=2)
	{
		max[num++] = MaxChessmanNum(point,p->square,i) + MaxChessmanNum(point,p->square,i+1) - 1;
	}
	int maxmax=max[0];
	num = 0;
	for (i=1; i<4; i++)
	{
		if (maxmax < max[i])
		{
			maxmax = max[i];
			num = i;
		}
	}
	
	int direction = num*2;
	int m1 = MaxChessmanNum(point,p->square,direction);
	int m2 = MaxChessmanNum(point,p->square,direction+1);
	POINT pt = point;
	for (i=0; i<m1; i++)
	{
		pt = GetNextPoint(pt,direction);
	}
	if ((p=list.Find(pt)) != NULL)
	{
		if (p->square == Empty)
		{
			Input(pt);
			return;
		}
	}
	pt = point;
	for (i=0; i<m2; i++)
	{
		pt = GetNextPoint(pt,direction+1);
	}
	if ((p=list.Find(pt)) != NULL)
	{
		if (p->square == Empty)
		{
			Input(pt);
			return;
		}
	}
	//
	p = NULL;
	while ((p=list.GetNext(p)) != NULL)
	{
		if (p->square == Empty)
		{
			pt.x = p->x;
			pt.y = p->y;
			Input(pt);
			return;
		}
	}
}
//C中的标准函数
void Gomoku::SaveToFile()
{
	FILE *pFile;
	char *sPath = "save.gu";
	pFile = fopen(sPath,"w");
	if(pFile == NULL)
		return;

	fprintf(pFile,"%d\n",row);
	fprintf(pFile,"%d\n",col);
	fprintf(pFile,"%d\n",invite);
	fprintf(pFile,"%d\n",cur_player);
	//
	fprintf(pFile,"%d\n",list.space);
	Play *py = NULL;
	for (int i=0; i<list.GetSize(); i++)
	{
		if ((py=list.GetNext(py)) == NULL)
			break;
		fprintf(pFile,"%d\n",py->x);
		fprintf(pFile,"%d\n",py->y);
		fprintf(pFile,"%d\n",py->square);
	}
}

void Gomoku::ReadFromFile()
{
	FILE *pFile;
	char *sPath = "save.gu";
	pFile = fopen(sPath,"r");

	fscanf(pFile, "%d", &row);
	fscanf(pFile, "%d", &col);
	fscanf(pFile, "%d", &invite);
	fscanf(pFile, "%d", &cur_player);
	fscanf(pFile, "%d", &list.space);

	for (int i=0; i<row; i++)
	{
		for (int j=0; j<col; j++)
		{
			Play play;
			fscanf(pFile, "%d", &play.x);
			fscanf(pFile, "%d", &play.y);
			fscanf(pFile, "%d", &play.square);
			list.AddTail(play);
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -