简单的象棋开发

article/2025/9/20 15:56:26

我们需要准备的知识是c语言基础和easyx图形:

easyx官网:

https://easyx.cn/

首先头文件少不了:

#include<stdio.h>(c语言的头文件)
#include<graphics.h>(easyx的)
#include<mmsystem.h>(音乐播放的)
#pragma comment(lib,"winmm.lib")(链接上音乐播放器的库)

 

然后老套路了:

int main(int argc,char *argv[])
{
​
}

创建图形窗口(这里不创建会听到熟悉的声音):

int main(int argc,char *argv[])
{initgraph(WIN_WIDTH, WIN_HEIGHT);// (第三个参数SHOWCONSOLE控制控制台窗口的显示与否)
​
}

 

还有个问题图形窗口会闪退:

  • 所以我们需要阻塞窗口

     
    while (1)
    {;
    }
     
     

    或者:

    getchar();


象棋的属性和一些初始化:

 

#define INTERVAL 50 //前面的间隔
#define CHESS_GRID_SIZE 70//格子宽度
#define ROW 10
#define COL 9
#define WIN_WIDTH ((COL-1)*CHESS_GRID_SIZE+INTERVAL*2+250)
//窗口宽度计算得出
#define WIN_HEIGHT ((ROW-1)*CHESS_GRID_SIZE+INTERVAL*2)
//窗口高度计算得出
IMAGE img_chessBoard;(定义背景图)
void loadImg()(加载背景图)
{loadimage(&img_chessBoard, "./res/Chess.jpg", 650, 700);
}
​
enum Pieces //棋子
{SPACE = -1,車, 馬, 象, 士, 将, 砲, 卒,俥, 马, 相, 仕, 帥, 炮, 兵,BEGIN, END,
};
//给id赋值
int redChess[] = { 車, 馬, 象, 士, 将, 砲, 卒 };
int blackChess[] = { 俥, 马, 相, 仕, 帥, 炮, 兵 };
//绘制时转化成字符串
const char* ChessName[] = { "車","馬","象","士","将","砲","卒","俥", "马", "相", "仕", "帥", "炮", "兵" };
struct Chess
{int id;//棋子名称int type;//棋子类型,红棋,还是黑棋int x;//坐标int y;bool river;//是否过了河
}map[ROW][COL];

鼠标的点击初始化:

POINT begin = { -1, -1 }, end = { -1, -1 };//记录前后两次点击的下标
int state = BEGIN;
int whereMove = RED;

 

游戏开始初始化:

void GameInit()
{loadImg();//遍历二维数组for (int i = 0; i < ROW; i++){int temp = 0, temp1 = 0, temp2 = 1;for (int k = 0; k < COL; k++){int chessname = SPACE;int mcolor = BLACK;//black黑色//黑棋初始化if (i <= 4){mcolor = BLACK;if (i == 0)//第1行{if (temp <= 4){temp++;}else{temp1 = 4 - temp2;temp2++;}chessname = blackChess[temp1];temp1++;}//设置炮if (i == 2 && (k == 1 || k == 7)){chessname = blackChess[5];}//设置小兵if (i == 3 && k % 2 == 0){chessname = blackChess[6];}
​}else//红旗初始化{mcolor = RED;if (i == 9)//最后一行{if (temp <= 4){temp++;}else{temp1 = 4 - temp2;temp2++;}chessname = redChess[temp1];temp1++;}//设置炮if (i == 7 && (k == 1 || k == 7)){chessname = redChess[5];}//设置小兵if (i == 6 && k % 2 == 0){chessname = redChess[6];}}map[i][k].type = mcolor;map[i][k].id = chessname;map[i][k].river = false;map[i][k].x = k * CHESS_GRID_SIZE + INTERVAL;map[i][k].y = i * CHESS_GRID_SIZE + INTERVAL;
​}}
}

 

游戏绘制:

 

void GameDraw()
{setbkcolor(RGB(252, 215, 162));cleardevice();setlinecolor(BLACK);setlinestyle(PS_SOLID, 2);setfillcolor(RGB(252, 215, 162));
​putimage(0, 0, &img_chessBoard);
​//画棋子settextstyle(30, 0, "楷体");setbkmode(TRANSPARENT);for (int i = 0; i < ROW; i++){for (int k = 0; k < COL; k++){if (map[i][k].id != SPACE){if (map[i][k].type == BLACK){settextcolor(BLACK);setlinecolor(BLACK);}else{settextcolor(RED);setlinecolor(RED);}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 - 10, map[i][k].y - 10, ChessName[map[i][k].id]);}}}//画点击出现的边框if (state == END && map[begin.x][begin.y].id != SPACE){setlinecolor(BLUE);line(map[begin.x][begin.y].x - 30, map[begin.x][begin.y].y - 30, map[begin.x][begin.y].x + 30, map[begin.x][begin.y].y - 30);line(map[begin.x][begin.y].x - 30, map[begin.x][begin.y].y + 30, map[begin.x][begin.y].x + 30, map[begin.x][begin.y].y + 30);line(map[begin.x][begin.y].x - 30, map[begin.x][begin.y].y - 30, map[begin.x][begin.y].x - 30, map[begin.x][begin.y].y + 30);line(map[begin.x][begin.y].x + 30, map[begin.x][begin.y].y - 30, map[begin.x][begin.y].x + 30, map[begin.x][begin.y].y + 30);}info();
}

游戏控制:

void KeyControl()
{static ExMessage msg;if (peekmessage(&msg, EM_MOUSE)){if (msg.message == WM_LBUTTONDOWN){//获取鼠标点击得数组下标int row = (msg.y - INTERVAL) / CHESS_GRID_SIZE;int col = (msg.x - INTERVAL) / CHESS_GRID_SIZE;//if (msg.y > map[row][col].y - 30 && msg.y<map[row][col].y + 30 && msg.x>map[row][col].x - 30 && msg.x < map[row][col].x + 30)//{//  //在棋子上点击//}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++;}if (state == BEGIN){printf("begin:(%d,%d)\n", begin.x, begin.y);begin.x = row;begin.y = col;state = END;}else if (state == END){printf("end:(%d,%d)\n", end.x, end.y);end.x = row;end.y = col;state = BEGIN;}}}
}

 

游戏规则:

int check(POINT begin, POINT end)
{int _count = 0;//水平方向int tmax = 0;int tmin = 0;if (begin.x == end.x){tmax = max(begin.y, end.y);tmin = min(begin.y, end.y);for (int i = tmin + 1; i < tmax; i++){if (map[begin.x][i].id != SPACE){_count++;}}}else if (begin.y == end.y){//垂直方向tmax = max(begin.x, end.x);tmin = min(begin.x, end.x);for (int i = tmin + 1; i < tmax; i++){if (map[i][begin.y].id != SPACE){_count++;}}}return _count;
}

 

棋子的移动:

 

void chessMove()
{bool isok = false;printf("whereMove %d \n", whereMove);//点击的不是同一个,以及都有了数据if (!(begin.x == end.x && begin.y == end.y) && begin.x != -1 && end.x != -1 && map[begin.x][begin.y].id != SPACE&& (map[end.x][end.y].id == SPACE || map[end.x][end.y].type != map[begin.x][begin.y].type)&& map[begin.x][begin.y].type == whereMove){POINT general[2] = { 0,3,7,3 };//双方九宫格左上角的位置switch (map[begin.x][begin.y].id){case Pieces::将:case Pieces::帥:for (int t = 0; t < 2; t++){for (int i = general[t].x; i <= general[t].x + 2; i++){for (int k = general[t].y; k <= general[t].y + 2; k++){if (end.x == i && end.y == k &&  //结束位置在九宫格内(begin.x == end.x || begin.y == end.y) &&  //结束位置和开始位置,在同一水平或垂直方向(只能走直线)(abs(end.x - begin.x) == 1 || abs(end.y - begin.y) == 1) //一次只能走一格){isok = true;}}}}break;case Pieces::士:case Pieces::仕:for (int t = 0; t < 2; t++){for (int i = general[t].x; i <= general[t].x + 2; i++){for (int k = general[t].y; k <= general[t].y + 2; k++){if (end.x == i && end.y == k &&  //结束位置在九宫格内(begin.x != end.x && begin.y != end.y) &&  //结束位置和开始位置,不在同一水平或垂直方向(只能走斜线)(abs(end.x - begin.x) == 1 || abs(end.y - begin.y) == 1) //一次只能走一格){isok = true;}}}}break;case Pieces::相:case Pieces::象://if ((end.x == begin.x - 2 && end.y == begin.y - 2)//  || (end.x == begin.x + 2 && end.y == begin.y - 2)//  || (end.x == begin.x - 2 && end.y == begin.y + 2)//  || (end.x == begin.x + 2 && end.y == begin.y + 2)//  )if (abs(end.x - begin.x) == 2 && abs(end.y - begin.y) == 2 && map[end.x][end.y].type == map[begin.x][begin.y].type){isok = true;}break;case Pieces::马:case Pieces::馬:/*if ((end.x == begin.x + 1 && end.y == begin.y + 2)|| (end.x == begin.x + 1 && end.y == begin.y - 2)|| (end.x == begin.x - 1 && end.y == begin.y + 2)|| (end.x == begin.x - 1 && end.y == begin.y - 2)|| (end.x == begin.x + 2 && end.y == begin.y + 1)|| (end.x == begin.x + 2 && end.y == begin.y - 1)|| (end.x == begin.x - 2 && end.y == begin.y + 1)|| (end.x == begin.x - 2 && end.y == begin.y - 1))*/if ((abs(end.x - begin.x) == 1 && abs(end.y - begin.y) == 2)|| (abs(end.x - begin.x) == 2 && abs(end.y - begin.y) == 1)){
​isok = true;}break;case Pieces::俥:case Pieces::車://判断直行if (begin.x == end.x || begin.y == end.y){//落子位置为空,落子位置和源位置之间没有子挡路if (check(begin, end) == 0){isok = true;}}break;case Pieces::炮:case Pieces::砲://判断直行if (begin.x == end.x || begin.y == end.y){//落子位置为空,落子位置和源位置之间没有子挡路if ((map[end.x][end.y].id == SPACE && check(begin, end) == 0)//走子|| (map[end.x][end.y].id != SPACE && check(begin, end) == 1))//吃子{isok = true;}//吃子判断,落子位置有子,落子位置和源位置之间有且只有一个字挡路}break;case Pieces::兵:case Pieces::卒://没过河只准向前,不转左右if (map[begin.x][begin.y].type == BLACK && begin.x <= 4){map[begin.x][begin.y].river = false;}else if (map[begin.x][begin.y].type == BLACK && begin.x > 4){map[begin.x][begin.y].river = true;}if (map[begin.x][begin.y].type == RED && begin.x >= 5){map[begin.x][begin.y].river = false;}else if (map[begin.x][begin.y].type == RED && begin.x < 5){map[begin.x][begin.y].river = true;}
​//如果没过河,只能向前走if (map[begin.x][begin.y].river == false && end.y == begin.y){if ((map[begin.x][begin.y].type == BLACK && end.x == begin.x + 1) ||(map[begin.x][begin.y].type == RED && end.x == begin.x - 1)){isok = true;}}//如果过了河,不能往回走else if (map[begin.x][begin.y].river == true){//如果为黑棋(上方),并且结束位置不小于开始位置if (map[begin.x][begin.y].type == BLACK && end.x >= begin.x && (abs(end.x - begin.x) == 1 || abs(end.y - begin.y) == 1)){isok = true;}//如果为红棋(下方),并且结束位置不大于开始位置else if (map[begin.x][begin.y].type == RED && end.x <= begin.x && (abs(end.x - begin.x) == 1 || abs(end.y - begin.y) == 1)){isok = true;}}break;}if (isok == true){//落子声音mciSendString("close PLAY", 0, 0, 0);mciSendString("open ./res/playChess.mp3 alias PLAY", 0, 0, 0);mciSendString("play  PLAY", 0, 0, 0);map[end.x][end.y].id = map[begin.x][begin.y].id;map[end.x][end.y].type =map[begin.x[begin.y].type;map[end.x][end.y].river = map[begin.x][begin.y].river;//此处有待完善map[begin.x][begin.y].id = SPACE;//显示哪方行棋if (whereMove == RED){whereMove = BLACK;}else{whereMove = RED;}}//重置点击属性//state = BEGIN;//begin.x = -1;//begin.y = -1;//end.x = -1;//end.y = -1;}
}

判断输赢:

bool JudgeWin()
{POINT general[2] = { 0,3,7,3 };//双方九宫格左上角的位置int isok = 0;for (int t = 0; t < 2; t++){for (int i = general[t].x; i <= general[t].x + 2; i++){for (int k = general[t].y; k <= general[t].y + 2; k++){//统计将领数量,正常为两个if (map[i][k].id == 将 || map[i][k].id == 帥){isok++;}}}}//如果两个首领都在,则未结束,只有一个,则结束if (isok == 2){return false;}else{return true;}
}
​

 

main函数的最终写法:

int main(int argc,char *argv[])
{   initgraph(WIN_WIDTH, WIN_HEIGHT);//图像窗口GameInit();//初始化BeginBatchDraw();//双缓冲while (1)//循环绘制{GameDraw();FlushBatchDraw();KeyControl();chessMove();if (JudgeWin() == true)//判断结束弹出窗口{MessageBox(GetHWnd(), "游戏结束~", "Waring", MB_OK);break;}}return 0;
}

 

象棋讲解视频请看:

https://www.bilibili.com/video/BV1tR4y157xD

简单介绍以后编程学习和讲的东西:

1,从C语言开始
基础数据类型,运算符,控制结构,函数,数组,指针,枚举,结构体,联合,文件操作,,动态内存分配
2,数据结构
数组,链表,队列,栈,树,图,常用算 肥婆拉妾数列
3,C++ 
面向对象,类,对象,运算符重载,派生,继承,虚函数,(重点:多态),异常,IO流,STl,正则表达式
4,Windows编程
窗口原理,消息机制,对话框....   
5,windows内核编程
多线程,多进程 注入 hook
6,网络编程
计网,TCP/IP协议栈
7,数据库
MySQL,oracle  SQL语句,SQL注入,
8,Qt跨平台开发
Windows系统 linux系统  ios
9,Linux 黑客必备 运维...
命令 ls shell  


http://chatgpt.dhexx.cn/article/P4C0BwRB.shtml

相关文章

Java游戏开发 —— 五子棋

引言&#xff1a; 五子棋的代码实现很简单&#xff0c;难的是计算机的AI算法&#xff0c;在网上找了很多资料&#xff0c;费了好半天劲才弄明白其实现的原理&#xff0c;真的挺开阔思路的&#xff0c;很有意思&#xff01; 思路&#xff1a; 1、创建主窗口&#xff0c;加载菜单…

编程小游戏之三子棋

三子棋是一个民间的益智小游戏&#xff0c;游戏分为双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#xff0c;率先将自己的三个棋子连成一条线的一方则视为胜利者。下面将说明如何利用C语言在我们的计算机上简单的实现三子棋。 1.逻辑框架设计 在vs上创建两个.c文件test…

【C语言】三子棋游戏的实现(玩家VS玩家 or 玩家VS电脑)

目 录 一、三子棋游戏介绍 二、游戏功能函数分析 1 菜单显示函数 2 菜单选择函数 3 选择确认函数 4 显示当前棋盘状态函数 5 棋盘初始化函数 6 玩家下棋函数 7 电脑下棋函数 8 棋局状态判断函数 三、游戏功能函数的整合 四、三子棋游戏的实现 五、游戏…

安卓做的棋类游戏

大方大斜 前言一、直接上图二、游戏主要代码1.界面绘制代码2.游戏触摸事件代码 最后 前言 安卓制作棋类游戏&#xff0c;小时候和发小在地上画棋盘&#xff0c;有树叶或者树枝做棋子。 一、直接上图 二、游戏主要代码 1.界面绘制代码 双人界面绘制&#xff0c;主要代码代码如…

基于java的五子棋游戏设计

技术&#xff1a;Java、JSP等摘要&#xff1a;随着互联网迅速的发展&#xff0c;网络游戏已经成为人们普遍生活中不可或缺的一部分&#xff0c;它不仅能使人娱乐&#xff0c;也能够开发人的智力&#xff0c;就像本文所主要讲的五子棋游戏一样能挖掘人们聪明的才干与脑袋的机灵程…

自己设计的棋类游戏

1、构思&#xff1a; 象棋、国际象棋、井字棋等 我一开始的设计是这个样的&#xff1a;一个5x5的棋盘&#xff08;之后变成7x7&#xff09;&#xff0c;所有棋子摆成一个井字 棋子有两种&#xff0c;一种兵一种王&#xff0c;中间用中立的棋子&#xff0c;就叫box来隔开他们 …

Java围棋游戏的设计与实现

技术&#xff1a;Java等 摘要&#xff1a; 围棋作为一个棋类竞技运动&#xff0c;在民间十分流行&#xff0c;为了熟悉五子棋规则及技巧&#xff0c;以及研究简单的人工智能&#xff0c;决定用Java开发五子棋游戏。主要完成了人机对战和玩家之间联网对战2个功能。网络连接部分为…

【国际象棋】棋盘游戏-微信小程序开发流程详解

与中国象棋类似的&#xff0c;还有国际象棋&#xff0c;知道有人爱玩&#xff0c;于是凭着好奇心&#xff0c;网上研究了一下&#xff0c;跟中国象棋有相似之处&#xff0c;玩法是有些许不一样&#xff0c;不知道象棋最早出于谁之手呢&#xff0c;抽空做一做&#xff0c;最终完…

利用C语言巧妙实现棋类游戏——三子棋

小游戏&#xff1a;三子棋用C语言实现 你是否学完了C语言的函数、数组、选择结构、循环结构苦于没有实战小项目巩固自己所学的知识呢&#xff0c;今天小程序猿就给大家带来了一个游戏的小游戏——三子棋&#xff0c;利用C语言实现的&#xff0c;希望对大家能有所帮助。 我们大家…

基于C#的五子棋游戏设计

目 录 一、 毕业设计内容 3 二、 毕业设计目的 3 三、 工具/准备工作 3 四、 设计步骤和方法 3 &#xff08;一&#xff09; 总体设计 3 1&#xff0e; 总体设计思路及设计图 3 2&#xff0e; 界面设计 4 3&#xff0e; 全局变量设计 4 &#xff08;二&#xff09; 详细设计 5 …

【Unity连载】斗兽棋-棋类游戏开发演示(2)

第四章 游戏操作与指令 如同养育一个婴儿&#xff0c;父母总会一步步引领孩子成长&#xff0c;从蹒跚学步到来去如风&#xff1b;我们对游戏功能的开发&#xff0c;也无疑应当从走出第一步棋开始。现在&#xff0c;我们已经构建出了棋盘、棋子等基本的游戏逻辑对象&#xff1b…

Java游戏开发——中国象棋联机版

游戏介绍&#xff1a; 中国象棋是起源于中国的一种棋戏&#xff0c;属于二人对抗性游戏的一种&#xff0c;在中国有着悠久的历史。由于规则简单&#xff0c;趣味性强&#xff0c;成为流行极为广泛的棋类游戏。 中国象棋使用方形格状棋盘及红黑二色圆形棋子进行对弈&#xff0c…

【论文】word中三线表的快速简单制作

【论文】word中三线表的快速简单制作 首先&#xff0c;打开word点击插入→表格&#xff0c;选择需要插入表格的行列数&#xff0c;行列数没有关系&#xff0c;因为你插入后可以随意添加行列。 则插入了一下表格&#xff1a; 把你所需要的数据放进去&#xff1a; 之后&#…

如何在word中制作线宽不同的三线表

在word中难免会插入特定的三线表&#xff0c;那就现场给给大家演示一遍 1、打开word&#xff0c;点击插入&#xff0c;点击表格&#xff0c;至于插入几行几列看自己的需求哈。 2、右键点击表格&#xff0c;然后点击表格属性 3、点击边框和底纹&#xff0c;对表格去除相关边线 …

论文中的三线表绘制(word)

步骤 1、选中表格&#xff08;点击下图中的红框部分选中&#xff09; 2、右击表格选择“表格属性” 3、点击边框和底纹&#xff0c;再选择无边框&#xff08;先不要点确定&#xff09; 4、设置三线表的上下边框&#xff08;1.5磅&#xff09;&#xff0c;完成下图之后点击确定-…

word三线表标题两条线之间如何出现空白间隔(论文必备)

为了写论文&#xff0c;我需要把以上的标题转换成下图所示的样子 所实现的步骤如下&#xff1a; 1、把标题内容回车 放在下一行 2、加一条绘制表格的线 3、选中第一行对应位置的两格&#xff0c;合并单元格 并填入内容 可以看到单纯的加上边框&#xff0c;两条线之间是没有空…

Word 2016表格三线表制作

1、打开word&#xff0c;点击插入&#xff0c;插入一个表格。 2、选中表格&#xff0c;点击设计&#xff0c;在边框中的笔画粗细选择1.5磅&#xff0c;然后在边框下拉框先选择无框线&#xff0c;再选择上框线和下框线。然后笔画粗细选择0.5磅&#xff0c;选中第一行后&#x…

三线表的制作

目录 前言参考过程 前言 最近在写些东西的时候&#xff0c;需要用到三线表&#xff0c;上网查了一下&#xff0c;将方法记录下来。 参考 三分钟快速制作论文三线表 过程 (1) 先插入一个表格&#xff0c;然后新建一个表格样式 (2) 如下图所示更改 (3) 点击第二步中的格式&a…

word表格跨页多出一根线(三线表)

在word中做三线表&#xff0c;表格跨页了自动在页底部加一横线&#xff0c;下一页页首加一横线这个怎么去掉么 首先感谢上方在知乎给出解决方案的博主&#xff0c; 接着&#xff1a;文中描述大概操作如下&#xff1a; 如果还是不行&#xff0c;那么就拿来dou一个三线表

Word插入三线表

在Word中插入一个三线表&#xff0c;方法如下所示&#xff1a; 一、先插入一个正常的表格&#xff0c;并输入好相应的数据 二、单击表格的左上角按钮&#xff0c;选中整个表格 选中表格之后&#xff0c;【右键】-【表格属性】&#xff0c;在弹出的表格属性对话框中单击【边框与…