简单的象棋开发

我们需要准备的知识是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://www.rhkb.cn/news/58690.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中国象棋C++实现

使用C语言开发中国象棋的小游戏 Chess.cpp // includes #include<iostream> #include<graphics.h> using namespace std;// 使用到的 WCHAR 字符 class CKind{ public:WCHAR ROOKS *(_T("车"));WCHAR KNIGHTS *_T("马");WCHAR ELEPHANTS …

用C++实现中国象棋

项目介绍 最近学习到了STL库&#xff0c;了解到一些很实用的容器&#xff0c;同时我也是个象棋爱好者&#xff0c;想着能不能做个象棋的游戏小程序出来&#xff0c;运用一下所学到的知识点&#xff0c;于是动手做了这个项目&#xff0c;花了两天左右的时间基本完成&#xff0c;…

C++中国象棋

ssdut c的大作业&#xff0c;在控制台的界面实现人人对弈&#xff0c;比较适合初学&#xff0c;自己设计了一些简单算法&#xff0c;两百多行完成。 以下正文&#xff1a; 完成中国象棋游戏&#xff0c;实现如下功能&#xff1a; 1.实现人与人之间象棋的对弈。 2.每次走子之…

Java版本实现中国象棋

预览效果 中国象棋 游戏介绍&#xff1a;中国象棋是起源于中国的一种棋&#xff0c;属于二人对抗性游戏的一种&#xff0c;在中国有着悠久的历史&#xff0c;由于用具简单&#xff0c;趣味性强&#xff0c;成为流行极为广泛的棋艺活动。阿巴阿巴阿巴 代码结构&#xff1a;Butto…

数影周报:小米汽车供应商被罚100万,1688延迟下线“1688买家旺旺”

本周看点&#xff1a;小米汽车供应商被罚100万&#xff1b;特斯拉将在硅谷招聘AI 人才&#xff1b;阳光出行等25款 App涉违规收集使用个人信息等&#xff1b;1688延迟于2月8日下线“1688买家旺旺”&#xff1b;微蚁科技完成数千万元B轮融资...... 数据安全那些事 小米汽车供应商…

Coggle 30 Days of ML (23年7月)任务二:数据可视化

Coggle 30 Days of ML (23年7月&#xff09;任务二&#xff1a;数据可视化 任务二&#xff1a;对数据集字符进行可视化&#xff0c;统计标签和字符分布 说明&#xff1a;在这个任务中&#xff0c;需要使用Pandas库对数据集的字符进行可视化&#xff0c;并统计数据集中的标签和…

阿里云服务器ECS是什么?详细介绍

阿里云服务器ECS是什么&#xff1f;云服务器和传统的物理服务器有什么区别&#xff1f;云服务器有哪些优势&#xff1f;云服务器可以什么&#xff1f;云服务器架构及云服务器包含哪些功能组件&#xff1f;阿里云百科来详细说下什么是云服务器ECS&#xff1a; 目录 阿里云服务…

使用Chrome修改user agent模拟微信内置浏览器

很多时候&#xff0c;我们需要模拟微信内置浏览器&#xff0c;今天教大家用 chrome 简单模拟。如图设置&#xff1a; F12或者右键审查元素进入开发者模式&#xff0c;点击Emulation&#xff0c;然后点击Network&#xff0c;把Spoof user agent改成Other&#xff0c;并把下面…

数据分析案例-足球运动员分析

目录 加载数据 查看数据 数据详细 ​缺值处理 异常值处理 重复值处理 运动员身高和体重分布 左脚右脚使用数量 俱乐部球员评分分析 足球运动员数是否与出生日期相关 身高与体重是否具有相关性 加载数据 #加载足球运动员数据 import numpy as np import pandas as pd impor…

如何用算法预测世界杯?

预测2021欧洲世界杯 世界杯预测结果预测的原理是什么&#xff1f;周易算卦原理算命可以解决的问题善易者不卜 人工智能预测原理预测模型&#xff1a;逻辑回归算法可以预测的问题 可以单挑整个华尔街的算法现代足球 世界杯预测结果 预测2021年欧洲世界杯&#xff0c;也是一道考…

采用 Python 机器学习预测足球比赛结果

足球是世界上最火爆的运动之一,如何运用机器学习来预测足球比赛结果,是每一个足球爱好者所向往的! 本场 Chat 适合有 Python 基础的机器学习初学者,我们带你一起熟悉机器学习的开发流程,帮你快速建立起自己的英超比赛预测模型! 你将获取到如下内容: 人工智能在线建模平…

按键精灵移动端系列 - 按键精灵IOS版 之 网络已断开,请检查网络连接.解决方案.

由于很多网友对这种问题,不知道如何处理.因本人也曾遇到过这种情况.经过不懈努力终于解决了这个神奇的BUG.长话短说上操作流程.如果觉得给力,请三连 点赞. 收藏. 转发. 谢谢您的支持. ** 1 安装雷锋源: apt.abcydia.com 2安装好雷锋源, 搜索: conditionalwifi 更新到最新版 …

按键精灵助手无法连接模拟器解决方案【适用任何模拟器】

找到按键精灵安装地址 D:\ProgramData\按键精灵\按键精灵手机助手\android 找到木木安装地址&#xff0c;并搜索adb.exe,未找到 但是在D:\Program Files (x86)\MuMu\emulator\nemu\vmonitor\bin找到 adb_server.exe 以及另外两个.dll 复制着三个文件到按键精灵上述文件夹&#…

国行版苹果 ios 按键精灵无法联网问题处理

国行版苹果手机安装按键精灵后无法联网的问题&#xff1a; 操作步骤&#xff1a; &#xff08;1&#xff09;自行把苹果手机进行越狱&#xff0c;找到并打开越狱商店“Cydia” &#xff0c;其他商店同理&#xff0c;按照如下图步骤添加 “雷锋源”&#xff0c;源地址&#xff…

网易mumu显示无法连接服务器,网易MuMu无法连接网络_网易MuMu如何实现多开

网易MuMu是由网易全方面打造的一种非常具有精品特色的游戏服务平台&#xff0c;这款游戏服务平台在下载安装之后可以直接运行电脑上的各种不同游戏和应用程序&#xff0c;同时它的兼容性是比较强的&#xff0c;有着非常流畅的操作过程&#xff0c;还可以通过智能辅助等优秀特色…

网易mumu模拟器adb连接配置

一、 网易mumu模拟器下载 二、安装模拟器到本机指定目录 1、例如&#xff1a;D:\Program Files\MuMu 2、adb文配置相关文件位于&#xff1a;D:\Program Files\MuMu\emulator\nemu\vms\myandrovm_vbox86下&#xff0c;如下图所示&#xff1a; 3、打开myandrovm_vbox86.nemu文件…

uni-app 连接不上夜神模拟器

uni-app 连接不上夜神模拟器 第一步打开运行设置 设置端口号 第二步通过cmd命令去连接模拟器 我这利用的是HX 找到&#xff1a;HBuilderX.3.1.17.20210608.full\HBuilderX\plugins\launcher\tools\adbs 直接cmd 执行下面两个命令 adb connect 127.0.0.1:62001 adb devices…

夜神模拟器无法连接网络的解决办法

我们经常会在电脑上安装安卓模拟器来玩一些手机游戏或者运行手机软件&#xff0c;但是有时候可能由于网络不好等原因导致模拟器连接不上网络。比如夜神模拟器无法连接网络怎么办&#xff1f;下面就来看看解决的办法。 夜神模拟器无法连接网络怎么办&#xff1a; 1、同时按下“w…

按键精灵手机助手如何连接安卓版按键精灵如何连接手机助手

通过上述讲解过的按键精灵如何下载文章得知,按键精灵手机版分为两个版本,分别为安卓版和IOS版,都是需要连接在按键精灵手机助手运行,按键精灵手机助手则必须在电脑上安装运行。好的,下面我们就来逐步讲解一下,手机版按键精灵如何使用。 首先,我们打开已经安装完成的按键…

天天模拟器显示获取服务器失败,天天模拟器无法联网怎么办-天天模拟器不能上网的解决方法 - 河东软件园...

天天模拟器是目前最热门的安卓模拟器软件&#xff0c;这是国内自主研发的一款优秀模拟器&#xff0c;其采用了持OpenGL硬件加速技术&#xff0c;能够帮助用户稳定的运行各类安卓应用&#xff0c;&#xff0c;并且具备了应用多开&#xff0c;软件具备了操作简单、稳定流畅等诸多…