完成进度:
C++课程设计
游戏截图
主界面:
鼠标移到对应选项会变色:
双人模式界面:
双人模式胜利界面:
AI模式胜利界面:
附上主要的代码,完整的代码去文末GitHub里面找:
#include <graphics.h> #include <conio.h> #include <stdio.h> #include <cstring> #include <string> #include <iostream> #include <algorithm> #include <time.h> #include "chess.h" #include "Pos.h" #define mem(a,b) memset(a,b,sizeof(a)) #include <windows.h> #include <mmsystem.h> #pragma comment(lib,"winmm.lib") using namespace std; #define window_x 1013 #define window_y 800 #define inf 0x3f3f3f3f #define chess_r 49 #define debug() puts("what the fuck!!!") int MODE = 1;//模式,1代表双人,2代表单人,3代表联机 Pos map[20][20];//存储每一个棋子的坐标 int vis[20][20];//标记一个位置当前有没有落子 int color[20][20];//1代表黑棋,0代表白棋 IMAGE MAPIMAGE[30][30];//图片对象 IMAGE NowChessImage;//存储请谁落子的图 void monse() { POINT point; char s[10]; while (true) { GetCursorPos(&point); // 输出鼠标坐标 sprintf(s, _T("%d "), point.x); outtextxy(0, 0, s); sprintf(s, _T("%d "), point.y); outtextxy(0, 20, s); // 适当延时 Sleep(10); } } void chess::welcome() { mciSendString("open welcome.mp3", NULL, 0, 0); mciSendString("play welcome.mp3 repeat", NULL, 0, 0); initgraph(1024, 632);//创建一个1024*632的画布 loadimage(NULL, "welcome.jpg");//放置背景 /*mciSendString("open welcome.mp3", NULL, 0, 0); mciSendString("play welcome.mp3", NULL, 0, 0);*/ //monse(); setbkmode(TRANSPARENT);//透明字体 HWND hwnd = GetHWnd();//获取当前窗口句柄 SetWindowText(hwnd, "蒟蒻的五子棋 --- By:贺鹏程");//设置窗口标题 settextcolor(RGB(77, 77, 77)); LOGFONT f;//字体类对象 gettextstyle(&f);//获取当前字体设置 f.lfHeight = 70; strcpy_s(f.lfFaceName, "微软雅黑"); f.lfQuality = ANTIALIASED_QUALITY;//字体抗锯齿 settextstyle(&f); RECT r1 = { 500, 300, 800, 400 }; RECT r2 = { 500, 405, 800, 505 }; RECT r3 = { 500, 510, 800, 610 }; /*setlinecolor(BLACK); rectangle(500, 300, 800, 400);*/ drawtext("【双人模式】", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//文字居中,文字垂直居中,使文字显示在一行 drawtext("【单人A I】", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//文字居中,文字垂直居中,使文字显示在一行 drawtext("【联机对战】", &r3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//文字居中,文字垂直居中,使文字显示在一行 //-------------------------------------------------------------------------------------------- bool flag = true; MOUSEMSG m;//定义一个鼠标对象 while (flag) { //这个函数用于开始批量绘图。执行后,任何绘图操作都将暂时不输出到屏幕上,直到执行 FlushBatchDraw 或 EndBatchDraw 才将之前的绘图输出。 BeginBatchDraw(); m = GetMouseMsg();//获取鼠标消息 switch (m.uMsg) { case WM_LBUTTONDOWN://鼠标左键按下 EndBatchDraw(); if (m.x >= 500 && m.x <= 800 && m.y >= 300 && m.y <= 400)//判断在开始游戏的矩形区域内 { flag = false; MODE = 1; closegraph(); } else if (m.x >= 500 && m.x <= 800 && m.y >= 405 && m.y <= 505)//单人ai模式 { flag = false; MODE = 2; closegraph(); } case WM_MOUSEMOVE://监测鼠标移动 EndBatchDraw(); if (m.x >= 500 && m.x <= 800 && m.y >= 300 && m.y <= 400)//判断鼠标在开始游戏的矩形区域内 { settextcolor(RGB(254, 67, 101)); drawtext("【双人模式】", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } else if (m.x >= 500 && m.x <= 800 && m.y >= 405 && m.y <= 505) { settextcolor(RGB(254, 67, 101)); drawtext("【单人A I】", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } else if (m.x >= 500 && m.x <= 800 && m.y >= 510 && m.y <= 610) { settextcolor(RGB(254, 67, 101)); drawtext("【联机对战】", &r3, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } else { settextcolor(RGB(77, 77, 77)); drawtext("【双人模式】", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE); drawtext("【单人A I】", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE); drawtext("【联机对战】", &r3, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } //break; } } } double chess::dis(int x1, int y1, int x2, int y2)//算出两点间的距离 { return sqrt((double)((x1 - x2)*(x1 - x2)) + (double)((y1 - y2)*(y1 - y2))); } bool chess::JudgeChess(int x, int y) { //思路:以当前点为中心点,向四个方向展开搜索 if (color[x][y] == 0)//判断白棋连珠 { int num = 0;//记录棋子数量 //横向x不变 for (int i = y; i <= 15; i++)//向右 { if (color[x][i] == 0) { num++; } else break; } for (int i = y - 1; i >= 0; i--)//向左 { if (color[x][i] == 0) { num++; } else break; } if (num >= 5) return true;//横向连珠,返回结果 num = 0;//归零 //竖向y不变 for (int i = x; i <= 15; i++)//向下 { if (color[i][y] == 0) { num++; } else break; } for (int i = x - 1; i >= 0; i--)//向上 { if (color[i][y] == 0) { num++; } else break; } if (num >= 5) return true;//竖向连珠,返回结果 num = 0;//归零 //由右下斜向左上'\' for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i--, j--)//由当前点向左上 { if (color[i][j] == 0) { num++; } else break; } for (int i = x + 1, j = y + 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i++, j++)//由当前点向右下 { if (color[i][j] == 0) { num++; } else break; } if (num >= 5) return true;// '\'连珠,返回结果 num = 0;//归零 //由左下斜向右上'/' for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i--, j++)//由当前点斜向右上 { if (color[i][j] == 0) { num++; } else break; } for (int i = x + 1, j = y - 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i++, j--)//由当前点斜下左下 { if (color[i][j] == 0) { num++; } else break; } if (num >= 5) return true;// '/'连珠,返回结果 num = 0;//归零 return false;//白棋不能连珠 } else if (color[x][y] == 1)//黑棋连珠 { int num = 0;//记录棋子数量 //横向x不变 for (int i = y; i <= 15; i++)//向右 { if (color[x][i] == 1) { num++; } else break; } for (int i = y - 1; i >= 0; i--)//向左 { if (color[x][i] == 1) { num++; } else break; } if (num >= 5) return true;//横向连珠,返回结果 num = 0;//归零 //竖向y不变 for (int i = x; i <= 15; i++)//向下 { if (color[i][y] == 1) { num++; } else break; } for (int i = x - 1; i >= 0; i--)//向上 { if (color[i][y] == 1) { num++; } else break; } if (num >= 5) return true;//竖向连珠,返回结果 num = 0;//归零 //由右下斜向左上'\' for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i--, j--)//由当前点向左上 { if (color[i][j] == 1) { num++; } else break; } for (int i = x + 1, j = y + 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i++, j++)//由当前点向右下 { if (color[i][j] == 1) { num++; } else break; } if (num >= 5) return true;// '\'连珠,返回结果 num = 0;//归零 //由左下斜向右上'/' for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i--, j++)//由当前点斜向右上 { if (color[i][j] == 1) { num++; } else break; } for (int i = x + 1, j = y - 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i++, j--)//由当前点斜下左下 { if (color[i][j] == 1) { num++; } else break; } if (num >= 5) return true;// '/'连珠,返回结果 num = 0;//归零 return false;//黑棋不能连珠 } } void chess::PlayGame1() { /*---------------------------------处理背景音乐------------------------------------------------*/ mciSendString("close welcome.mp3", NULL, 0, 0); mciSendString("open palying.mp3", NULL, 0, 0); mciSendString("play palying.mp3 repeat", NULL, 0, 0); /*---------------------------------画棋盘------------------------------------------------*/ initgraph(window_x, window_y); loadimage(NULL, "4.jpg"); HWND hwnd = GetHWnd();//获取当前窗口句柄 SetWindowText(hwnd, "蒟蒻的五子棋 --- By:贺鹏程");//设置窗口标题 setlinestyle(PS_SOLID, 2); setlinecolor(BLACK); for (int x = 30; x <= 765; x += 49) { line(30, x, 765, x); } for (int y = 30; y <= 765; y += 49) { line(y, 30, y, 765); } /*---------------------------------存储棋盘坐标------------------------------------------------*/ //存储坐标 for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { map[i][j].x = 30 + 49 * j; } } for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { map[j][i].y = 30 + 49 * j; } } //画黑点 setlinecolor(BLACK); setfillcolor(BLACK); fillrectangle(map[3][3].x - 3, map[3][3].y - 3, map[3][3].x + 3, map[3][3].y + 3); fillrectangle(map[3][11].x - 3, map[3][11].y - 3, map[3][11].x + 3, map[3][11].y + 3); fillrectangle(map[7][7].x - 3, map[7][7].y - 3, map[7][7].x + 3, map[7][7].y + 3); fillrectangle(map[11][3].x - 3, map[11][3].y - 3, map[11][3].x + 3, map[11][3].y + 3); fillrectangle(map[11][11].x - 3, map[11][11].y - 3, map[11][11].x + 3, map[11][11].y + 3); //存储每一个位置的圆的图片 /*for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { getimage(&MAPIMAGE[i][j],) } }*/ /*---------------------------------游戏开始------------------------------------------------*/ mem(vis, 0);//清零标记数组 mem(color, -1);//把颜色全部设置无 bool flag = true; int opp = 0;//偶数是黑棋,奇数是白棋 MOUSEMSG m;//定义一个鼠标对象 /*setlinestyle(PS_SOLID, 1); setlinecolor(BLACK);*/ getimage(&NowChessImage, 780, 40, 1000, 100);//获取原来的图像并存储 //rectangle(780,40, 1000, 100); settextcolor(RGB(77, 77, 77)); RECT r1 = { 780,40, 1000, 100 }; LOGFONT f;//字体类对象 setbkmode(TRANSPARENT);//透明字体 gettextstyle(&f);//获取当前字体设置 f.lfHeight = 50; strcpy_s(f.lfFaceName, "微软雅黑"); f.lfQuality = ANTIALIASED_QUALITY;//字体抗锯齿 settextstyle(&f); drawtext("请黑方落子", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE); while (flag) { //这个函数用于开始批量绘图。执行后,任何绘图操作都将暂时不输出到屏幕上,直到执行 FlushBatchDraw 或 EndBatchDraw 才将之前的绘图输出。 BeginBatchDraw(); m = GetMouseMsg();//获取鼠标消息 switch (m.uMsg) { case WM_LBUTTONDOWN://鼠标左键按下 EndBatchDraw(); Pos temp; temp.x = inf, temp.y = inf; double R = 10000000.0; for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { if (dis(map[i][j].x, map[i][j].y, m.x, m.y)<R) { R = dis(map[i][j].x, map[i][j].y, m.x, m.y); temp.x = i; temp.y = j; } } } setlinecolor(BLACK); if (!vis[temp.x][temp.y])//只有没有被标记过才可以走 { vis[temp.x][temp.y] = 1; if (opp & 1)//是奇数就画白棋 { setfillcolor(WHITE); fillcircle(map[temp.x][temp.y].x, map[temp.x][temp.y].y, chess_r / 3); PlaySound(TEXT("chessmusic.wav"), 0, SND_FILENAME);//播放声音 putimage(780, 40, &NowChessImage); drawtext("请黑方落子", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE); color[temp.x][temp.y] = 0; if (JudgeChess(temp.x, temp.y) == true)//白棋可以连珠 { flag = false; GameOver1(0); } } else//偶数就画黑棋 { setfillcolor(BLACK); fillcircle(map[temp.x][temp.y].x, map[temp.x][temp.y].y, chess_r / 3); PlaySound(TEXT("chessmusic.wav"), 0, SND_FILENAME); putimage(780, 40, &NowChessImage); drawtext("请白方落子", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE); color[temp.x][temp.y] = 1;//标记颜色 if (JudgeChess(temp.x, temp.y) == true)//黑棋可以连珠 { flag = false; GameOver1(1); } } opp++;//改变状态 } //case WM_MOUSEMOVE://监测鼠标移动 // EndBatchDraw(); } } } void chess::GameOver1(int n) { settextcolor(RGB(254, 67, 101)); LOGFONT f;//字体类对象 setbkmode(TRANSPARENT);//透明字体 gettextstyle(&f);//获取当前字体设置 f.lfHeight = 120; strcpy_s(f.lfFaceName, "黑体"); f.lfQuality = ANTIALIASED_QUALITY;//字体抗锯齿 settextstyle(&f); RECT r1 = { 0, 0, 800, 800 }; RECT r2 = { 790, 710, 980, 760 }; RECT r3 = { 780,40, 1000, 100 }; setlinecolor(BLACK); if (n == 0) { drawtext("白 棋 获 胜", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//文字居中,文字垂直居中,使文字显示在一行 } else if (n == 1) { drawtext("黑 棋 获 胜", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//文字居中,文字垂直居中,使文字显示在一行 } gettextstyle(&f);//获取当前字体设置 f.lfHeight = 50; strcpy_s(f.lfFaceName, "微软雅黑"); f.lfQuality = ANTIALIASED_QUALITY;//字体抗锯齿 settextstyle(&f); putimage(780, 40, &NowChessImage); drawtext("游戏结束", &r3, DT_CENTER | DT_VCENTER | DT_SINGLELINE); //设置矩形 setlinestyle(PS_SOLID, 1); setlinecolor(BLACK); rectangle(790, 710, 980, 760);//画重新开始的矩形边框 setbkmode(TRANSPARENT);//透明字体 gettextstyle(&f);//获取当前字体设置 f.lfHeight = 50; strcpy_s(f.lfFaceName, "微软雅黑"); f.lfQuality = ANTIALIASED_QUALITY;//字体抗锯齿 settextstyle(&f); settextcolor(RGB(77, 77, 77)); drawtext("重新开始", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE); bool flag = true; MOUSEMSG m;//定义一个鼠标对象 while (flag) { //这个函数用于开始批量绘图。执行后,任何绘图操作都将暂时不输出到屏幕上,直到执行 FlushBatchDraw 或 EndBatchDraw 才将之前的绘图输出。 BeginBatchDraw(); m = GetMouseMsg();//获取鼠标消息 switch (m.uMsg) { case WM_LBUTTONDOWN://鼠标左键按下 EndBatchDraw(); if (m.x >= 790 && m.x <= 980 && m.y >= 710 && m.y <= 760)//判断在开始游戏的矩形区域内 { flag = false; //*********************************************** PlayGame1();//重新开始游戏 } //break; case WM_MOUSEMOVE://监测鼠标移动 EndBatchDraw(); if (m.x >= 790 && m.x <= 980 && m.y >= 710 && m.y <= 760)//判断鼠标在开始游戏的矩形区域内 { settextcolor(RGB(254, 67, 101)); drawtext("重新开始", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } else { settextcolor(RGB(77, 77, 77)); drawtext("重新开始", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } //break; } } } void chess::PlayGame2() { /*---------------------------------处理背景音乐------------------------------------------------*/ mciSendString("close welcome.mp3", NULL, 0, 0); mciSendString("open palying.mp3", NULL, 0, 0); mciSendString("play palying.mp3 repeat", NULL, 0, 0); /*---------------------------------画棋盘------------------------------------------------*/ initgraph(window_x, window_y); loadimage(NULL, "4.jpg"); HWND hwnd = GetHWnd();//获取当前窗口句柄 SetWindowText(hwnd, "蒟蒻的五子棋 --- By:贺鹏程");//设置窗口标题 setlinestyle(PS_SOLID, 2); setlinecolor(BLACK); for (int x = 30; x <= 765; x += 49) { line(30, x, 765, x); } for (int y = 30; y <= 765; y += 49) { line(y, 30, y, 765); } /*---------------------------------存储棋盘坐标------------------------------------------------*/ //存储坐标 for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { map[i][j].x = 30 + 49 * j; } } for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { map[j][i].y = 30 + 49 * j; } } //画黑点 setlinecolor(BLACK); setfillcolor(BLACK); fillrectangle(map[3][3].x - 3, map[3][3].y - 3, map[3][3].x + 3, map[3][3].y + 3); fillrectangle(map[3][11].x - 3, map[3][11].y - 3, map[3][11].x + 3, map[3][11].y + 3); fillrectangle(map[7][7].x - 3, map[7][7].y - 3, map[7][7].x + 3, map[7][7].y + 3); fillrectangle(map[11][3].x - 3, map[11][3].y - 3, map[11][3].x + 3, map[11][3].y + 3); fillrectangle(map[11][11].x - 3, map[11][11].y - 3, map[11][11].x + 3, map[11][11].y + 3); //存储每一个位置的圆的图片 /*---------------------------------游戏开始------------------------------------------------*/ mem(vis, 0);//清零标记数组 mem(color, -1);//把颜色全部设置无 bool flag = true; int opp = 0;//偶数是黑棋,奇数是白棋 MOUSEMSG m;//定义一个鼠标对象 getimage(&NowChessImage, 780, 40, 1000, 100);//获取原来的图像并存储 settextcolor(RGB(77, 77, 77)); RECT r1 = { 780,40, 1000, 100 }; LOGFONT f;//字体类对象 setbkmode(TRANSPARENT);//透明字体 gettextstyle(&f);//获取当前字体设置 f.lfHeight = 50; strcpy_s(f.lfFaceName, "微软雅黑"); settextstyle(&f); drawtext("请黑方落子", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE); while (flag) { //这个函数用于开始批量绘图。执行后,任何绘图操作都将暂时不输出到屏幕上,直到执行 FlushBatchDraw 或 EndBatchDraw 才将之前的绘图输出。 BeginBatchDraw(); m = GetMouseMsg();//获取鼠标消息 switch (m.uMsg) { case WM_LBUTTONDOWN://鼠标左键按下 EndBatchDraw(); Pos temp; temp.x = inf, temp.y = inf; double R = 10000000.0; for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { if (dis(map[i][j].x, map[i][j].y, m.x, m.y)<R) { R = dis(map[i][j].x, map[i][j].y, m.x, m.y); temp.x = i; temp.y = j; } } } setlinecolor(BLACK); int black_go = 0; if (!vis[temp.x][temp.y])//只有没有被标记过才可以走 { vis[temp.x][temp.y] = 1; black_go = 1; //////////////////////画黑棋////////////////////////// setfillcolor(BLACK); fillcircle(map[temp.x][temp.y].x, map[temp.x][temp.y].y, chess_r / 3); PlaySound(TEXT("chessmusic.wav"), 0, SND_FILENAME); putimage(780, 40, &NowChessImage); drawtext("请白方落子", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE); color[temp.x][temp.y] = 1;//标记颜色 if (JudgeChess(temp.x, temp.y) == true)//黑棋可以连珠 { flag = false; GameOver2(1); break; } } ///////////////////////////////画白棋////////////////////////////////// Pos PointWhite = GetAddress(); if (!vis[PointWhite.x][PointWhite.y] && black_go == 1) { vis[PointWhite.x][PointWhite.y] = 1; setfillcolor(WHITE); //MessageBox(NULL, to_string(PointWhite.y).c_str(), "Title(标题)", MB_OK); fillcircle(map[PointWhite.x][PointWhite.y].x, map[PointWhite.x][PointWhite.y].y, chess_r / 3); PlaySound(TEXT("chessmusic.wav"), 0, SND_FILENAME);//播放声音 putimage(780, 40, &NowChessImage); drawtext("请黑方落子", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE); color[PointWhite.x][PointWhite.y] = 0; if (JudgeChess(PointWhite.x, PointWhite.y) == true)//白棋可以连珠 { flag = false; GameOver2(0); break; } } } } } void chess::GameOver2(int n) { settextcolor(RGB(254, 67, 101)); LOGFONT f;//字体类对象 setbkmode(TRANSPARENT);//透明字体 gettextstyle(&f);//获取当前字体设置 f.lfHeight = 120; strcpy_s(f.lfFaceName, "黑体"); f.lfQuality = ANTIALIASED_QUALITY;//字体抗锯齿 settextstyle(&f); RECT r1 = { 0, 0, 800, 800 }; RECT r2 = { 790, 710, 980, 760 }; RECT r3 = { 780,40, 1000, 100 }; setlinecolor(BLACK); if (n == 0) { drawtext("电 脑 获 胜", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//文字居中,文字垂直居中,使文字显示在一行 } else if (n == 1) { drawtext("玩 家 获 胜", &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//文字居中,文字垂直居中,使文字显示在一行 } gettextstyle(&f);//获取当前字体设置 f.lfHeight = 50; strcpy_s(f.lfFaceName, "微软雅黑"); f.lfQuality = ANTIALIASED_QUALITY;//字体抗锯齿 settextstyle(&f); putimage(780, 40, &NowChessImage); drawtext("游戏结束", &r3, DT_CENTER | DT_VCENTER | DT_SINGLELINE); //设置矩形 setlinestyle(PS_SOLID, 1); setlinecolor(BLACK); rectangle(790, 710, 980, 760);//画重新开始的矩形边框 setbkmode(TRANSPARENT);//透明字体 gettextstyle(&f);//获取当前字体设置 f.lfHeight = 50; strcpy_s(f.lfFaceName, "微软雅黑"); f.lfQuality = ANTIALIASED_QUALITY;//字体抗锯齿 settextstyle(&f); settextcolor(RGB(77, 77, 77)); drawtext("重新开始", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE); bool flag = true; MOUSEMSG m;//定义一个鼠标对象 while (flag) { //这个函数用于开始批量绘图。执行后,任何绘图操作都将暂时不输出到屏幕上,直到执行 FlushBatchDraw 或 EndBatchDraw 才将之前的绘图输出。 BeginBatchDraw(); m = GetMouseMsg();//获取鼠标消息 switch (m.uMsg) { case WM_LBUTTONDOWN://鼠标左键按下 EndBatchDraw(); if (m.x >= 790 && m.x <= 980 && m.y >= 710 && m.y <= 760)//判断在开始游戏的矩形区域内 { flag = false; //*********************************************** PlayGame2();//重新开始游戏 } //break; case WM_MOUSEMOVE://监测鼠标移动 EndBatchDraw(); if (m.x >= 790 && m.x <= 980 && m.y >= 710 && m.y <= 760)//判断鼠标在开始游戏的矩形区域内 { settextcolor(RGB(254, 67, 101)); drawtext("重新开始", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } else { settextcolor(RGB(77, 77, 77)); drawtext("重新开始", &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } //break; } } } Pos chess::GetAddress()//传进来当前落子的坐标 { Pos now; int choose_score = 1;//判分,如果需要防守此值为0,要进攻为1 //白棋防守,判断黑棋最多能连成几个棋子,然后进行封堵 int flag = 1;//判断是否跳出循环 for (int x = 0; x <= 15 && flag; x++) { for (int y = 0; y <= 15 && flag; y++) { if (color[x][y] == 1 && flag)//如果当前棋子的颜色为黑色 { int num = 0;//记录连续黑色棋子数量 //横向x不变 for (int i = y; i <= 15; i++)//向右 { if (color[x][i] == 1) { num++; } else break; } for (int i = y - 1; i >= 0; i--)//向左 { if (color[x][i] == 1) { num++; } else break; } if (num >= 3)//如果横向已经连成三个 { choose_score = 0; int flog = 1;//区分是否已找到 for (int i = y; i <= 15 && flog; i++)//向右 { if (color[x][i] == -1) { flog = 0; now.x = x; now.y = i; } } for (int i = y - 1; i >= 0 && flog; i--)//向左 { if (color[x][i] == -1) { flog = 0; now.x = x; now.y = i; } } flag = 0; break; } num = 0; //竖向y不变 for (int i = x; i <= 15; i++)//向下 { if (color[i][y] == 1) { num++; } else break; } for (int i = x - 1; i >= 0; i--)//向上 { if (color[i][y] == 1) { num++; } else break; } if (num >= 3)//如果竖向已经连成三个 { choose_score = 0; int flog = 1; for (int i = x; i <= 15 && flog; i++)//向下 { if (color[i][y] == -1) { flog = 0; now.x = i; now.y = y; } } for (int i = x - 1; i >= 0 && flog; i--)//向上 { if (color[i][y] == 1) { flog = 0; now.x = i; now.y = y; } } flag = 0; break; } num = 0; //由右下斜向左上'\' for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i--, j--)//由当前点向左上 { if (color[i][j] == 1) { num++; } else break; } for (int i = x + 1, j = y + 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i++, j++)//由当前点向右下 { if (color[i][j] == 1) { num++; } else break; } if (num >= 3)//如果'\'已经连成三个 { choose_score = 0; int flog = 1; for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15) && flog; i--, j--)//由当前点向左上 { if (color[i][j] == -1) { flog = 0; now.x = i; now.y = j; } } for (int i = x + 1, j = y + 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15) && flog; i++, j++)//由当前点向右下 { if (color[i][j] == -1) { flog = 0; now.x = i; now.y = j; } } flag = 0; break; } num = 0; //由左下斜向右上'/' for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i--, j++)//由当前点斜向右上 { if (color[i][j] == 1) { num++; } else break; } for (int i = x + 1, j = y - 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i++, j--)//由当前点斜下左下 { if (color[i][j] == 1) { num++; } else break; } if (num >= 3)//如果已经连成三个 { choose_score = 0; int flog = 1; for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15) && flog; i--, j++)//由当前点斜向右上 { if (color[i][j] == -1) { flog = 0; now.x = i; now.y = j; } } for (int i = x + 1, j = y - 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15) && flog; i++, j--)//由当前点斜下左下 { if (color[i][j] == -1) { flog = 0; now.x = i; now.y = j; } } flag = 0; break; } num = 0; } } } //白棋进攻,找到对自己最有利的,判断当前白棋最多能连几个棋子 int maxx = 0; if (choose_score) { for (int x = 0; x <= 15; x++) { for (int y = 0; y <= 15; y++) { if (color[x][y] == -1)//这一点可以落子 { int num = 0;//记录棋子数量 int max_num = 0; //横向x不变 for (int i = y; i <= 15; i++)//向右 { if (color[x][i] == 0) { num++; } else break; } for (int i = y - 1; i >= 0; i--)//向左 { if (color[x][i] == 0) { num++; } else break; } max_num = max(max_num, num); num = 0; //竖向y不变 for (int i = x; i <= 15; i++)//向下 { if (color[i][y] == 0) { num++; } else break; } for (int i = x - 1; i >= 0; i--)//向上 { if (color[i][y] == 0) { num++; } else break; } max_num = max(max_num, num); num = 0; //由右下斜向左上'\' for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i--, j--)//由当前点向左上 { if (color[i][j] == 0) { num++; } else break; } for (int i = x + 1, j = y + 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i++, j++)//由当前点向右下 { if (color[i][j] == 0) { num++; } else break; } max_num = max(max_num, num); num = 0; //由左下斜向右上'/' for (int i = x, j = y; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i--, j++)//由当前点斜向右上 { if (color[i][j] == 0) { num++; } else break; } for (int i = x + 1, j = y - 1; (i >= 0 && i <= 15 && j >= 0 && j <= 15); i++, j--)//由当前点斜下左下 { if (color[i][j] == 0) { num++; } else break; } max_num = max(max_num, num); num = 0; if (maxx <= max_num) { maxx = max_num; now.x = x; now.y = y; } } } } } //MessageBox(NULL, to_string(now.x).c_str(), "Title(标题)", MB_OK); return now; } int main() { chess fivech; fivech.welcome();//欢迎界面 if (MODE == 1)//双人模式 { fivech.PlayGame1(); } else if (MODE == 2)//单人ai { fivech.PlayGame2(); } getch(); closegraph(); return 0; }
在这里附上编译好的下载地址:
云盘下载 密码:x1ao
项目源码在GitHub上:https://github.com/riba2534/Ink-FiveChess
欢迎fork…..(不过还是等写完吧,代码不忍直视~~~)
虽然没人看,自己沙发一下
不不不,还是有人看的
还是很厉害的
%%%很强大
超级喜欢万代传承
挺好听的