数据结构与算法课程设计之五子棋(人机)

数据结构与算法课程设计之五子棋(人机)

五子棋是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连线者获胜。
这是我在大二下数据结构与算法课程设计的时候做的经典小游戏。如果仅仅做一个人人对战的五子棋(不联机)是非常简单的。这实际就是一个简单的界面设计,鼠标事件的响应以及五子连珠的判断问题。但我做了一个人机对战的五子棋。你下一子,电脑会下一子,谁先连成五子谁获得胜利。想要电脑足够智能(当然没有用到现在比较热门的机器学习和深度学习),就需要程序能够应对各种情况(这里相对比较复杂,需要足够了解五子棋的规则,有一定技术的人才能让电脑不至于是一个大傻瓜)。对于一个对弈类的游戏,其实可以使用博弈树来做,可以让电脑找到有限步内的最优解,但我当时并不是很了解博弈树,所以就没用。完全是分了将近20种情况,电脑遇到不同情况做出不同的选择。
除了人机对弈做的有模有样,我的界面也受到了室友们的一致赞同。并且课设老师在验收的时候就直接给了优(一般需要经过验收+报告等步骤,最后综合给分)。下面展示一下我的程序的界面:
C++课程设计之小游戏欢乐小鱼
在这里插入图片描述
上面是登录界面,哪个樱花一直在往下掉落,是动态的。有人人对战模式和人机对战模式。掉落的梅花是一个类,类有一个实现往下掉落的函数。
在这里插入图片描述
这个界面是游戏的介绍。
在这里插入图片描述
人机对战,界面包含了基本的下棋功能。以及悔棋,重玩,计实等功能。整个棋盘是一个二维的数组。没棋子的位子为0.,下白棋的位置位为1,下黑棋的位置为2。(可能是反着的,我记得不是很清楚了)
在这里插入图片描述
上面一局棋,是人机对弈。我和电脑玩的。我先手执黑棋,电脑执白棋。很容易看出来是我输了。
最后我会把代码放在后面,需要的可以运行看看效果。所以我先讲讲运行环境:
我编译的环境:windows 10、Visual Studio 2017Easy_x春分版2018(加载图形库)。
我上面已经标好软件的位置了,你也可以下载最高版本的,是可以运行我的程序的。
由于需要加载easy_x图形库,所以在下载好【Easy_x】后,点击它然后进去找到vs,点一下安装就可以了(记得重新打开vs)。
这个是程序用到的图片,可以免费下载:图片资源(使用的相对路径,需要把图片(不是图片文件夹)放到源代码同一级目录下)
代码:

//////////////////////////////////////////////////////////////
///项目名称:五子棋                                        ///
///编译程序:Visual Studio 2017                             ///
///图形库:Easyx2018春分版(下载网址:http://www.easyx.cn )///
///作者:[email protected]                                 ///
//////////////////////////////////////////////////////////////
#include<iostream>
using namespace std;
#include<graphics.h>
#include<conio.h>
#include<time.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")

enum Condition {//状态
	NO_CHESSMEN, BLACK_CHESSMEN, WHITE_CHESSMEN, WALL
};
enum Direction {//方向
	HORIZONTAL, VERTICAL, POSITIVE_BATTER, NEGATIVE_BATTER
};
class Flowers {//飞舞梅花
public:
	Flowers()
	{
		loadimage(&img[0], _T("桃花一朵1.png"));
		loadimage(&img[1], _T("桃花一朵2.png"));
		loadimage(&img[2], _T("桃花一朵3.png"));
		loadimage(&img[3], _T("桃花一朵4.png"));
		loadimage(&img1, _T("桃花枝.png"));
		loadimage(&img3, _T("棋盘.png"));
		x = (rand() % 250) + 20;
		m = (rand() % 2) + 1;
	}
	void Move()
	{
		n = n + m;
		if (n % (m * 5) == 0) l++;
		if (l >= 4) l = 0;
		putimage(x, 100 + n, &img[l]);
		putimage(-50, -50, &img1, SRCPAINT);
		putimage(0, 250, &img3, SRCPAINT);
		setlinecolor(BLACK);
		line(x, 100 + n, x + 25, 100 + n);
		if (m == 2)line(x, 101 + n, x + 25, 101 + n);
		if (n >= 360)
		{
			n = 0;
			x = (rand() % 250) + 20;
			m = (rand() % 2) + 1;
		}
	}
private:
	IMAGE img[4];
	IMAGE img1, img3;
	int x;
	int  n = 0, l = 0, m = 1;

};
class Point {//点类
public:
	Point()
	{
		x = 0;
		y = 0;
		condition = NO_CHESSMEN;
		for (int i = 0; i < 4; i++)
			W[i] = 0;
	}
	void Change_Condition(Condition condition1)
	{
		condition = condition1;
	}
	Condition Get_Condition()
	{
		return condition;
	}
	int Get_M_W()
	{
		int a, b;
		a = max(W[0], W[1]);
		b = max(W[2], W[3]);
		return max(a, b);
	}
	int x;
	int y;
	int W[4];//横、纵、正斜、反斜
private:
	Condition condition;
};
typedef struct Lnode {//链表节点
	Point point;
	int W_mun;
	int W_max;
	Lnode* next;
}Lnode;

typedef int Status;//相当于定义一个bool;
const int NODE = 15;//棋盘大小15*15。
IMAGE img11, img21, img12, img22;
int ss = 1;//判断可否落子。1-可以,0-不可以
void Introduce();
Status Pop(Lnode* top);//出栈
Status Push(Lnode* top, Point point);//入栈
void Draw_Begin_Face();//(图片的插入和布局)
void Draw_Chessboard();//画棋盘(主要是画线条)
Status Init_List(Lnode*& H, Point point);//创链表
Status Increase_Node(Lnode*& H, Lnode* node);//头插法
void Coordinate(Point point[NODE + 2][NODE + 2]);//坐标初始化
void PVP(int l, int p, int q, Point point[NODE + 2][NODE + 2]);//人人对战
void PVC(int l, int p, int q, Point point[NODE + 2][NODE + 2]);//人机对弈
int Work(int front, int back, Condition condition1, Condition condition2);//计算权值
int Get_Weight(Point point[NODE + 2][NODE + 2], int i, int j, Condition condition, Direction direction);//获取权值
void Charge(Point point[NODE + 2][NODE + 2], int i, int j, Condition condition);//判断是否有五子连珠(是否有一方获得胜利)
int main()
{
	int h = 0;//花瓣落下时,控制各花朵出现的时间。
	MOUSEMSG m;	// 定义鼠标消息
	int l = 0;//用来判断当前落子的颜色
	int q = 0, p = 0;
	Flowers flower[6];
	srand((unsigned)time(NULL));
	loadimage(&img11, _T("悔1.jpg"));
	loadimage(&img21, _T("重1.jpg"));
	loadimage(&img12, _T("悔2.jpg"));
	loadimage(&img22, _T("重2.jpg"));
	/*mciSendString(_T("open 亡灵序曲.mp3 alias music1"), NULL, 0, NULL);///////////////////////////////
	mciSendString(_T("play music1 repeat"), NULL, 0, NULL);///////////////////////////////////////////
	mciSendString(_T("stop music1 "), NULL, 0, NULL);/////////////////////////////////////////////*/
	initgraph(560, 460);
	HWND hWnd = GetHWnd();
	// 使用 API 函数修改窗口名称
	SetWindowText(hWnd, _T("五子棋"));
	Draw_Begin_Face();
	while (true)
	{
		Point point[NODE + 2][NODE + 2];
		Coordinate(point);
		while (MouseHit())
		{
			m = GetMouseMsg();// 获取一条鼠标消息
			switch (m.uMsg)
			{
			case WM_LBUTTONDOWN:
				if (m.x >= 400 && m.x <= 504)
				{
					closegraph();
					if (m.y >= 330 && m.y <= 355) { Draw_Chessboard(); PVP(l, p, q, point); }
					if (m.y >= 365 && m.y <= 390) { Draw_Chessboard(); PVC(l, p, q, point); }
					if (m.y >= 400 && m.y <= 425) { Introduce(); }
					if (m.y >= 435 && m.y <= 460) { return 0; }
					setfillcolor(BLACK);
					cleardevice();
					Draw_Begin_Face();
				}
			}
		}
		h++;
		flower[0].Move();
		if (h >= 100)flower[1].Move();
		if (h >= 140)flower[2].Move();
		if (h >= 180)flower[3].Move();
		if (h >= 220)flower[4].Move();
		if (h >= 270)flower[5].Move();
		Sleep(50);
	}
	closegraph();
	return 0;
}

void Introduce()
{
	initgraph(560, 460);
	IMAGE img1;
	loadimage(&img1, _T("桃花枝.png"));
	IMAGE img3;
	loadimage(&img3, _T("棋盘.png"));
	putimage(0, 250, &img3);
	putimage(-50, -50, &img1);
	settextcolor(GREEN);
	outtextxy(300, 150, _T("游戏名称:简易五子棋"));
	outtextxy(300, 170, _T("游戏玩法:人人对战、人机对战"));
	outtextxy(300, 200, _T("人人对战:两人用鼠标点击下棋,"));
	outtextxy(300, 220, _T("                   先下的玩家执黑旗,后下"));
	outtextxy(300, 240, _T("                   的执白棋。"));
	outtextxy(300, 270, _T("人机对战:玩家和电脑对抗,玩家"));
	outtextxy(300, 290, _T("                   可以选择先手,也可以当"));
	outtextxy(300, 310, _T("                   后手,可悔棋,可重玩。"));
	int j = 0;
	FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
	while (!_kbhit())
	{
		outtextxy(j, 440, _T("按任意键退出"));
		setfillcolor(BLACK);
		solidrectangle(j - 1, 440, j, 460);
		Sleep(20);
		j++;
		if (j >= 570)j = 0;
	}
}
void Draw_Begin_Face()
{
	IMAGE img1;
	loadimage(&img1, _T("桃花枝.png"));
	putimage(-50, -50, &img1);
	IMAGE img4[3];
	loadimage(&img4[0], _T("五.png"));
	putimage(325, 0, &img4[0]);
	loadimage(&img4[1], _T("子.png"));
	putimage(335, 100, &img4[1]);
	loadimage(&img4[2], _T("棋.png"));
	putimage(395, 140, &img4[2]);
	IMAGE img[4];
	loadimage(&img[0], _T("桃花一朵1.png"));
	loadimage(&img[1], _T("桃花一朵2.png"));
	loadimage(&img[2], _T("桃花一朵3.png"));
	loadimage(&img[3], _T("桃花一朵4.png"));
	IMAGE img3;
	loadimage(&img3, _T("棋盘.png"));
	putimage(0, 250, &img3);
	IMAGE img6[4];
	loadimage(&img6[0], _T("人人.png"));
	loadimage(&img6[1], _T("人机.png"));
	loadimage(&img6[2], _T("介绍.png"));
	loadimage(&img6[3], _T("退出.png"));
	putimage(400, 330, &img6[0]);
	putimage(400, 365, &img6[1]);
	putimage(400, 400, &img6[2]);
	putimage(400, 435, &img6[3]);
}
void Draw_Chessboard()
{
	initgraph(560, 460);
	setlinecolor(RGB(230, 200, 150));
	setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 1);
	line(320, 0, 320, 320);
	IMAGE img;
	loadimage(&img, _T("木头4.jpg"));
	putimage(0, 0, &img);
	for (int i = 2; i < NODE; i++)
	{
		line(20, (i - 1) * 30 + 20, 440, (i - 1) * 30 + 20);
		line((i - 1) * 30 + 20, 20, (i - 1) * 30 + 20, 440);
	}
	setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 3);
	line(20, (1 - 1) * 30 + 20, 440, (1 - 1) * 30 + 20);
	line(20, (NODE - 1) * 30 + 20, 440, (NODE - 1) * 30 + 20);
	line((1 - 1) * 30 + 20, 20, (1 - 1) * 30 + 20, 440);
	line((NODE - 1) * 30 + 20, 20, (NODE - 1) * 30 + 20, 440);
	setfillcolor(BLACK);
	solidcircle(110, 110, 3);
	solidcircle(350, 110, 3);
	solidcircle(110, 350, 3);
	solidcircle(350, 350, 3);
	solidcircle(230, 230, 3);
}
Status Pop(Lnode* top)
{
	if (top->next == NULL) return false;
	Lnode* q;
	q = top->next;
	top->next = q->next;
	free(q);
	return true;
}
Status Push(Lnode* top, Point point)
{
	Lnode* p = new Lnode;
	if (!p) return false;
	p->point = point;
	p->next = top->next;
	top->next = p;
	return true;
}
Status Init_List(Lnode*& H, Point point)//////////////论初始化的重要性
{
	Lnode* p = new Lnode;
	if (!p)return false;
	p->W_mun = 0;
	p->W_max = 0;
	p->point = point;
	p->next = NULL;
	Increase_Node(H, p);
	return 1;
}
Status Increase_Node(Lnode*& H, Lnode* node)//头插法
{
	node->next = H->next;
	H->next = node;
	return 1;

}
void Coordinate(Point point[NODE + 2][NODE + 2])
{
	for (int i = 0; i < NODE + 2; i++)//对落子位置初始化
		for (int j = 0; j < NODE + 2; j++)
		{
			point[i][j].x = (i - 1) * 30 + 20;
			point[i][j].y = (j - 1) * 30 + 20;
		}
	for (int i = 0; i < NODE + 2; i++)//对棋盘边界初始化
	{
		point[i][0].Change_Condition(WALL);
		point[i][16].Change_Condition(WALL);
		point[0][i].Change_Condition(WALL);
		point[16][i].Change_Condition(WALL);
	}
}//点的坐标
void PVP(int l, int p, int q, Point point[NODE + 2][NODE + 2])
{
	IMAGE IM, Im;
	int out = 1;
	int minute = 0, secend = 0;
	TCHAR s1[5], s2[5];
	putimage(470, 80, &img11);
	putimage(470, 180, &img21);
	settextcolor(RED);
	settextstyle(30, 0, _T("宋体"));
	outtextxy(470, 350, _T("退出"));
	outtextxy(470, 400, _T("返回"));
	settextstyle(0, 0, _T("宋体"));
	getimage(&Im, 470, 80, 60, 60);
	getimage(&IM, 40, 40, 21, 21);//悔棋后恢复棋盘
	solidrectangle(470, 20, 530, 45);
	_stprintf_s(s2, _T("%d"), secend);
	outtextxy(510, 25, s2);
	_stprintf_s(s1, _T("%d"), minute);
	outtextxy(480, 25, s1);
	outtextxy(495, 25, _T(":"));
	SYSTEMTIME t1, t2; GetLocalTime(&t1);
	Lnode* top = new Lnode;
	if (!top)exit(0);
	top->W_max = 0; top->W_mun = 0; top->next = NULL; top->point = point[0][0];
	HWND wnd = GetHWnd();
	MOUSEMSG m;
	while (out)
	{
		GetLocalTime(&t2);
		if (t2.wSecond != t1.wSecond)
		{
			secend++;
			_stprintf_s(s1, _T("%d"), secend);
			setfillcolor(BLACK);
			solidrectangle(500, 20, 530, 45);
			outtextxy(510, 25, s1);
			t1 = t2;
		}
		if (secend >= 60)
		{
			secend = 0; minute++;
			_stprintf_s(s2, _T("%d"), minute);
			outtextxy(480, 25, s2);
		}
		while (MouseHit())
		{
			m = GetMouseMsg();// 获取一条鼠标消息
			switch (m.uMsg)
			{
			case WM_LBUTTONDOWN:
				for (int i = 1; i <= NODE; i++)
					for (int j = 1; j <= NODE; j++)
					{
						if (ss == 1 && (point[i][j].x - m.x) * (point[i][j].x - m.x) + (point[i][j].y - m.y) * (point[i][j].y - m.y) <= 100 && point[i][j].Get_Condition() == NO_CHESSMEN)
						{
							if (l == 0)
							{
								setfillcolor(WHITE);
								solidcircle(point[q][p].x, point[q][p].y, 10);
								setfillcolor(BLACK);
								solidcircle(point[i][j].x, point[i][j].y, 10);
								setfillcolor(RED);
								solidcircle(point[i][j].x, point[i][j].y, 3);
								point[i][j].Change_Condition(BLACK_CHESSMEN);
								Push(top, point[i][j]);
								Charge(point, i, j, BLACK_CHESSMEN);
								l = 1;//l=1,则下白棋
								q = i; p = j;
							}
							else
							{
								setfillcolor(BLACK);
								solidcircle(point[q][p].x, point[q][p].y, 10);
								setfillcolor(WHITE);
								solidcircle(point[i][j].x, point[i][j].y, 10);
								setfillcolor(RED);
								solidcircle(point[i][j].x, point[i][j].y, 3);
								point[i][j].Change_Condition(WHITE_CHESSMEN);
								Push(top, point[i][j]);
								Charge(point, i, j, WHITE_CHESSMEN);
								q = i; p = j;
								l = 0;//l=0,则下黑棋
							}

						}
					}
				if ((m.x - 500) * (m.x - 500) + (m.y - 110) * (m.y - 110) <= 30 * 30 && top->next != NULL)
				{
					ss = 1;
					putimage(470, 80, &Im);
					putimage(477, 87, &img12);
					Sleep(50);
					putimage(470, 80, &img11);
					int ii = (top->next->point.x - 20) / 30 + 1;
					int jj = (top->next->point.y - 20) / 30 + 1;
					point[ii][jj].Change_Condition(NO_CHESSMEN);
					putimage(point[ii][jj].x - 10, point[ii][jj].y - 10, &IM);
					Pop(top);/////////////////////////////////////////////////////////////////////////////////////////////
					q = 0, p = 0;
				}
				if ((m.x - 500) * (m.x - 500) + (m.y - 210) * (m.y - 210) <= 30 * 30 && top->next != NULL)
				{
					ss = 1;
					putimage(470, 180, &Im);
					putimage(477, 187, &img22);
					Sleep(50);
					putimage(470, 180, &img21);
					for (Lnode* p = top; top->next != NULL;)
					{
						int ii = (top->next->point.x - 20) / 30 + 1;
						int jj = (top->next->point.y - 20) / 30 + 1;
						point[ii][jj].Change_Condition(NO_CHESSMEN);
						putimage(point[ii][jj].x - 10, point[ii][jj].y - 10, &IM);
						Pop(top);
					}
					q = 0, p = 0, l = 0, secend = 0, minute = 0;
				}
				if (m.x >= 470 && m.x <= 530 && m.y >= 350 && m.y <= 380)
				{
					HWND wnd = GetHWnd();
					if (MessageBox(wnd, _T("是否退出游戏?"), _T("退出"), MB_YESNO | MB_ICONQUESTION) == IDYES)
						exit(1);
				}
				if (m.x >= 470 && m.x <= 530 && m.y >= 400 && m.y <= 430)
				{
					HWND wnd = GetHWnd();
					if (MessageBox(wnd, _T("是否返回上一界面?"), _T("返回"), MB_YESNO | MB_ICONQUESTION) == IDYES)
						out = 0;
				}
			}
		}
	}
}
void PVC(int l, int p, int q, Point point[NODE + 2][NODE + 2])
{
	IMAGE IM, Im;
	int choose;
	int out = 1;
	TCHAR s1[5], s2[5];
	int minute = 0, secend = 0;
	SYSTEMTIME t1, t2;
	GetLocalTime(&t1);
	putimage(470, 80, &img11);
	putimage(470, 180, &img21);
	settextcolor(RED);
	settextstyle(30, 0, _T("宋体"));
	outtextxy(470, 350, _T("退出"));
	outtextxy(470, 400, _T("返回"));
	settextstyle(0, 0, _T("宋体"));
	getimage(&Im, 470, 80, 60, 60);
	getimage(&IM, 40, 40, 21, 21);//悔棋后恢复棋盘
	solidrectangle(470, 20, 530, 45);
	_stprintf_s(s2, _T("%d"), secend);
	outtextxy(510, 25, s2);
	_stprintf_s(s1, _T("%d"), minute);
	outtextxy(480, 25, s1);
	outtextxy(495, 25, _T(":"));
	Lnode* top = new Lnode;
	if (!top)exit(0);
	top->W_max = 0; top->W_mun = 0; top->next = NULL; top->point = point[0][0];
	Sleep(1000);
	HWND wnd = GetHWnd();
	if (MessageBox(wnd, _T("是否先手?"), _T("选择"), MB_YESNO | MB_ICONQUESTION) == IDYES)
		choose = 1;
	else choose = 0;
	MOUSEMSG m;
	while (out)
	{
		if (l == choose)
		{
			int number = 0;
			Lnode* H = new Lnode;
			if (!H)exit(0);
			H->W_max = 0; H->W_mun = 0; H->next = NULL; H->point = point[0][0];
			for (int i = NODE; i > 0; i--)
				for (int j = NODE; j > 0; j--)
				{
					if (point[i][j].Get_Condition() == NO_CHESSMEN) { Init_List(H, point[i][j]); number++; }
				}
			for (Lnode* p = H; p->next != NULL; )
			{
				int i = (p->next->point.x - 20) / 30 + 1;
				int j = (p->next->point.y - 20) / 30 + 1;
				p->next->point.W[0] = Get_Weight(point, i, j, WHITE_CHESSMEN, HORIZONTAL) + Get_Weight(point, i, j, BLACK_CHESSMEN, HORIZONTAL);
				p->next->point.W[1] = Get_Weight(point, i, j, WHITE_CHESSMEN, VERTICAL) + Get_Weight(point, i, j, BLACK_CHESSMEN, VERTICAL);
				p->next->point.W[2] = Get_Weight(point, i, j, WHITE_CHESSMEN, POSITIVE_BATTER) + Get_Weight(point, i, j, BLACK_CHESSMEN, POSITIVE_BATTER);
				p->next->point.W[3] = Get_Weight(point, i, j, WHITE_CHESSMEN, NEGATIVE_BATTER) + Get_Weight(point, i, j, BLACK_CHESSMEN, NEGATIVE_BATTER);
				p->next->W_max = p->next->point.Get_M_W();
				p->next->W_mun = p->next->point.W[0] + p->next->point.W[1] + p->next->point.W[2] + p->next->point.W[3];
				if (p->next->W_max >= H->W_max)
				{
					H->W_max = p->next->W_max;
					p = p->next;
				}
				else
				{
					Lnode* q = p->next;
					p->next = p->next->next;
					delete(q);
					number--;
				}
			}
			if (H->next != NULL)
			{
				for (Lnode* p = H; p->next != NULL;)
				{
					if (p->next->W_max < H->W_max)
					{
						Lnode* q = p->next;
						p->next = p->next->next;
						delete(q);
						number--;
					}
					else
					{
						if (p->next->W_mun > H->W_mun) H->W_mun = p->next->W_mun;
						p = p->next;
					}
				}
				for (Lnode* p = H; p->next != NULL;)
				{
					if (p->next->W_mun < H->W_mun)
					{
						Lnode* q = p->next;
						p->next = p->next->next;
						delete(q);
						number--;
					}
					else p = p->next;
				}
				int w = rand() % number;
				while ((w - 1) >= 0)
				{
					H->next = H->next->next;
					w--;
				}
				int i = (H->next->point.x - 20) / 30 + 1;
				int j = (H->next->point.y - 20) / 30 + 1;
				if (choose == 0)
				{
					setfillcolor(WHITE);
					solidcircle(point[q][p].x, point[q][p].y, 10);
					setfillcolor(BLACK);
					solidcircle(point[i][j].x, point[i][j].y, 10);
					setfillcolor(RED);
					solidcircle(point[i][j].x, point[i][j].y, 3);
					point[i][j].Change_Condition(BLACK_CHESSMEN);
					Charge(point, i, j, BLACK_CHESSMEN);
				}
				else
				{
					setfillcolor(BLACK);
					solidcircle(point[q][p].x, point[q][p].y, 10);
					setfillcolor(WHITE);
					solidcircle(point[i][j].x, point[i][j].y, 10);
					setfillcolor(RED);
					solidcircle(point[i][j].x, point[i][j].y, 3);
					point[i][j].Change_Condition(WHITE_CHESSMEN);
					Charge(point, i, j, WHITE_CHESSMEN);
				}
				Push(top, point[i][j]);
				q = i; p = j;
			}
			else MessageBox(NULL, _T("平局,厉害了!"), _T("游戏结束"), MB_OK);
			l = !choose;//l=0,则下黑棋
			secend = 0;
		}
		else
		{
			GetLocalTime(&t2);
			if (t2.wSecond != t1.wSecond)
			{
				secend++;
				_stprintf_s(s1, _T("%d"), secend);
				setfillcolor(BLACK);
				solidrectangle(500, 20, 530, 45);
				outtextxy(510, 25, s1);
				t1 = t2;
			}
			if (secend >= 60)
			{
				secend = 0; minute++;
				_stprintf_s(s2, _T("%d"), minute);
				outtextxy(480, 25, s2);
			}
			while (MouseHit())
			{
				m = GetMouseMsg();// 获取一条鼠标消息
				switch (m.uMsg)
				{
				case WM_LBUTTONDOWN:
				{
					for (int i = 1; i <= NODE; i++)
						for (int j = 1; j <= NODE; j++)
							if (ss == 1 && (point[i][j].x - m.x) * (point[i][j].x - m.x) + (point[i][j].y - m.y) * (point[i][j].y - m.y) <= 100 && point[i][j].Get_Condition() == NO_CHESSMEN)
							{
								if (choose == 1)
								{
									setfillcolor(WHITE);
									solidcircle(point[q][p].x, point[q][p].y, 10);
									setfillcolor(BLACK);
									solidcircle(point[i][j].x, point[i][j].y, 10);
									setfillcolor(RED);
									solidcircle(point[i][j].x, point[i][j].y, 3);
									point[i][j].Change_Condition(BLACK_CHESSMEN);
									Charge(point, i, j, BLACK_CHESSMEN);
								}
								else
								{
									setfillcolor(BLACK);
									solidcircle(point[q][p].x, point[q][p].y, 10);
									setfillcolor(WHITE);
									solidcircle(point[i][j].x, point[i][j].y, 10);
									setfillcolor(RED);
									solidcircle(point[i][j].x, point[i][j].y, 3);
									point[i][j].Change_Condition(WHITE_CHESSMEN);
									Charge(point, i, j, WHITE_CHESSMEN);
								}
								Push(top, point[i][j]);
								l = choose;
								q = i; p = j;
							}
				}
				if ((m.x - 500) * (m.x - 500) + (m.y - 110) * (m.y - 110) <= 30 * 30 && top->next != NULL)
				{
					ss = 1;
					putimage(470, 80, &Im);
					putimage(477, 87, &img12);
					Sleep(50);
					putimage(470, 80, &img11);
					int ii = (top->next->point.x - 20) / 30 + 1;
					int jj = (top->next->point.y - 20) / 30 + 1;
					point[ii][jj].Change_Condition(NO_CHESSMEN);
					putimage(point[ii][jj].x - 10, point[ii][jj].y - 10, &IM);
					Pop(top);
					ii = (top->next->point.x - 20) / 30 + 1;
					jj = (top->next->point.y - 20) / 30 + 1;
					point[ii][jj].Change_Condition(NO_CHESSMEN);
					putimage(point[ii][jj].x - 10, point[ii][jj].y - 10, &IM);
					Pop(top);
					q = 0, p = 0;
				}
				if ((m.x - 500) * (m.x - 500) + (m.y - 210) * (m.y - 210) <= 30 * 30 && top->next != NULL)
				{
					ss = 1;
					putimage(470, 180, &Im);
					putimage(477, 187, &img22);
					Sleep(50);
					putimage(470, 180, &img21);
					for (Lnode* p = top; top->next != NULL;)
					{
						int ii = (top->next->point.x - 20) / 30 + 1;
						int jj = (top->next->point.y - 20) / 30 + 1;
						point[ii][jj].Change_Condition(NO_CHESSMEN);
						putimage(point[ii][jj].x - 10, point[ii][jj].y - 10, &IM);
						Pop(top);
					}
					q = 0, p = 0, l = 0;
					if (MessageBox(wnd, _T("是否先手?"), _T("选择"), MB_YESNO | MB_ICONQUESTION) == IDYES)
						choose = 1;
					else choose = 0;
				}
				if (m.x >= 470 && m.x <= 530 && m.y >= 350 && m.y <= 380)
				{
					HWND wnd = GetHWnd();
					if (MessageBox(wnd, _T("是否退出游戏?"), _T("退出"), MB_YESNO | MB_ICONQUESTION) == IDYES)
						exit(1);
				}
				if (m.x >= 470 && m.x <= 530 && m.y >= 400 && m.y <= 430)
				{
					HWND wnd = GetHWnd();
					if (MessageBox(wnd, _T("是否返回上一界面?"), _T("返回"), MB_YESNO | MB_ICONQUESTION) == IDYES)
						out = 0;
				}
				}
			}
		}
	}
}
int Work(int front, int back, Condition condition1, Condition condition2)
{
	switch (front + back)
	{
	case 0:
		return 0; break;//权值
	case 1: if (condition1 != NO_CHESSMEN && condition2 != NO_CHESSMEN)return 0;
		  else if (condition1 == NO_CHESSMEN && condition2 == NO_CHESSMEN) return 10;
		  else return 1; break;
	case 2: if (condition1 != NO_CHESSMEN && condition2 != NO_CHESSMEN)return 0;
		  else if (condition1 == NO_CHESSMEN && condition2 == NO_CHESSMEN) return 100;
		  else return 10; break;
	case 3: if (condition1 != NO_CHESSMEN && condition2 != NO_CHESSMEN)return 0;
		  else if (condition1 == NO_CHESSMEN && condition2 == NO_CHESSMEN) return 1000;
		  else return 100; break;
	default: return 10000;//权值
	}
}
int Get_Weight(Point point[NODE + 2][NODE + 2], int i, int j, Condition condition, Direction direction)
{//权值计算
	int front = 0, back = 0, e = 0, m = 0;
	int h = i, l = j;
	Condition condition1 = NO_CHESSMEN, condition2 = NO_CHESSMEN;
	if (direction == HORIZONTAL)m = min(4, h);
	else if (direction == VERTICAL)m = min(4, l);
	else if (direction == POSITIVE_BATTER) { e = min(h, l); m = min(4, e); }
	else { e = min(16 - h, l); m = min(4, e); }
	while (m > 0)
	{
		switch (direction)
		{
		case HORIZONTAL: h--; break;
		case VERTICAL:l--; break;
		case POSITIVE_BATTER: h--; l--; break;
		case NEGATIVE_BATTER:h++; l--; break;
		default:exit(0);
		}
		if (point[h][l].Get_Condition() == condition) front++;
		else {
			condition1 = point[h][l].Get_Condition();
			break;
		}
		m--;
	}
	if (direction == HORIZONTAL)m = min(4, 16 - i);
	else if (direction == VERTICAL)m = min(4, 16 - j);
	else if (direction == POSITIVE_BATTER) { e = min(16 - i, 16 - j); m = min(4, e); }
	else { e = min(i, 16 - j); m = min(4, e); }
	while (m > 0)
	{
		switch (direction)
		{
		case HORIZONTAL: i++; break;
		case VERTICAL:j++; break;
		case POSITIVE_BATTER: i++; j++; break;
		case NEGATIVE_BATTER:i--; j++; break;
		default:exit(0);
		}
		if (point[i][j].Get_Condition() == condition) back++;
		else {
			condition2 = point[i][j].Get_Condition();
			break;
		}
		m--;
	}
	return Work(front, back, condition1, condition2);
};
void Charge(Point point[NODE + 2][NODE + 2], int i, int j, Condition condition)
{
	int m, h = 0;
	if (condition == WHITE_CHESSMEN)m = 0;
	else m = 1;
	for (int e = 0, k = 1; k <= NODE; k++)//判断横向
	{

		if (point[k][j].Get_Condition() == condition) e++;
		else e = 0;
		if (e == 5) h++;

	}
	for (int e = 0, k = 1; k < NODE; k++)//判断纵向
	{

		if (point[i][k].Get_Condition() == condition) e++;
		else e = 0;
		if (e == 5)h++;
	}
	if (i >= j)
	{
		for (int e = 0, k = 1, l = (i - j) + 1; l <= NODE; k++, l++)
		{
			if (point[l][k].Get_Condition() == condition) e++;
			else e = 0;
			if (e == 5) h++;
		}
	}
	else
	{
		for (int e = 0, k = 1, l = (j - i) + 1; l <= NODE; k++, l++)
		{
			if (point[k][l].Get_Condition() == condition) e++;
			else e = 0;
			if (e == 5) h++;
		}
	}
	if (i + j <= NODE)
	{
		for (int e = 0, k = 1, l = (i + j) - 1; l > 0; k++, l--)
		{
			if (point[l][k].Get_Condition() == condition) e++;
			else e = 0;
			if (e == 5) h++;
		}
	}
	else
	{
		for (int e = 0, k = j + i - NODE, l = NODE; k <= NODE; k++, l--)
		{
			if (point[l][k].Get_Condition() == condition) e++;
			else e = 0;
			if (e == 5) h++;
		}
	}
	if (m == 0 && h != 0) { MessageBox(NULL, _T("执白者获胜!"), _T("游戏结束"), MB_OK); ss = 0; }
	if (m == 1 && h != 0) { MessageBox(NULL, _T("执黑者获胜!"), _T("游戏结束"), MB_OK); ss = 0; }
}
/*setfillcolor(BLUE);
if (Music == true)
{
Music = false;
solidrectangle(0, -160, 30, -130);
outtextxy(0, -160, L"关");
}
else
{
Music = true;
solidrectangle(0, -160, 30, -130);
outtextxy(0, -160, L"开");
}*/

猜你喜欢

转载自blog.csdn.net/qq_41789960/article/details/106381808
今日推荐