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