C++ 中国象棋 C++ 中国象棋的实现流程详解
MAX在码字 人气:2想了解C++ 中国象棋的实现流程详解的相关内容吗,MAX在码字在本文为您仔细讲解C++ 中国象棋的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:C++,中国象棋,C++,象棋,下面大家一起来学习吧。
中国象棋的中国棋文化,也是中华民族的文化瑰宝,它源远流长,趣味浓厚,基本规则简明易懂。中国象棋在中国的群众中基础远远超过围棋,是普及最广的棋类项目,中国象棋已流传到十几个国家和地区。 中国象棋使用方形格状棋盘,圆形棋子共有32个,红黑二色各有16个棋子,摆放和活动在交叉点上。双方交替行棋,先把对方的将(帅)“将死”的一方获胜。
我们今天就来看看我们自己能不能写出这样一个游戏呢?
今天就不话不多说了,先说一下,今天我们做的是一个简易版的单机中国象棋,希望大家理解,联网对弈的话需要用到的知识过多,数据库以及网络协议这些大部分同学都没有学,所以我们今天就简单的实现《中国象棋》的简单对弈,主要是希望同学们可以理解其中的逻辑关系,之后就可以更好的去完善
行吧,我们现在就开始吧!!!
今天先出场的就不是我们的老朋友结构体了,而是我们的新朋友枚举类型
enum Pieces //棋子 { NONE = -1, 車, 馬, 象, 士, 将, 砲, 卒, 俥, 马, 相, 仕, 帥, 炮, 兵, BEGIN, END, }; //给id赋值 enum Pieces redChess[] = { 車, 馬, 象, 士, 将, 砲, 卒 }; enum Pieces blackChess[] = { 俥, 马, 相, 仕, 帥, 炮, 兵 }; //绘制时转化成字符串 const char* ChessName[] = { "車","馬","象","士","将","砲","卒","俥", "马", "相", "仕", "帥", "炮", "兵" };
接下来出场的是我们的老朋友结构体
//每一个棋子的属性 struct Chess { enum Pieces id; //棋子名称 DWORD type; //棋子类型,红?黑? short x; short y; bool isRiver; //是否过了河 }; //游戏地图 struct Chess map[ROW][COL]; struct State { int begr; int begc; int endr; int endc; int state; }state = {-1,-1,-1,-1,BEGIN};
我们的初始化函数,一定要想好其中的逻辑
//初始化数据 void init() { //遍历地图 for (size_t i = 0; i < ROW; i++) { size_t temp = 0; for (size_t k = 0; k < COL; k++) { map[i][k].id = NONE; //先把棋子置为没有 if (i <= 4) //黑棋子 { map[i][k].type = BLACK; if (i == 0) //放置第一行的棋子 { //0 1 2 3 4 if (k <= 4) { temp = k; } // 3 2 1 0 else { // k == 5 temp = 4 - (k - 4); /* 4 - (5-4) //3 4 - (6-4) //2 4 - (7-4) //1 4 - (8-4) //0 */ } map[i][k].id = blackChess[temp]; } //设置炮 if (i == 2 && (k == 1 || k == 7)) { map[i][k].id = blackChess[5]; } //设置兵 if (i == 3 && k % 2 == 0) { map[i][k].id = blackChess[6]; } } else //红棋 { map[i][k].type = RED; if (i == 9) //放置第一行的棋子 { //0 1 2 3 4 if (k <= 4) { temp = k; } // 3 2 1 0 else { // k == 5 temp = 4 - (k - 4); /* 4 - (5-4) //3 4 - (6-4) //2 4 - (7-4) //1 4 - (8-4) //0 */ } map[i][k].id = redChess[temp]; } //设置炮 if (i == 7 && (k == 1 || k == 7)) { map[i][k].id = redChess[5]; } //设置兵 if (i == 6 && k % 2 == 0) { map[i][k].id = redChess[6]; } } map[i][k].isRiver = false; map[i][k].x = k * GRID_SIZE + INTERVAL; map[i][k].y = i * GRID_SIZE + INTERVAL; } } }
接下来是我们的绘制函数
//绘制 void draw() { setfillcolor(RGB(252, 215, 162)); setlinestyle(PS_SOLID, 2); //设置文字的样式 settextstyle(30, 0, "楷体"); for (size_t i = 0; i < ROW; i++) { for (size_t k = 0; k < COL; k++) { if (map[i][k].id == NONE) continue; settextcolor(map[i][k].type); setlinecolor(map[i][k].type); //绘制棋子 fillcircle(map[i][k].x, map[i][k].y, 30); fillcircle(map[i][k].x, map[i][k].y, 25); outtextxy(map[i][k].x - 15, map[i][k].y - 15, ChessName[map[i][k].id]); } } }
后面是我们的重点,鼠标控制函数,以后类似的游戏项目都会有这样的函数,好好理解
//鼠标操作 void mouseEvent() { ExMessage msg; //定义消息结构体变量 if(peekmessage(&msg, EM_MOUSE)) { if (msg.message == WM_LBUTTONDOWN) //鼠标左键按下 { //通过鼠标坐标得出点击的数组的下标 //k * GRID_SIZE + INTERVAL = x; int col = (msg.x - INTERVAL) / GRID_SIZE; int row = (msg.y - INTERVAL) / GRID_SIZE; //下标校准 if (msg.x > map[row][col].x + 30 && msg.y < map[row][col].y + 30) { col++; } if (msg.x < map[row][col].x + 30 && msg.y > map[row][col].y + 30) { row++; } if (msg.x > map[row][col].x + 30 && msg.y > map[row][col].y + 30) { row++; col++; } //printf("(%d %d)\n", row, col); if (state.state == BEGIN) { state.begr = row; state.begc = col; state.state = END; } else if (state.state == END) { state.endr = row; state.endc = col; state.state = BEGIN; } chessMove(); } } }
重点中的重点,棋子的移动函数,游戏的规则也就在这里体现出来
//移动棋子 void chessMove() { printf("beg(%d %d) end(%d %d)\n", state.begr, state.begc, state.endr, state.endc); bool canMove = false; //什么情况下能够移动棋子 if (!(state.begr == state.endr && state.begc == state.endc) && //点击的不是同一个棋子 state.endr!=-1 && state.begr!=-1&& //下标必须合法 map[state.begr][state.begc].id != NONE//没有棋子不能移动 /*&&map[state.begr][state.begc].type != map[state.endr][state.endc].type*/) //不能自己吃自己 { switch (map[state.begr][state.begc].id) { case 車: case 俥: if (state.begr == state.endr || state.begc == state.endc) { //起始点和结束点之间是否有阻碍 if (hasBlock(&state)) { canMove = true; } } break; case 馬: case 马: break; case 象: case 相: break; case 士: case 仕: break; case 将: case 帥: break; case 砲: case 炮: break; case 卒: case 兵: break; default: break; } if (canMove) { printf("canMove\n"); map[state.endr][state.endc].id = map[state.begr][state.begc].id; map[state.begr][state.begc].id = NONE; map[state.endr][state.endc].isRiver = map[state.begr][state.begc].isRiver; map[state.endr][state.endc].type = map[state.begr][state.begc].type; } } }
最后就是我们的主函数,进行调用,让项目运行起来
int main() { //创建图形窗口 initgraph(740, 820,EW_SHOWCONSOLE); //设置背景模式 setbkmode(TRANSPARENT); //贴棋盘 IMAGE img_board; loadimage(&img_board, "./res/ChessBoard.png"); init(); //双缓冲绘图,防止闪屏 BeginBatchDraw(); while (true) { cleardevice(); putimage(0, 0, &img_board); draw(); mouseEvent(); FlushBatchDraw(); } EndBatchDraw(); getchar(); return 0; }
这样一个简易版的《中国象棋》游戏项目就解决啦,重点就是逻辑,一定要想清楚,想要实现联网的同学就要更加的去想清楚,以及去提高自己的能力,好啦,希望可以让大家从中感受到编程的快乐吧,也希望大家可以给UP主一个关注,非常感谢大家了!!!
加载全部内容