日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

五子棋GUI_C++

發(fā)布時間:2024/3/24 c/c++ 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 五子棋GUI_C++ 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

五子棋游戲人機對戰(zhàn) C/C++ (圖形界面)

準備:找好游戲圖片、音樂等基本素材。另外,代碼中的圖片尺寸數(shù)據(jù)根據(jù)各自的實際素材調(diào)整。
注:本人的素材均不做盈利用,不涉及版權(quán)。
tools文件是從相關(guān)網(wǎng)站學(xué)習(xí)課程上獲得的,此處對相關(guān)內(nèi)容不做明示。可以告知的是tools做的工作是使PNG圖片背景透明。
tools.h

主函數(shù):

#define _CRT_SECURE_NO_WARNINGS 1 /* * 設(shè)計一個人機交互程序——五子棋 也可參考設(shè)計軍棋、跳棋、圍棋、象棋 */ #include "ChessData.h"int main() { //_wuziqi2board_Init();//主要功能區(qū)while (1) { //~while(true) C/C++最好用while(1)MOUSEMSG msg = GetMouseMsg(); //獲取光標信息 如果報錯4996,項目名右鍵->屬性->c/c++->sdl檢查選否if (msg.uMsg == WM_LBUTTONDOWN && clickBoard(msg)) { //鼠標左鍵點擊落子 且是有效點擊man_Go();if (checkOver()) {board_Init();continue;}AI_Go();if (checkOver()) {board_Init();continue;}}}closegraph();system("pause");return 0; }

“ChessData.h”文件內(nèi)容:(需要graphics.h)
說明:AI走子算法是關(guān)鍵。

#pragma once #include <stdlib.h> #include <windows.h> #include "tools.h" //外部寫的頭文件 #include <mmsystem.h> //音樂播放 #pragma comment (lib, "winmm.lib") //表示接入winmm.lib靜態(tài)鏈接庫,和在工程設(shè)置中寫上鏈入winmm.lib的效果相同const float BLOCK_SIZE = 50.4; //const float BLOCK_SIZE = 50.4; //25.2 const int BOARD_GRADE_SIZE = 13; const int POS_OFFSET = BLOCK_SIZE * 0.4; //位置模糊,一定要小于0.5 const int margin_x = 32; const int margin_y = 31;typedef enum {CHESS_WHITE = -1,CHESS_BLACK = 1 } chess_kind_t;struct ChessData {//0:空白 1:黑子 -1:白子int chessMap[BOARD_GRADE_SIZE][BOARD_GRADE_SIZE]; //使用宏,好//各個落子點評分int scoreMap[BOARD_GRADE_SIZE][BOARD_GRADE_SIZE];//輪流下棋,true黑方,flase白方bool playerFlag; };typedef struct point {int row;int col; }point_t;void board_Init(); //棋盤初始化 void initChessData(struct ChessData* data);bool clickBoard(MOUSEMSG msg); //判斷有效點擊 void chessDown(int row, int col, chess_kind_t kind); void updateGameMap(ChessData* data, int row, int col);bool checkWin(ChessData* game, int row, int col); //row和col表示當(dāng)前落子 bool checkOver(); void man_Go(); void caculateScore(ChessData* data); point_t action_AI(ChessData* data); //機器執(zhí)行下棋 void AI_Go();

“ChessData.cpp”文件內(nèi)容:

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h> //NULL #include <math.h> //sqrt #include <string.h> #include <memory.h> //memset //string.h #include <conio.h> //getch #include <time.h> #include "ChessData.h"//加載圖片到內(nèi)存,提高效率 IMAGE chessBlackImg; //黑白子需要不斷輸出 IMAGE chessWhiteImg; int clickPosRow, clickPosCol; //表示有效點擊的實際位置(行列) struct ChessData game;void initChessData(struct ChessData* data) {if (!data) { //data == NULLreturn;}memset(data->chessMap, 0, sizeof(data->chessMap)); //比雙重for更高級memset(data->scoreMap, 0, sizeof(data->scoreMap));data->playerFlag = true; } void board_Init() {initgraph(673, 672); //根據(jù)圖片尺寸確定loadimage(0, "res/棋盤.jpg"); //加載報錯時,項目名右鍵->屬性->高級->字符集選擇多字節(jié)字符集//添加對戰(zhàn)開始背景音mciSendString("play res/start.wav", 0, 0, 0); //可以添加背景音樂,mciSendString("play 背景音樂 repeat", 0, 0, 0);loadimage(&chessBlackImg, "res/black.png", BLOCK_SIZE, BLOCK_SIZE, true); //圖片太大時true等比縮放loadimage(&chessWhiteImg, "res/white.png", BLOCK_SIZE, BLOCK_SIZE, true);initChessData(&game); }bool clickBoard(MOUSEMSG msg) {//上下邊界 x32 y31,定義在ChessData.h中int col = (msg.x - margin_x) / BLOCK_SIZE;int row = (msg.y - margin_y) / BLOCK_SIZE;int leftTopPosX = margin_x + col * BLOCK_SIZE;int leftTopPosY = margin_y + row * BLOCK_SIZE;int selectPos = false;do {//左上角int len = sqrt((msg.x - leftTopPosX) * (msg.x - leftTopPosX) +(msg.y - leftTopPosY) * (msg.y - leftTopPosY));if (len < POS_OFFSET) {clickPosRow = row;clickPosCol = col;selectPos = true;break;}//右上角 leftTopPosX+BLOCK_SIZE leftTopPosY,其余同理len = sqrt((msg.x - (leftTopPosX + BLOCK_SIZE)) * (msg.x - (leftTopPosX + BLOCK_SIZE)) +(msg.y - leftTopPosY) * (msg.y - leftTopPosY));if (len < POS_OFFSET) {clickPosRow = row;clickPosCol = col + 1;selectPos = true;break;}//右下角len = sqrt((msg.x - (leftTopPosX + BLOCK_SIZE)) * (msg.x - (leftTopPosX + BLOCK_SIZE)) +(msg.y - (leftTopPosY + BLOCK_SIZE)) * (msg.y - (leftTopPosY + BLOCK_SIZE)));if (len < POS_OFFSET) {clickPosRow = row + 1;clickPosCol = col + 1;selectPos = true;break;}//左下角len = sqrt((msg.x - leftTopPosX) * (msg.x - leftTopPosX) +(msg.y - (leftTopPosY + BLOCK_SIZE)) * (msg.y - (leftTopPosY + BLOCK_SIZE)));if (len < POS_OFFSET) {clickPosRow = row + 1;clickPosCol = col;selectPos = true;break;}} while (0); //只循環(huán)一次,關(guān)鍵作用是break避免使用returnreturn selectPos; } void chessDown(int row, int col, chess_kind_t kind) {mciSendString("play res/down7.WAV", 0, 0, 0);int x = margin_x + clickPosCol * BLOCK_SIZE - 0.5 * BLOCK_SIZE;int y = margin_y + clickPosRow * BLOCK_SIZE - 0.5 * BLOCK_SIZE;if (kind == CHESS_BLACK) {//putimage(msg.x, msg.y, &chessBlackImg); //在鼠標點擊處放圖片,從左上角開始鋪圖drawPNG(x, y, &chessBlackImg); //tools.h中的函數(shù)//還需要模糊算法處理擺正位置,模塊化,clickBoard}else {drawPNG(x, y, &chessWhiteImg);} } void updateGameMap(ChessData* data, int row, int col) {if (!data) {return;}if (data->playerFlag) {data->chessMap[row][col] = 1;}else {data->chessMap[row][col] = -1;}data->playerFlag = !data->playerFlag; //換手 }bool checkWin(ChessData* game, int row, int col) {//8個方向,本質(zhì)是4個方向只要有5連就算贏int i;//水平for (i = 0; i < 5; i++) {//左、右各匹配if (col - i >= 0 &&col - i + 4 < BOARD_GRADE_SIZE &&game->chessMap[row][col - i] == game->chessMap[row][col - i + 1] &&game->chessMap[row][col - i] == game->chessMap[row][col - i + 2] &&game->chessMap[row][col - i] == game->chessMap[row][col - i + 3] &&game->chessMap[row][col - i] == game->chessMap[row][col - i + 4] ) {return true;}}//豎直for (i = 0; i < 5; i++) {if (row - i >= 0 &&row - i + 4 < BOARD_GRADE_SIZE &&game->chessMap[row - i][col] == game->chessMap[row - i + 1][col] &&game->chessMap[row - i][col] == game->chessMap[row - i + 2][col] &&game->chessMap[row - i][col] == game->chessMap[row - i + 3][col] &&game->chessMap[row - i][col] == game->chessMap[row - i + 4][col] ){return true;}}// '/'for (i = 0; i < 5; i++) {if (row + i < BOARD_GRADE_SIZE &&row + i - 4 >= 0 &&col - i >= 0 &&col - i + 4 < BOARD_GRADE_SIZE &&//第[row+i]行,第[col-i]列的棋子,與右上方連續(xù)4子相同game->chessMap[row + i][col - i] == game->chessMap[row + i - 1][col - i + 1] &&game->chessMap[row + i][col - i] == game->chessMap[row + i - 2][col - i + 2] &&game->chessMap[row + i][col - i] == game->chessMap[row + i - 3][col - i + 3] &&game->chessMap[row + i][col - i] == game->chessMap[row + i - 4][col - i + 4] ){return true;}}// '\'for (i = 0; i < 5; i++) {if (row - i >= 0 &&row - i + 4 < BOARD_GRADE_SIZE &&col - i >= 0 &&col - i + 4 < BOARD_GRADE_SIZE &&//第[row-i]行,第[col-i]列的棋子,與右下方連續(xù)4子相同game->chessMap[row - i][col - i] == game->chessMap[row - i + 1][col - i + 1] &&game->chessMap[row - i][col - i] == game->chessMap[row - i + 2][col - i + 2] &&game->chessMap[row - i][col - i] == game->chessMap[row - i + 3][col - i + 3] &&game->chessMap[row - i][col - i] == game->chessMap[row - i + 4][col - i + 4] ){return true;}}return false; } bool checkOver() {if (checkWin(&game, clickPosRow, clickPosCol)) {//Sleep(1500);if (game.playerFlag == false) {mciSendString("play res/不錯.mp3", 0, 0, 0);loadimage(0, "res/勝利.jpg");}else {mciSendString("play res/失敗.mp3", 0, 0, 0);loadimage(0, "res/失敗.jpg");}getch();return true;}return false; }void man_Go() {chessDown(clickPosRow, clickPosCol, CHESS_BLACK);updateGameMap(&game, clickPosRow, clickPosCol); }//*************************系統(tǒng)評分函數(shù),是關(guān)鍵******************************* /* * 黑子 白子(連1/普通~~~5) * 連2 10 10 * 死3 30 25 * 活3 40 50 * 死4 60 55 * 活4 200 300 * 連5 20000 30000 */ void caculateScore(ChessData* data) {if (!data) {return;}int row, col, i, k;//統(tǒng)計玩家或電腦連子個數(shù)int man_Num = 0; //玩家連子個數(shù)int AI_Num = 0; //AI連子個數(shù)int emptyNum = 0; //空白位個數(shù)//清空評分數(shù)組memset(data->scoreMap, 0, sizeof(data->scoreMap));for (row = 0; row < BOARD_GRADE_SIZE; row++) {for (col = 0; col < BOARD_GRADE_SIZE; col++) {//空白點就算if (row >= 0 && col >= 0 && data->chessMap[row][col] == 0) {//遍歷周圍4個方向,考慮正反int direction[4][2] = { {1,0}, {1,1}, {0,1}, {-1,1} }; //for (k = 0; k < 4; k++) {int x = direction[k][0];int y = direction[k][1]; ////重置man_Num = 0;AI_Num = 0;emptyNum = 0;//黑方正向計數(shù)for (i = 1; i <= 4; i++) {if (row + i * y >= 0 &&row + i * y < BOARD_GRADE_SIZE &&col + i * x >= 0 &&col + i * x < BOARD_GRADE_SIZE &&data->chessMap[row + i * y][col + i * x] == 1){man_Num++;}else if (row + i * y >= 0 &&row + i * y < BOARD_GRADE_SIZE &&col + i * x >= 0 &&col + i * x < BOARD_GRADE_SIZE &&data->chessMap[row + i * y][col + i * x] == 0){emptyNum++;break; //遇到空白位,停止搜索}else { //出邊界或者遇到白棋,停止搜索break;}}//黑反for (i = 1; i <= 4; i++) {if (row - i * y >= 0 &&row - i * y < BOARD_GRADE_SIZE &&col - i * x >= 0 &&col - i * x < BOARD_GRADE_SIZE &&data->chessMap[row - i * y][col - i * x] == 1){man_Num++;}else if (row - i * y >= 0 &&row - i * y < BOARD_GRADE_SIZE &&col - i * x >= 0 &&col - i * x < BOARD_GRADE_SIZE &&data->chessMap[row - i * y][col - i * x] == 0){emptyNum++;break; //遇到空白位,停止搜索}else { //出邊界或者遇到白棋,停止搜索break;}}//黑,數(shù)->分 //elseif elseif (man_Num == 1) { //殺2data->scoreMap[row][col] += 10;}else if (man_Num == 2) { //殺3if (emptyNum == 1) { //死3data->scoreMap[row][col] += 30;}else if (emptyNum == 2) { //活3data->scoreMap[row][col] += 40;}}else if (man_Num == 3) { //殺4if (emptyNum == 1) {data->scoreMap[row][col] += 60;}else if (emptyNum == 2) {data->scoreMap[row][col] += 200;}}else if (man_Num == 4) { //殺5data->scoreMap[row][col] += 20000;}//進行一次清空emptyNum = 0;//對白棋評分for (i = 1; i <= 4; i++) { //正if (row + i * y > 0 &&row + i * y < BOARD_GRADE_SIZE &&col + i * x > 0 &&col + i * x < BOARD_GRADE_SIZE &&data->chessMap[row + i * y][col + i * x] == -1){AI_Num++;}else if (row + i * y > 0 &&row + i * y < BOARD_GRADE_SIZE &&col + i * x > 0 &&col + i * x < BOARD_GRADE_SIZE &&data->chessMap[row + i * y][col + i * x] == 0){emptyNum++;break;}else {break;}}for (i = 1; i <= 4; i++) { //反if (row - i * y > 0 &&row - i * y < BOARD_GRADE_SIZE &&col - i * x > 0 &&col - i * x < BOARD_GRADE_SIZE &&data->chessMap[row - i * y][col - i * x] == -1){AI_Num++;}else if (row - i * y > 0 &&row - i * y < BOARD_GRADE_SIZE &&col - i * x > 0 &&col - i * x < BOARD_GRADE_SIZE &&data->chessMap[row - i * y][col - i * x] == 0) //空白位{emptyNum++;break;}else { //出邊界break;}}if (AI_Num == 0) { //普通下子data->scoreMap[row][col] += 5;}else if (AI_Num == 1) { //活2data->scoreMap[row][col] += 10;}else if (AI_Num == 2) {if (emptyNum == 1) {data->scoreMap[row][col] += 25;}else if (emptyNum == 2) {data->scoreMap[row][col] += 50;}}else if (AI_Num == 3) {if (emptyNum == 1) {data->scoreMap[row][col] += 55;}else if (emptyNum == 2) {data->scoreMap[row][col] += 300;}}else if (AI_Num >= 4) {data->scoreMap[row][col] += 30000;}}}}} }point_t action_AI(ChessData* data) {caculateScore(data);int maxScore = 0;//std::vector<std::pair<int, int>>maxPoints;point_t maxPoints[BOARD_GRADE_SIZE * BOARD_GRADE_SIZE] = { 0, };int k = 0;for (int row = 0; row < BOARD_GRADE_SIZE; row++) { //面向?qū)ο笳Z言for (int col = 0; col < BOARD_GRADE_SIZE; col++) {//前提是坐標為空if (data->chessMap[row][col] == 0) {if (data->scoreMap[row][col] > maxScore) {//maxPoints.clear();memset(maxPoints, 0, sizeof(maxPoints));k = 0;maxScore = data->scoreMap[row][col];//maxPoints.push_back(std::make_pair(row, col));maxPoints[k].row = row;maxPoints[k].col = col;k++;}else if (data->scoreMap[row][col] == maxScore) {//maxPoints.push_back(std::make_pair(row, col));maxPoints[k].row = row;maxPoints[k].col = col;k++;}}}}srand((unsigned)time(0));int index = rand() % k;return maxPoints[index]; } void AI_Go() {point_t point = action_AI(&game);clickPosRow = point.row;clickPosCol = point.col;//Sleep(1000);chessDown(clickPosRow, clickPosCol, CHESS_WHITE);updateGameMap(&game, clickPosRow, clickPosCol); }

附結(jié)果圖:

補充:已發(fā)現(xiàn)的漏洞有黑子可覆蓋白子,需要在玩家走子函數(shù)中添加判斷條件。

總結(jié)

以上是生活随笔為你收集整理的五子棋GUI_C++的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 伊人22综合 | 亚洲精品日韩精品 | 严厉高冷老师动漫播放 | 人人操天天射 | 91视频在线观看网站 | 男男黄色片 | 秋霞福利片 | 欧美日韩aaa | 色欲欲www成人网站 老色鬼av | 国产老女人乱淫免费可以 | 极品销魂美女一区二区三区 | 亚洲成人一区在线观看 | 中文在线第一页 | 亚洲av无码乱码在线观看性色 | 精品人妻午夜一区二区三区四区 | 日本人xxxⅹ18hd19hd | 国产三级在线观看视频 | 成全影视在线观看第8季 | 91视频h | 黄瓜视频在线播放 | 欧美日韩一区二区在线视频 | 影音先锋成人资源网站 | 久久综合九色综合欧美狠狠 | 久操福利在线 | 不卡影院av | 欧美日本久久 | aise爱色av| 亚洲av无码乱码国产精品 | 蜜桃视频导航 | 日韩欧美精品一区 | www.狠狠艹 | 911久久| 激情欧美一区二区免费视频 | 亚洲一区二区三区高清 | 午夜影院色| 亚洲人妖在线 | 91综合在线 | 男人天堂一区二区 | 久久久久一区二区三区四区 | 国产一区二区99 | 国产一区二区三区四区三区四 | 古装做爰无遮挡三级 | 国产精品玖玖玖 | 国产美女视频 | 噜噜噜亚洲色成人网站 | 欧美激情精品久久久久久免费 | 深夜免费在线视频 | 久久91久久| 538在线精品| 观看毛片 | 不许穿内裤随时挨c调教h苏绵 | 可以免费观看的毛片 | 永久av| 午夜h | 精品人妻一区二区三区蜜桃视频 | 久久9966 | 免费观看日韩毛片 | 亚洲色图欧美在线 | 国产精品伦理一区二区 | 国产色婷婷一区二区三区竹菊影视 | 色妞色视频一区二区三区四区 | 成人黄色片免费 | 网站免费黄色 | 91精品黄色 | 亚洲网站免费看 | 成人精品一区二区三区电影 | 国产伦精品一区三区精东 | 韩国19主播内部福利vip | www三级 | 99色在线视频 | www欧美精品 | 337p亚洲精品色噜噜噜 | 爽爽窝窝午夜精品一区二区 | 91国模| 免费伊人网| 碰碰久久 | 97人妻人人澡人人爽人人精品 | 萌白酱喷水视频 | 国产日韩欧美一区二区东京热 | 欧美成人图区 | 亚洲爱视频 | 久久免费高清视频 | 99热99在线 | 中文字幕在线免费看线人 | 好吊妞视频在线观看 | 人妖天堂狠狠ts人妖天堂狠狠 | 丁香六月啪啪 | 色偷偷人人澡人人爽人人模 | aaaa级片| 亚洲第一在线播放 | 蜜桃av一区二区三区 | 少妇自摸视频 | 成人国产精品视频 | 国产一二在线 | 色婷婷在线视频 | 欧洲黄色片 | 国产一区两区 | 欧美大黄视频 | 9l视频自拍蝌蚪9l视频成人 |