C++编写面向对象的五子棋(windowsAPI32位窗口编程,非控制台)(提供百度云源代码)


五个文件:
myPoint.h--------------------------存放棋子的坐标
GoBang.h--------------------------棋子类的头文件
GoBang.cpp-----------------------棋子类的实现文件
Game.h-----------------------------游戏类的头文件
Game.cpp--------------------------游戏类的实现文件
五子棋面向对象版本.cpp--------windows文件

不说废话,直接上代码,代码里面有不少注释

myPoint.h

#pragma once
//位置
struct myPoint
{
	int x;
	int y;
	myPoint()
	{
		x = 0;
		y = 0;
	}
	//复制构造函数
	myPoint(const myPoint& thePoint)
	{
		x = thePoint.x;
		y = thePoint.y;
	}
	myPoint(int theX, int theY)
	{
		x = theX;
		y = theY;
	}
	//赋值构造函数
	myPoint& operator = (const myPoint& thePoint)
	{
		x = thePoint.x;
		y = thePoint.y;
		return *this;
	}

	myPoint& operator += (const myPoint& thePoint)
	{
		x += thePoint.x;
		y += thePoint.y;
		return *this;
	}
	myPoint& operator -= (const myPoint& thePoint)
	{
		x -= thePoint.x;
		y -= thePoint.y;
		return *this;
	}

	myPoint operator + (const myPoint& thePoint)
	{
		return myPoint(this->x + thePoint.x, this->y + thePoint.y);
	}

	myPoint operator - (const myPoint& thePoint)
	{
		return myPoint(this->x - thePoint.x, this->y - thePoint.y);
	}

	myPoint operator * (const int & num)
	{
		return myPoint(this->x*num, this->y*num);
	}

	//只要有一个小于就true
	bool operator <(const myPoint & thePoint)
	{
		if (x < thePoint.x || y < thePoint.y)
			return true;
		return false;
	}
	//只要有一个大于就true
	bool operator >(const myPoint & thePoint)
	{
		if (x > thePoint.x || y > thePoint.y)
			return true;
		return false;
	}
	//两个都大于就true
	bool operator >=(const myPoint & thePoint)
	{
		if (x >= thePoint.x &&y >= thePoint.y)
			return true;
		return false;
	}
	//两个都小于就true
	bool operator <=(const myPoint & thePoint)
	{
		if (x <= thePoint.x && y <= thePoint.y)
			return true;
		return false;
	}

};

GoBang.h

#pragma once
#include<Windows.h>
#include<iostream>
#include"myPoint.h"
#include<vector>
#include<mmsystem.h>
using namespace std;
#pragma comment(lib,"Msimg32.lib")
#pragma comment(lib,"Winmm.lib")

const int comWinFive = 15;//00000
const int playWinFive = 15;
const int comWinFor = 14;//-0000-
const int playWinFor = 14;
const int comGoldenThreeOne = 13;//两个方向连三
const int playGoldenThreeOne = 13;
const int normalFourOne = 12;//“|0000-”、“-00-00-”
const int goodThree = 11;//"-000--"、“--000-”、“-0-00-”
const int sleepThree = 10;//眠三,形如:“@000--”
const int goodTwo = 8;//活二,形如:“--00--”、“-0-0-”、“-0--0-”
const int sleepTwo = 6;//眠二,分“@00---”、“@0-0--”、“@0--0--”、“-0---0-”
const int centerPoint = 13;

//记录一个棋子某方向的连续棋子数以及左、右(上下、斜向)的空格数目
struct SolidStr
{
	int leftSpaceNum=0;
	int rightSpaceNum=0;
	int StringNum=0;
};

//棋子的x、y位置(15*15)以及状态
struct chess
{
	int x, y;
	int state = 0;//0空1黑2白
};

struct currentPos
{
	static const bool Exist = true;
	static const bool notExist = false;
	bool isExist = notExist;
	int x=0;
	int y=0;

	currentPos& operator =(const myPoint& thePoint)
	{
		x = thePoint.x;
		y = thePoint.y;
		return *this;
	}
};

class GoBang
{
public:
	GoBang();
	GoBang(HINSTANCE theHinstance,HWND theHwnd);
	~GoBang();
	currentPos myCurrentPos;
	//绘制
	void drawBk();//画背景
	void drawChess();//画棋子
	void drawWorld();//画世界
	int getWorldState(myPoint thePoint);//返回某坐标的状态(空、黑、白)
	void setWorldState(myPoint thePoint, int theState);//设置某坐标的状态
	void ifWin();//赢了,提醒
	void comPlay(myPoint & thePos);//电脑下子
	bool checkWin(myPoint thePos);//检测某位置是否获胜
	int getPriority(myPoint thePos, int thestatus);//某位置棋子的最高优先级
	int getStringNum(myPoint thePos, int thestate, myPoint thestep);//得到某位置某方向的连续棋子数
	bool isFourOne(myPoint thePos, int thestate, myPoint thestep);//检测某方向是否是连着的五个子为4+1(棋子、空格)

	bool isWinFive(myPoint thePos);//该位置是否有某方向连五子

	SolidStr getSolidStrStatus(myPoint thePos, myPoint theStep);//检测一定数目的连子数目,并且两边要有空格,spaceNum为单一边的空格数目
	bool isThreeOne(myPoint thePos, myPoint theStep);//three:三个棋子  one 一个空格,要求,两端是空格,不被挡住

	bool isThreeOne_forGoodThree(myPoint thePos, myPoint theStep);//是否存在“-0-00-”

	bool isThreeOne_forSleepThree(myPoint thePos, myPoint theStep);//眠三的“@00-0-”
	bool isTwoOne(myPoint thePos, myPoint theStep);//判断“-0-0-”
	bool isTwoTwo(myPoint thePos, myPoint theStep);//判断“-0--0-”
	bool isTwoOneAnother(myPoint thePos, myPoint theStep);//眠二的“@0-0--”
	bool isTwoTwoAnother(myPoint thePos, myPoint theStep);//眠二的“@0--0-”
	bool isTwoThree(myPoint thePos, myPoint theStep);//眠二的“0---0”
	int getPieceNum()const{ return takePieceNum; }//得到棋盘上的棋子数目
	void addPieceNum(){ ++takePieceNum; }//棋子数目+1
	void removePieceNum(){ --takePieceNum; }//棋子数目-1
	void initialPieceNum(){ takePieceNum = 0; }//棋子数目归0
	void setCurrentPos(myPoint thePoint);//当前落子的位置
	void InitialCurrentPos();//初始化当前落子位置为无

private:
	chess world[15][15];
	myPoint comChessPos=myPoint(7,7);//电脑落子位置
	bool win = false;//输赢
	int comScore[15][15];//电脑的位置得分
	int playerScore[15][15];//玩家的位置得分
	HDC hdc;//主dc
	HDC memDC;//内存dc
	HDC srcDC;//内存dc
	HWND myhwnd = NULL;
	HBITMAP memBitmap = NULL;
	HBITMAP hbkBmp = NULL;
	BITMAP bm ;
	HINSTANCE myhInst;
	int comPriority[15][15];
	int playPriority[15][15];
	int takePieceNum = 0;
	HPEN hPen=NULL;
public:
	myPoint horizontal = myPoint(1, 0);
	myPoint vertical = myPoint(0, 1);
	myPoint lowleft = myPoint(-1, 1);
	myPoint lowright = myPoint(1, 1);
};

GoBang.cpp

#include "stdafx.h"
#include "GoBang.h"

GoBang::GoBang(HINSTANCE theHinstance, HWND theHwnd)
{
	myhwnd = theHwnd;
	myhInst = theHinstance;
	hdc = GetDC(myhwnd);
	memDC = CreateCompatibleDC(hdc);
	memBitmap = CreateCompatibleBitmap(hdc, 1266, 768);
	SelectObject(memDC, memBitmap);
	hbkBmp = (HBITMAP)LoadImage(myhInst, _T("qipan.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	GetObject(hbkBmp, sizeof(BITMAP), &bm);
	srcDC = CreateCompatibleDC(hdc);
	SelectObject(srcDC, hbkBmp);

	hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
	SelectObject(memDC, hPen);
	ReleaseDC(myhwnd, hdc);
	for (int i = 0; i < 14; ++i)
	{
		for (int j = 0; j < 14; ++j)
		{
			world[i][j].state = 0;
		}
	}
}

GoBang::~GoBang()
{
	if (memDC)
	{
		DeleteObject(memDC);
	}
	if (srcDC)
	{
		DeleteObject(srcDC);
	}
	if (hbkBmp)
	{
		DeleteObject(hbkBmp);
	}
	if (memBitmap)
	{
		DeleteObject(memBitmap);
	}
	if (hPen)
	{
		DeleteObject(hPen);
	}
	
}

void GoBang::drawBk()
{
	//将图像限制为500*500
	TransparentBlt(memDC, 0, 0, 500, 500, srcDC, 0, 0, bm.bmWidth, bm.bmHeight, RGB(255, 255, 255));
}

void GoBang::drawWorld()
{
	hdc = GetDC(myhwnd);
	BitBlt(hdc, 0, 0, 500, 500, memDC, 0, 0, SRCCOPY);
	ReleaseDC(myhwnd, hdc);
}

void GoBang::drawChess()
{
	for (int i = 0; i < 15; i++)
	for (int j = 0; j < 15; j++)
	{
		HBRUSH hBr;
		if (world[i][j].state != 0)
		{
			if (world[i][j].state == 1)
				hBr = CreateSolidBrush(RGB(0, 0, 0));
			if (world[i][j].state == 2)
				hBr = CreateSolidBrush(RGB(255, 255, 255));
			SelectObject(memDC, hBr);
			//left		10 + i * 32
			//top		10 + j * 32
			//right		41 + i * 32
			//buttom	41+j * 32
			//在绘制图像时,限制像素大小为500,500/16=31.25,这张图的边距与格点的距离相似,又因大小被缩放,最终看起来没误差
			//14*x+2*y=500,先将y算作x,得到近似值31.25,后又经过几番尝试,确定x为32,y为26,32*14+26*2=500;棋子宽度设为31
			Ellipse(memDC, 10 + i * 32, 10 + j * 32, 41 + i * 32, 41+j * 32 );//32指一个格子的像素跨度,(41-10)是边长
			DeleteObject(hBr);
			ReleaseDC(myhwnd, memDC);
		}
	}
	if (myCurrentPos.isExist == currentPos::Exist)
	{
		/*HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));*/
		//left			10 + myCurrentPos.x * 32
		//top			10 + myCurrentPos.y * 32
		///right		myCurrentPos.x * 32 + 41
		//button		myCurrentPos.y * 32 + 41
		//point:左上角 10+myCurrentPos.x*32			10+myCurrentPos.y*32
		//右上角		myCurrentPos.x*32+41			 10+myCurrentPos.y*32
		//左下角		10 + myCurrentPos.x * 32		myCurrentPos.y * 32 + 41
		//右下角		myCurrentPos.x * 32 + 41		myCurrentPos.y * 32 + 41	
		//SelectObject(memDC, hPen);
		myPoint top_left_corner(10 + myCurrentPos.x * 32, 10 + myCurrentPos.y * 32);
		myPoint upper_right_corner(myCurrentPos.x * 32 + 41, 10 + myCurrentPos.y * 32);
		myPoint lower_left_corner(10 + myCurrentPos.x * 32, myCurrentPos.y * 32 + 41);
		myPoint lower_right_corner(myCurrentPos.x * 32 + 41, myCurrentPos.y * 32 + 41);
		MoveToEx(memDC, top_left_corner.x, top_left_corner.y, NULL);
		LineTo(memDC, upper_right_corner.x, upper_right_corner.y);	//左上角划线到右上角
		LineTo(memDC, lower_right_corner.x, lower_right_corner.y);//右上角划线到右下角
		LineTo(memDC, lower_left_corner.x, lower_left_corner.y);//右下角划线到左下角
		LineTo(memDC, top_left_corner.x, top_left_corner.y);//左下角划线到左上角
	}

}

void GoBang::setCurrentPos(myPoint thePoint)
{
	myCurrentPos = thePoint;
	myCurrentPos.isExist = currentPos::Exist;
}

void GoBang::InitialCurrentPos()
{
	myCurrentPos.isExist = currentPos::notExist;
}

int GoBang::getStringNum(myPoint  thePos, int thestate, myPoint thestep)
{
	int stringNum = 0;
	myPoint startPos(0, 0);
	myPoint movePos(thePos);
	//状态相同,就移动,直到状态不同
	//越界,肯定与当前状态不同
	while (getWorldState(movePos) == thestate)
	{
		movePos -= thestep;
	} //离开这个while循环,就说明,状态不同了
	//起始位置确定
	startPos = movePos + thestep;
	while (getWorldState(startPos) == thestate)
	{
		++stringNum;
		startPos += thestep;
	}
	return stringNum;
}

bool GoBang::checkWin(myPoint  thePos)
{
	int theState = getWorldState(thePos);
	int highest = 1;//最大连子数目
	int stringNum = 1;//某方向上的连子数目
	//横-------------------------------------------------------------
	stringNum = getStringNum(thePos, theState, horizontal);
	if (stringNum > highest)
		highest = stringNum;
	//竖|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
	stringNum = getStringNum(thePos, theState, vertical);
	if (stringNum > highest)
		highest = stringNum;
	//撇/
	stringNum = getStringNum(thePos, theState, lowleft);
	if (stringNum > highest)
		highest = stringNum;
	//捺
	stringNum = getStringNum(thePos, theState, lowright);
	if (stringNum > highest)
		highest = stringNum;

	if (highest >= 5)
		return true;
	return false;
}

int GoBang::getWorldState(myPoint thePoint)
{
	if (thePoint<myPoint(0, 0) || thePoint>myPoint(14,14))
		return -1;//越界,返回-1		
	return world[thePoint.x][thePoint.y].state;
}

void GoBang::setWorldState(myPoint thePoint, int theState)
{
	world[thePoint.x][thePoint.y].state = theState;
}

void GoBang::comPlay(myPoint & thePos)
{
	for (int i = 0; i < 15;++i)
	for (int j = 0; j < 15; ++j)
	{
		comPriority[i][j] = 0;
		playPriority[i][j] = 0;
	}
	for (int i = 0; i < 15; ++i)
	for (int j = 0; j < 15; ++j)
	{
		if (getWorldState(myPoint(i,j))==0)
		{
			comPriority[i][j] = getPriority(myPoint(i, j), 2);
			playPriority[i][j] = getPriority(myPoint(i, j), 1);
		}
	}
	int comNiceValue = 0;
	int plyaNiceValue = 0;
	for (int i = 0; i < 15; ++i)
	for (int j = 0; j < 15; ++j)
	{
		if (comPriority[i][j]>comNiceValue)
			comNiceValue = comPriority[i][j];
		if (playPriority[i][j]>plyaNiceValue)
			plyaNiceValue = playPriority[i][j];
	}

	if (comNiceValue == 0)
	{
		setWorldState(myPoint(7,7), 2);
		return;
	}

	myPoint bestPos(0, 0);
	int enmyValue = 0;
	if (comNiceValue >= plyaNiceValue)
	{
		for (int i = 0; i < 15; ++i)
		for (int j = 0; j < 15; ++j)
		{
			if (comPriority[i][j] == comNiceValue)
			{
				if (playPriority[i][j]>enmyValue)
				{
					enmyValue = playPriority[i][j];
					bestPos.x = i;
					bestPos.y = j;
				}
			}
		}
	}
	else
	{
		for (int i = 0; i < 15; ++i)
		for (int j = 0; j < 15; ++j)
		{
			if (playPriority[i][j] == plyaNiceValue)
			{
				if (comPriority[i][j]>enmyValue)
				{
					enmyValue = comPriority[i][j];
					bestPos.x = i;
					bestPos.y = j;
				}
			}
		}
	}
	thePos.x = bestPos.x;
	thePos.y = bestPos.y;
	setWorldState(bestPos, 2);
	if (takePieceNum<225)
		addPieceNum();
}

bool GoBang::isWinFive(myPoint thePos)
{
	if (checkWin(thePos))
		return true;
	return false;
}

//检测"-00--",周围有空格;如果对“00-000-”,最多检测到一个空格
SolidStr GoBang::getSolidStrStatus(myPoint thePos, myPoint theStep)
{
	int spaceNumLeft = 0;//左边的空格数目
	int spaceNumRight = 0;//右边的空格数目

	int stringNum = 0;
	int theState = getWorldState(thePos);
	myPoint startPos(0, 0);
	myPoint movePos(thePos);
	//状态相同,就移动,直到状态不同
	//越界,肯定与当前状态不同
	while (getWorldState(movePos) == theState)
	{
		movePos -= theStep;
	} //离开这个while循环,就说明,状态不同了
	//起始位置确定
	startPos= movePos ;
	while (getWorldState(startPos) == 0)
	{
		++spaceNumLeft;
		startPos -= theStep;
	}
	movePos = thePos;
	while (getWorldState(movePos) == theState)
	{
		//此刻不能计数stringNum
		movePos += theStep;
	}
	startPos = movePos;
	while (getWorldState(startPos) == 0)
	{
		++spaceNumRight;
		startPos += theStep;
	}
	startPos = movePos - theStep;
	while (getWorldState(startPos) == theState)
	{
		++stringNum;//现在才能计数
		startPos -= theStep;
	}
	SolidStr mySolidStr;
	mySolidStr.leftSpaceNum = spaceNumLeft;
	mySolidStr.rightSpaceNum = spaceNumRight;
	mySolidStr.StringNum = stringNum;
	return mySolidStr;
}

bool GoBang::isThreeOne(myPoint thePos, myPoint theStep)
{

	//确定非空再做操作
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos(thePos - (theStep * 3)), movePos;

	//可以越界,不做越界检测
	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0,limit=4;
	while ((startPos.x <= thePos.x&&theStep.x>0) || (startPos.y <= thePos.y&&theStep.y>0))
	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += theStep;
		}
		if (spaceNum == 1 && strNum == 3)//活三的本质是连起来的三个棋子和一个空格
		{
			if (getWorldState(movePos)==0)//该位置为空,“-000”,存在“-000--”,两边空格数目有3个就行
			{
				int outsideSpaceNum = 0;
				//移到非空的位置上
				movePos = startPos+theStep*1;
				if (getWorldState(movePos - theStep) == 0)
				{
					++outsideSpaceNum;
					//检测到为空格,才能继续探索
					if (getWorldState(movePos - theStep*2) == 0)
					{
						++outsideSpaceNum;
					}
				}
				movePos = startPos + theStep * 3;
				if (getWorldState(movePos + theStep) == 0)
				{
					++outsideSpaceNum;
					if (getWorldState(movePos+ theStep * 2) == 0)
					{
						++outsideSpaceNum;
					}
				}
				if (outsideSpaceNum >= 3)
					return true;//满足情况,返回true
			}
			else//该位置不为空,“死位置000--”或者“0-00”等,看两边是否各有一个空
			{
				movePos = startPos;
				int outsideSpaceNum = 0;
				if (getWorldState(movePos - theStep) == 0)
					++outsideSpaceNum;
				movePos = startPos + theStep * 3;
				if (getWorldState(movePos+theStep)==0)
					++outsideSpaceNum;
				if (outsideSpaceNum == 2)
					return true;
			}
		}
		startPos += theStep;
	}
	return false;
}

//是否存在“-0-00-”
bool GoBang::isThreeOne_forGoodThree(myPoint thePos, myPoint theStep)
{
	//确定非空再做操作
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos(thePos - (theStep * 3)), movePos;
	//可以越界,不做越界检测
	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0, limit = 4;
	while ((startPos.x <= thePos.x&&theStep.x>0) || (startPos.y <= thePos.y&&theStep.y>0))
	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += theStep;
		}
		if (spaceNum == 1 && strNum == 3)//“-0-00-”
		{
			movePos = startPos;
			int outsideSpaceNum = 0;
			if (getWorldState(movePos - theStep) == 0)
				++outsideSpaceNum;
			movePos = startPos + theStep * 3;
			if (getWorldState(movePos + theStep) == 0)
				++outsideSpaceNum;
			if (outsideSpaceNum == 2)
					return true;
		}
		startPos += theStep;
	}
	return false;
}

//检测是否是连着的五个子为4+1(棋子、空格)
bool GoBang::isFourOne(myPoint thePos, int thestate, myPoint thestep)
{
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos, movePos;
	startPos = thePos - (thestep * 4);

	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0;		//遍历假想的情况
	int limit = 5;				//限制iteratorNum的遍历次数
	while ((startPos.x <= thePos.x&&thestep.x>0) || (startPos.y <= thePos.y&&thestep.y>0))	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += thestep;
		}
		if (spaceNum == 1 && strNum == 4)
			return true;     //连着四个的情况属于神四,没有检测到说明没有
		startPos += thestep;
	}

	return false;
}

//眠三的“@00-0-”
bool GoBang::isThreeOne_forSleepThree(myPoint thePos, myPoint theStep)
{
	//确定非空再做操作
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos(thePos - (theStep * 3)), movePos;
	//可以越界,不做越界检测
	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0, limit = 4;
	while ((startPos.x <= thePos.x&&theStep.x>0) || (startPos.y <= thePos.y&&theStep.y>0))
	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += theStep;
		}
		if (spaceNum == 1 && strNum == 3)//“@00-0-”
		{
			movePos = startPos;
			int outsideSpaceNum = 0;
			//如果空格为相同状态的棋子,也算上
			if (getWorldState(movePos - theStep) == 0 || getWorldState(movePos - theStep) == theState)
				return true;
			movePos = startPos + theStep * 3;
			if (getWorldState(movePos + theStep) == 0 || getWorldState(movePos - theStep) == theState)
				return true;
		}
		startPos += theStep;
	}
	return false;
}

//判断“-0-0-”
bool GoBang::isTwoOne(myPoint thePos, myPoint theStep)
{
	//确定非空再做操作
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos(thePos - (theStep * 2)), movePos;
	//可以越界,不做越界检测
	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0, limit = 3;
	while ((startPos.x <= thePos.x&&theStep.x>0) || (startPos.y <= thePos.y&&theStep.y>0))
	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += theStep;
		}
		if (spaceNum == 1 && strNum == 2)
		{
			movePos = startPos;
			int outsideSpaceNum = 0;
			if (getWorldState(movePos - theStep) == 0)
				++outsideSpaceNum;
			movePos = startPos + theStep * 2;
			if (getWorldState(movePos + theStep) == 0)
				++outsideSpaceNum;
			if (outsideSpaceNum == 2)
				return true;
		}
		startPos += theStep;
	}
	return false;
}

//判断“-0--0-”
bool GoBang::isTwoTwo(myPoint thePos, myPoint theStep)
{
	//确定非空再做操作
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos(thePos - (theStep * 3)), movePos;
	//可以越界,不做越界检测
	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0, limit = 4;
	while ((startPos.x <= thePos.x&&theStep.x>0) || (startPos.y <= thePos.y&&theStep.y>0))
	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += theStep;
		}
		if (spaceNum == 2 && strNum == 2)
		{
			movePos = startPos;
			int outsideSpaceNum = 0;
			if (getWorldState(movePos - theStep) == 0)
				++outsideSpaceNum;
			movePos = startPos + theStep * 3;
			if (getWorldState(movePos + theStep) == 0)
				++outsideSpaceNum;
			if (outsideSpaceNum == 2)
				return true;
		}
		startPos += theStep;
	}
	return false;
}


bool GoBang::isTwoOneAnother(myPoint thePos, myPoint theStep)
{
	//确定非空再做操作
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos(thePos - (theStep * 2)), movePos;
	//可以越界,不做越界检测
	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0, limit = 3;
	while ((startPos.x <= thePos.x&&theStep.x>0) || (startPos.y <= thePos.y&&theStep.y>0))
	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += theStep;
		}
		if (spaceNum == 1 && strNum == 2)
		{
			movePos = startPos;
			if (getWorldState(movePos - theStep) == 0 &&
				getWorldState(movePos - theStep * 2) == 0)
				return true;
			movePos = startPos + theStep * 2;
			if (getWorldState(movePos + theStep) == 0 &&
				getWorldState(movePos + theStep * 2) == 0)
				return true;
		}
		startPos += theStep;
	}
	return false;
}

//眠二的“@0--0-”
bool GoBang::isTwoTwoAnother(myPoint thePos, myPoint theStep)
{
	//确定非空再做操作
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos(thePos - (theStep * 3)), movePos;
	//可以越界,不做越界检测
	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0, limit = 4;
	while ((startPos.x <= thePos.x&&theStep.x>0) || (startPos.y <= thePos.y&&theStep.y>0))
	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += theStep;
		}
		if (spaceNum == 2 && strNum == 2)
		{
			movePos = startPos;
			if (getWorldState(movePos - theStep) == 0)
				return true;
			movePos = startPos + theStep * 3;
			if (getWorldState(movePos + theStep) == 0)
				return true;
		}
		startPos += theStep;
	}
	return false;
}

//眠二的“0---0”
bool  GoBang::isTwoThree(myPoint thePos, myPoint theStep)
{
	//确定非空再做操作
	int theState = getWorldState(thePos);
	if (theState == 0)
		return false;
	myPoint startPos(thePos - (theStep * 4)), movePos;
	//可以越界,不做越界检测
	int spaceNum = 0, strNum = 0;
	int iteratorNum = 0, limit = 5;
	while ((startPos.x <= thePos.x&&theStep.x>0) || (startPos.y <= thePos.y&&theStep.y>0))
	{
		spaceNum = 0;
		strNum = 0;
		iteratorNum = 0;
		movePos = startPos;
		while (iteratorNum < limit)
		{
			if (getWorldState(movePos) == 0)
				++spaceNum;
			if (getWorldState(movePos) == theState)
				++strNum;
			++iteratorNum;
			movePos += theStep;
		}
		if (spaceNum == 3 && strNum == 2)
				return true;
		startPos += theStep;
	}
	return false;
}

int GoBang::getPriority(myPoint thePos, int thestatus)
{

	setWorldState(thePos, thestatus);
	//连5
	if (isWinFive(thePos))
	{
		setWorldState(thePos, 0);
		return comWinFive;
	}

	//四个方向上的最大直接连子数目与其状态
	SolidStr solidHorozontal;
	SolidStr solidVertical;
	SolidStr solidLowleft;
	SolidStr solidLowlowright;
	solidHorozontal = getSolidStrStatus(thePos, horizontal);
	solidVertical = getSolidStrStatus(thePos, vertical);
	solidLowleft = getSolidStrStatus(thePos, lowleft);
	solidLowlowright = getSolidStrStatus(thePos, lowright);
	//活四,四个连在一起
	if (solidHorozontal.leftSpaceNum >= 1 && solidHorozontal.rightSpaceNum >= 1 && solidHorozontal.StringNum>=4 || 
		solidVertical.leftSpaceNum >= 1 && solidVertical.rightSpaceNum >= 1 && solidVertical.StringNum>=4 ||
		solidLowleft.leftSpaceNum >= 1 && solidLowleft.rightSpaceNum >= 1 && solidLowleft.StringNum>=4 ||
		solidLowlowright.leftSpaceNum >= 1 && solidLowlowright.rightSpaceNum >= 1 && solidLowlowright.StringNum>=4)
	{
		setWorldState(thePos, 0);
		return comWinFor;
	}

	//神三:调用isThreeOne查看满足条件的情况(横竖撇捺),有大于等于两个就是神三
	int threeOneNum = 0;
	if (isThreeOne(thePos, horizontal))
		++threeOneNum;
	if (isThreeOne(thePos, vertical))
		++threeOneNum;

	if (isThreeOne(thePos, lowleft))
		++threeOneNum;
	if (isThreeOne(thePos, lowright))
		++threeOneNum;
	if (threeOneNum >= 2)
	{
		setWorldState(thePos, 0);
		return comGoldenThreeOne;
	}
	//冲四,类似“00-00”,中间有空格
	if (isFourOne(thePos, thestatus, horizontal) || isFourOne(thePos, thestatus, vertical)
		|| isFourOne(thePos, thestatus, lowleft) || isFourOne(thePos, thestatus, lowright)
		)
	{
		setWorldState(thePos, 0);
		return normalFourOne;
	}	
	//冲四的另外一种情况,如“死位置0000-”,一端有一个死位置挡着,还有一端是空格
	if (((solidHorozontal.leftSpaceNum >= 1 || solidHorozontal.rightSpaceNum >= 1) &&solidHorozontal.StringNum >= 4) ||
		((solidVertical.leftSpaceNum >= 1||solidVertical.rightSpaceNum >= 1) && solidVertical.StringNum >= 4 )||
		((solidLowleft.leftSpaceNum >= 1||solidLowleft.rightSpaceNum >= 1)&&solidLowleft.StringNum >= 4) ||
		((solidLowlowright.leftSpaceNum >= 1||solidLowlowright.rightSpaceNum >= 1)&&solidLowlowright.StringNum >= 4))
	{
		setWorldState(thePos, 0);
		return normalFourOne;
	}
	//活三“--000-”,两边空格数加起来有三个以上,或者“-0-00-”
	//活三的“--000-”,必须是三个连着一起
	if (
		(((solidHorozontal.leftSpaceNum >= 2 && solidHorozontal.rightSpaceNum >= 1) || (solidHorozontal.leftSpaceNum >= 1 && solidHorozontal.rightSpaceNum >= 2))
		&& (solidHorozontal.StringNum==3))				||
		(((solidVertical.leftSpaceNum >= 2 && solidVertical.rightSpaceNum >= 1) || (solidVertical.leftSpaceNum>=1&&solidVertical.rightSpaceNum>=2))
		&& (solidVertical.StringNum==3))				||
		(((solidLowleft.leftSpaceNum >= 2 && solidLowleft.rightSpaceNum >= 1) || (solidLowleft.leftSpaceNum>=1&&solidLowleft.rightSpaceNum>=2))
		&& (solidLowleft.StringNum==3))					||
		(((solidLowlowright.leftSpaceNum >= 2 && solidLowlowright.rightSpaceNum >= 1) || (solidLowlowright.leftSpaceNum >= 1 && solidLowlowright.rightSpaceNum>=2))
		&& (solidLowlowright.StringNum==3))
		)
	{
		setWorldState(thePos, 0);
		return goodThree;//活三“--000-”
	}
	//活三的另外一种情况“-0-00-”,这里直接调用函数isThreeOne的修改版isThreeOne_forGoodThree,它检测一个方向上是否满足条件“-0-00-”
	if (
		isThreeOne_forGoodThree(thePos, horizontal) || isThreeOne_forGoodThree(thePos, vertical) ||
		isThreeOne_forGoodThree(thePos, lowleft) || isThreeOne_forGoodThree(thePos, lowright)
		)
	{
		setWorldState(thePos, 0);
		return goodThree;
	}
	//眠三,形如:“@000--”、“@00-0-”
	//眠三的“@000--”;
	if (//只要有一边的空格数目大于等于2,就符合条件
		((solidHorozontal.leftSpaceNum >= 2 ||solidHorozontal.rightSpaceNum >= 2)&& (solidHorozontal.StringNum == 3))       ||
		((solidVertical.leftSpaceNum >= 2|| solidVertical.rightSpaceNum >= 2)&& (solidVertical.StringNum == 3))             ||
		((solidLowleft.leftSpaceNum >= 2  || solidLowleft.rightSpaceNum >= 2)&& (solidLowleft.StringNum == 3))              ||
		((solidLowlowright.leftSpaceNum >= 2||solidLowlowright.rightSpaceNum >= 2)&& (solidLowlowright.StringNum == 3))
		)
	{
		setWorldState(thePos, 0);
		return sleepThree;
	}
	//眠三的“@00-0-”,调用isThreeOne_forSleepThree
	if (
		isThreeOne_forSleepThree(thePos, horizontal) || isThreeOne_forSleepThree(thePos, vertical) ||
		isThreeOne_forSleepThree(thePos, lowleft) || isThreeOne_forSleepThree(thePos, lowright)
		)
	{
		setWorldState(thePos, 0);
		return sleepThree;
	}
	//眠三的“@-000-@”
	if (
		((solidHorozontal.leftSpaceNum >= 1 && solidHorozontal.rightSpaceNum >= 1)&& (solidHorozontal.StringNum == 3)) ||
		((solidVertical.leftSpaceNum >= 1 && solidVertical.rightSpaceNum >= 1)&& (solidVertical.StringNum == 3)) ||
		((solidLowleft.leftSpaceNum >= 1 && solidLowleft.rightSpaceNum >= 1)&& (solidLowleft.StringNum == 3)) ||
		((solidLowlowright.leftSpaceNum >= 1 && solidLowlowright.rightSpaceNum >= 1)&& (solidLowlowright.StringNum == 3))
		)
	{
		setWorldState(thePos, 0);
		return sleepThree;
	}
	//活二,形如:“--00--”、“-0-0-”、“-0--0-”
	//判断“-00-”
	if (solidHorozontal.leftSpaceNum >= 1 && solidHorozontal.rightSpaceNum >= 1 && solidHorozontal.StringNum >= 2 ||
		solidVertical.leftSpaceNum >= 1 && solidVertical.rightSpaceNum >= 1 && solidVertical.StringNum >= 2 ||
		solidLowleft.leftSpaceNum >= 1 && solidLowleft.rightSpaceNum >= 1 && solidLowleft.StringNum >= 2 ||
		solidLowlowright.leftSpaceNum >= 1 && solidLowlowright.rightSpaceNum >= 1 && solidLowlowright.StringNum >= 2)
	{
		setWorldState(thePos, 0);
		return goodTwo;
	}
	//判断“-0-0-”
	if (
		isTwoOne(thePos, horizontal) || isTwoOne(thePos, vertical) ||
		isTwoOne(thePos, lowleft) || isTwoOne(thePos, lowright)
		)
	{
		setWorldState(thePos, 0);
		return goodTwo;
	}
	//判断“-0--0-”
	if (
		isTwoTwo(thePos, horizontal) || isTwoTwo(thePos, vertical) ||
		isTwoTwo(thePos, lowleft) || isTwoTwo(thePos, lowright)
		)
	{
		setWorldState(thePos, 0);
		return goodTwo;
	}
	//眠二,分“@00---”、“@0-0--”、“@0--0-”、“0---0”
	//眠二的“@00---”
	if (//只要有一边的空格数目大于等于2,就符合条件
		((solidHorozontal.leftSpaceNum >= 3 || solidHorozontal.rightSpaceNum >= 3) && (solidHorozontal.StringNum == 2)) ||
		((solidVertical.leftSpaceNum >= 3 || solidVertical.rightSpaceNum >= 3) && (solidVertical.StringNum == 2)) ||
		((solidLowleft.leftSpaceNum >= 3 || solidLowleft.rightSpaceNum >= 3) && (solidLowleft.StringNum == 2)) ||
		((solidLowlowright.leftSpaceNum >= 3 || solidLowlowright.rightSpaceNum >= 3) && (solidLowlowright.StringNum == 2))
		)
	{
		setWorldState(thePos, 0);
		return sleepTwo;
	}
	//眠二的“@0-0--”
	if (
		isTwoOneAnother(thePos, horizontal) || isTwoOneAnother(thePos, vertical) ||
		isTwoOneAnother(thePos, lowleft) || isTwoOneAnother(thePos, lowright)
		)
	{
		setWorldState(thePos, 0);
		return sleepTwo;
	}
	//眠二的“@0--0-”
	if (
		isTwoTwoAnother(thePos, horizontal) || isTwoTwoAnother(thePos, vertical) ||
		isTwoTwoAnother(thePos, lowleft) || isTwoTwoAnother(thePos, lowright)
		)
	{
		setWorldState(thePos, 0);
		return sleepTwo;
	}
	//眠二的“0---0”
	if (
		isTwoThree(thePos, horizontal) || isTwoThree(thePos, vertical) ||
		isTwoThree(thePos, lowleft) || isTwoThree(thePos, lowright)
		)
	{
		setWorldState(thePos, 0);
		return sleepTwo;
	}

	if (thePos.x == 7 && thePos.y == 7)
	{
		setWorldState(thePos, 0);
		return centerPoint;
	}
		
	setWorldState(thePos, 0);
	return 2;

}


Game.h

#pragma once
#include"GoBang.h"

const bool comVSplay = true;
const bool playVSplay = false;

class Game
{
public:
	Game(HWND theHwnd,HINSTANCE theHINSTANCE);//初始化game
	Game();
	~Game();
	void playChess(HWND hWnd,myPoint thePos);
	void gameRun();//运行游戏
	void gameEnd();//终止游戏
	bool gameover = false;//游戏结束
	GoBang * getGoBang();
	bool getGameMode()const{ return gameMode; }
	bool getBlackAction()const{ return blackAction; }
	bool getOffsetStatus()const{ return OffsetStatus; }
	void setGameMode(bool theGameMode){ gameMode = theGameMode; }
	void setBlackAction(){ blackAction = !blackAction; }
	void initBlackAction(){ blackAction = true; }
	void setOffsetStatus(bool theOffsetStatus){ OffsetStatus = theOffsetStatus; }

	int getStringNum(myPoint  thePos, int thestate, myPoint thestep);
	bool checkWin(myPoint  thePos);

	void isOffset(bool gameMode);

	void InitialWorld();
	void setCurrentPos(int thex, int they){ currentPos.x = thex; currentPos.y = they; }
	myPoint getCurrentPos()const{ return currentPos; }
	void Initial_Regret(){ pieceStack.erase(pieceStack.begin(), pieceStack.end()); }
	void addRegret(myPoint thePoint){ pieceStack.push_back(thePoint); }
	void GameRegret(HWND hWnd);

	myPoint RemoveReget()
	{ 
		if (!isRegretEmpty())
		{
			myPoint tempPoint=pieceStack.back();
			pieceStack.pop_back();
			return tempPoint;
		}
	}
	bool isRegretEmpty()
	{
		if (pieceStack.size() <2)
			return true;
		return false;
	}

	myPoint getRegretBack(){ return pieceStack.back(); }

	void setPlayChess(myPoint thePos){ isPlayChess = true; pos = thePos; };

private:
	myPoint pos;
	HWND hWnd=NULL;
	bool isPlayChess = false;
	GoBang * myGoBangGame;
	bool gameMode = comVSplay;//默认与电脑打
	bool blackAction = true;
	//跳转到新状态立刻设置为false,如果手动转变状态,立刻设置为true
	//playvsplay状态下,检查是否有变化(人机)进行状态转变
	bool OffsetStatus = false;//偏移状态,comvsplay下,检查是否有变化(人人),进行状态转变;
	myPoint currentPos;
	vector<myPoint> pieceStack;

};


Game.cpp

#include "stdafx.h"
#include "Game.h"

Game::Game(HWND theHwnd, HINSTANCE theHINSTANCE)
{
	hWnd = theHwnd;
	myGoBangGame = new GoBang(theHINSTANCE, theHwnd);
	gameMode = comVSplay;
}

Game::~Game()
{
	myGoBangGame->~GoBang();
}

void Game::gameRun()
{
	if (isPlayChess == true)
		playChess(hWnd, pos);
	myGoBangGame->drawBk();
	myGoBangGame->drawChess();
	myGoBangGame->drawWorld();
}

GoBang * Game::getGoBang()
{
	return myGoBangGame;
}

int Game::getStringNum(myPoint  thePos, int thestate, myPoint thestep)
{
	return myGoBangGame->getStringNum(thePos, thestate, thestep);
}

bool Game::checkWin(myPoint  thePos)
{
	return myGoBangGame->checkWin(thePos);
}

void Game::isOffset(bool gameMode)
{
	setOffsetStatus(false);
	initBlackAction();
	setGameMode(gameMode);
}

void Game::InitialWorld()
{
	for (int i = 0; i < 15; i++)
	for (int j = 0; j < 15; j++)
	{
		getGoBang()->setWorldState(myPoint(i, j), 0);
	}
	getGoBang()->InitialCurrentPos();
	getGoBang()->initialPieceNum();
	Initial_Regret();
}

void Game::GameRegret(HWND hWnd)
{
	if (getGoBang()->getPieceNum() >= 3)
	{
		myPoint tempPoint = RemoveReget();
		getGoBang()->setWorldState(myPoint(tempPoint.x, tempPoint.y), 0);
		tempPoint = RemoveReget();
		getGoBang()->setWorldState(myPoint(tempPoint.x, tempPoint.y), 0);
		getGoBang()->removePieceNum();
		getGoBang()->removePieceNum();
		getGoBang()->myCurrentPos.isExist = currentPos::Exist;
		getGoBang()->setCurrentPos(getRegretBack());
	}
}

void Game::playChess(HWND hWnd,myPoint thePos)
{
	isPlayChess = false;
	if (thePos >= myPoint(0, 0) && thePos <= myPoint(14, 14) && (getGoBang()->getWorldState(thePos) == 0))
	{
		if (getGameMode() == comVSplay)			//电脑和玩家
		{
			if (getBlackAction())
				SetDlgItemText(hWnd, 5002, _T("白棋"));
			else
				SetDlgItemText(hWnd, 5002, _T("黑棋"));
			if (getOffsetStatus() == false)//没有偏移状态发生,正常走
			{
				getGoBang()->setWorldState(thePos, 1);
				setBlackAction();
				getGoBang()->setCurrentPos(thePos);
				getGoBang()->addPieceNum();
				addRegret(thePos);
				//判断是否赢
				if (checkWin(thePos))
				{
					MessageBox(hWnd, _T("play获胜,可以重新开始"), _T("五子棋"), 0);
					return;
				}
				SetDlgItemText(hWnd, 5002, _T("白棋"));
				myPoint comPos(0, 0);
				getGoBang()->comPlay(comPos);
				setBlackAction();
				addRegret(comPos);
				getGoBang()->setCurrentPos(comPos);
				getGoBang()->myCurrentPos.isExist = currentPos::Exist;
				if ((checkWin(comPos)))
				{
					MessageBox(hWnd, _T("com获胜,可以重新开始"), _T("五子棋"), 0);
					return;
				}
				SetDlgItemText(hWnd, 5002, _T("黑棋"));
			}
			else
			{
				MessageBox(hWnd, _T("开启playVSplay"), _T("五子棋"), 0);
				isOffset(playVSplay);
				InitialWorld();
				SetDlgItemText(hWnd, 5002, _T("黑棋"));
			}
		}
		else								//玩家和玩家
		{
			if (getBlackAction())
				SetDlgItemText(hWnd, 5002, _T("白棋"));
			else
				SetDlgItemText(hWnd, 5002, _T("黑棋"));
			if (getOffsetStatus() == false)
			{
				if (getBlackAction())
				{
					getGoBang()->setWorldState(thePos, 1);
					setBlackAction();
				}
				else
				{
					getGoBang()->setWorldState(thePos, 2);
					setBlackAction();
				}
				addRegret(thePos);
				getGoBang()->addPieceNum();
				getGoBang()->setCurrentPos(thePos);
				if (checkWin(thePos))
				{
					if (getBlackAction())
					{
						MessageBox(hWnd, _T("白子获胜,可以重新开始"), _T("五子棋"), 0);
					}
					else
					{
						MessageBox(hWnd, _T("黑子获胜,可以重新开始"), _T("五子棋"), 0);
					}
					return;
				}
			}
			else
			{
				MessageBox(hWnd, _T("开启playVScom"), _T("五子棋"), 0);
				isOffset(comVSplay);
				InitialWorld();
				SetDlgItemText(hWnd, 5002, _T("黑棋"));
			}
		}
		if (getGoBang()->getPieceNum() == 225)
		{
			MessageBox(hWnd, _T("和局,可以重新开始"), _T("五子棋"), 0);
		}
	}
}


五子棋面向对象版本.cpp

#include "stdafx.h"
#include "五子棋面向对象版本.h"
#include"Game.h"

#define MAX_LOADSTRING 100

// 全局变量: 
HINSTANCE hInst;								// 当前实例
HWND g_hwnd;
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗口类名

const int windowWidth = 720;
const int windowHeight = 560;

Game * game;
// 此代码模块中包含的函数的前向声明: 
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	MSG msg;

	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}
	game=new Game(g_hwnd,hInst);
	CreateWindow(_T("static"), _T("回合:"), WS_CHILD | WS_VISIBLE, 550, 20, 100, 20, g_hwnd, (HMENU)5001, hInst, NULL);
	CreateWindow(_T("static"), _T("黑棋"), WS_CHILD | WS_VISIBLE, 550, 44, 100, 20, g_hwnd, (HMENU)5002, hInst, NULL);
	CreateWindow(_T("button"), _T("玩家vs电脑(默认模式)"), WS_CHILD | WS_VISIBLE | WS_BORDER, 500, 70, 200, 20, g_hwnd, (HMENU)5003, hInst, NULL);
	CreateWindow(_T("button"), _T("玩家vs玩家(点击切换模式)"), WS_CHILD | WS_VISIBLE | WS_BORDER, 500, 95, 200, 40, g_hwnd, (HMENU)5004, hInst, NULL);
	CreateWindow(_T("static"), _T("切换模式后请鼠标点击棋盘"), WS_CHILD | WS_VISIBLE, 500, 140, 100, 50, g_hwnd, (HMENU)5005, hInst, NULL);
	CreateWindow(_T("button"), _T("重新开始"), WS_CHILD | WS_VISIBLE | WS_BORDER, 500, 200, 180, 45, g_hwnd, (HMENU)5006, hInst, NULL);
	CreateWindow(_T("button"), _T("悔棋(子数>=4)"), WS_CHILD | WS_VISIBLE | WS_BORDER, 500, 250, 180, 45, g_hwnd, (HMENU)5007, hInst, NULL);
 
	ZeroMemory(&msg, sizeof(MSG));

	while (!game->gameover)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);		
		}
		game->gameRun();
	}
	game->~Game();
	return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_MY);
	wcex.lpszClassName	= _T("gobangclass");
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // 将实例句柄存储在全局变量中

   hWnd = CreateWindow(_T("gobangclass"), szTitle, WS_OVERLAPPEDWINDOW,
	   0, 0, windowWidth, windowHeight, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }
   g_hwnd = hWnd;
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_LBUTTONDOWN:
	{
						   int x = LOWORD(lParam);
						   int y = HIWORD(lParam);
						   int tx = (x - 10) / 32;	//直接除以32,第一个点的像素坐标如果是33,除下来x被确定错会是1,需要-10,这样,就是0了
						   int ty = (y - 10) / 32;
						   myPoint pos(tx, ty);
						   game->setPlayChess(pos);
		break;
	}

	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		switch (wmId)
		{
		case 5003:
		{
					 game->setOffsetStatus(true);
		}
			break;
		case 5004:
		{
					 game->setOffsetStatus(true);
		}
			break;
		case 5006:
		{
					 game->InitialWorld();
					 MessageBox(0, _T("可以玩新的一局了"), 0, 0);
		}
			break;
		case 5007://悔棋gameRegret
		{
					  game->GameRegret(hWnd);
		}
			break;
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO:  在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
	{
					   game->gameover = true; 
					   PostQuitMessage(0);
	}
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

运行结果

起始界面
起始界面
电脑获胜
电脑获胜
黑棋获胜

黑棋获胜

在这里插入图片描述

悔棋前
悔棋1
悔棋后

悔棋2

项目完整链接,使用visualstudio打开sln文件

https://pan.baidu.com/s/1zRdaAyuR5U0OyIytEOWmUw
提取码c2hf

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值