10天开发的两国军旗
两国军旗
一、界面设计
下棋需要有棋盘,程序中通过在窗体激活时在图片框控件qi_pan上显示军旗棋盘图片文件。有了盘还需要有棋子,使用了以下如图5-6,图5-7中的图片表示棋子。另外还有R.bmp和G.bmp两个图片表示红方和绿方暗子。使用控件数组Qizi_Pic[]的Add方法加载了我们所需要的棋子图片控件并使用相应图片。Qizi_Pic[]中下标i的含义是:如果i小于24,那么说明它属于红方的棋子,否则是绿方的棋子。同时Qizi_Pic[i]的tag属性保存了棋子在控件数组的索引号。
图5-6 红方军棋棋子图片
图5-7 绿方军棋棋子图片
在界面中要求用户输入对方IP、端口(本地及对方远端)。同时按图5-8添加“联机”、“重新开始”、“退出”、“保存布阵”、“读取布阵”、“开始对战”6个按钮以及一些题使用的标签。
图5-8 网络两人对战军棋设计界面
二、通讯协议设计
网络程序设计的难点在于与对方需要通讯。这里使用了UDP(User Data Protocol)。UDP是用户数据文报协议的简称,两台计算机之间的传输类似于传递邮件;两台之间没有明确的连接,使用UDP协议建立对等通信。这里虽然两者两台计算机不分主次,但我们设计时假设一台做主机(红方),等待其他人加入。其他人想加入的时候输入主机的IP。为了区分通信中传送的是“输赢信息”,“下的棋子位置信息”,“重新开始”等,在发送信息的首部加上代号。定义了如下协议:
命令|参数|参数……
(1)联机功能
join|
(2)对方棋子移动信息
move|x , y , idx, old_x, old_y,old_idx
其中:棋子移动的目标位置坐标(x,y),棋子移动的起始位置坐标(old_x,old_y);
old_idx是被移动棋子的控件数组索引号,
idx是目标位置留下的棋子的控件数组索引号。
(3)游戏结束
over|+赢方代号 (赢了此局)
(4)表示要重新开始
reset|
(5)布阵信息
layout|布阵棋子信息
布阵棋子信息形式为x,y,idx,x,y,idx,x,y,idx……
idx是(x,y)处的棋子的控件数组索引号。
注意本程序在传递布阵信息时,我们默认了是绿方在棋盘上方,红方在下。但实际下棋如果棋手使用绿方,这样看非累死不可。所以这里我们采取了个小技巧,在发送布阵数据的时候我们把坐标在颠倒(把自己的棋盘颠倒)。即(x,y)坐标以(18-x),(18-y) 坐标发给对方。
在下棋过程中,为了保存下过的棋子的位置使用了Map数组,Map数组初值为101,表示此处无棋子。Map数组可以有0到49值,其中0到24代表红方棋子;25到49代表绿方棋子。
关于0到24的棋子含义如下在qi_index()规定:
private void qi_index()
{
Q=new int[25];
Q[0]=29; //军旗29
Q[1]=30;Q[2]=30;Q[3]=30;//地雷30
Q[4]=31;Q[5]=31;//炸弹31
Q[6]=32;Q[7]=32;Q[8]=32;//工兵32
Q[9]=33;Q[10]=33;Q[11]=33;//排长33
Q[12]=34;Q[13]=34;Q[14]=34;//连长34
Q[15]=35;Q[16]=35;//营长35
Q[17]=36;Q[18]=36;//团长36
Q[19]=37;Q[20]=37;//旅长37
Q[21]=38;Q[22]=38;//师长38
Q[23]=39;//军长39
Q[24]=40;//司令40
}
也即是0军旗,1—3地雷,4—5炸弹,6—8工兵,9—11排长,12—14连长,15—16营长,17—18团长,19-20旅长,21—22师长,23军长,24司令。
在Q数组中Q[24]=40而不直接写为“司令”,原因是棋子图片的命名时采用40.bmp
所以为显示图片时的方便,这里Q[24]=40。
25到49代表绿方棋子。绿方只要减去25(每方25个棋子)即可利用Q数组得知绿方棋子的含义。例如27代表的绿方地雷。
三、走棋规则设计
对于军旗游戏来说,规则非常简单,就是按照先后顺序在棋盘上走棋吃子,直到最先一方将对方的“军旗”挖掉为胜。
但在走棋过程中,需要考虑以下情况:
(1)是否为非棋子区;
(2)目标处是否是自己的棋子;
(3)判断目标是否实行营,如果是则需判断是否有子,如果没有可以如“士”一样斜线走棋。
(4)判断起始位置是否是铁道线,如果是则考虑弯道、直道、棋盘正中间的3*3“田子”,否则只能移动一步。
(5)“军旗”棋子、地雷棋子不能走动;
(6)在“大本营”中的棋子不能走动;
可以看出走棋规则实行比较复杂。在设计时Go_Juge(int old_x,int old_y,int x,int y)判断走棋的位置是否适当。
private bool Go_Juge(int old_x,int old_y,int x,int y)
{
//是否是棋子区域
if( (x<=6 && y>=1 && y<=6) || (x>=12 && y>=1 && y<=6) ||
(x<=6 && y>=12 && y<=17) || (x>=12 && y>=12 && y<=17)|| y>17 )
return false;
//目标位置是自己方的棋子
if(IsmyChess(x,y)) return false;
//到行营,行营是否有子
if(Is_Home( x, y)&& Map[x,y]!=101)return false;
//如“士”斜线从行营中出来**********
if(Is_Home( old_x, old_y)&& Map[x,y]==101&& Math.Abs(x-old_x)*Math.Abs(y-old_y)==1 )return true;
//如“士”斜线走入行营************
if(Is_Home( x, y)&& Map[x,y]==101 && Math.Abs(x-old_x)*Math.Abs(y-old_y)==1 )return true;
//移动一步
if( Math.Abs(x-old_x)==1 && y==old_y ||Math.Abs(y-old_y)==1 && x==old_x) return true;
//铁道线
if(T_Juge(old_x,old_y,x,y)) return true;
return false;
}
本程序中go_chess(int old_x,int old_y,int x,int y,int idx)完成走棋吃子功能,其中判断以下几种情况:
(1)双发均为工兵到司令的棋子,则按大小比较决定保留那方棋子;
(2)其中一方式炸弹(31),则同时去掉。
(3)其中一方是地雷(30),对方为工兵,则留兵,否则留雷。
(4)其中一方是军旗(29),则可以判断输赢。
注意:在发送走棋数据的时候我们仍然需要把坐标在颠倒(把自己的棋盘颠倒)。即(x,y)坐标以(18-x),(18-y) 坐标发给对方。
四、布阵规则设计
注意布阵是采用两次单击不同棋子来决定对调的,所以(old_x, old_y)是第一次单击的棋子坐标,(x1,y1)是第二次单击的棋子坐标。
判断布局棋子的位置是否适当是使用Layout_Juge(int old_x,int old_y,int x1,int y1)实现以下情况判断:
(1)第一排不允许放置炸弹;由于布阵均在南方,所以第一排即(y1=12);
(2)自己的军旗只能放置在大本营;由于布阵均在南方,所以大本营即x1==8&&y1==17||x1==10&&y1==17;
(3)后两排允许放置地雷。由于布阵均在南方,后两排即y1==16||y1==17。
具体实现如下:
//炸弹控件编号4,5,第一排(y1=12)不允许放置炸弹
if(Q[Map[old_x,old_y]%25]==31 && y1==12) return false;
if(Q[Map[x1,y1]%25]==31 && old_y==12) return false; if(Q[Map[old_x,old_y]%25]==29 && !(x1==8&&y1==17||x1==10&&y1==17))
return false;//自己的军旗控件,只能放置在大本营
if(Q[Map[x1,y1]%25]==29 && !(old_x==8&&old_y==17||old_x==10&&old_y==17))
return false;//自己的军旗控件,只能放置在大本营
if(Q[Map[x1,y1]%25]==30 && !(old_y==16||old_y==17))
return false;//第1,2,3,4排不允许放置地雷,
if(Q[Map[old_x,old_y]%25]==30 && !(y1==16||y1==17))
return false;//第1,2,3,4排不允许放置地雷,
return true;//其余情况均可以
10天开发的两国军旗相关推荐
- 张高兴的 Windows 10 IoT 开发笔记:BH1750FVI 光照度传感器
张高兴的 Windows 10 IoT 开发笔记:BH1750FVI 光照度传感器 原文:张高兴的 Windows 10 IoT 开发笔记:BH1750FVI 光照度传感器 BH1750FVI 是一款 ...
- iOS 10应用开发基础教程
iOS 10应用开发基础教程 介绍: 本教程是国内第一本iOS 10开发应用教程.本教程基于Xcode 8.0,使用Swift 3.0语言讲解如何开发iOS 10的应用App. 学习建议:本教程针对i ...
- 【Win 10 应用开发】Toast通知激活应用——前台后台
原文:[Win 10 应用开发]Toast通知激活应用--前台&后台 老周最近热衷于讲故事,接下来还是讲故事时间. 有人问我:你上大学的时候,有加入过学生会吗?读大学有没有必要加入学生会? 哎 ...
- 【Win 10应用开发】SplitView控件
[Win 10应用开发]SplitView控件 原文:[Win 10应用开发]SplitView控件 SplitView控件用于呈现分隔视图,简单地说,就是把一个视图分割为两部分,Content属性所 ...
- 水晶报表10高级开发版下载及序列号
水晶报表10高级开发版下载及序列号 分类: 编程语言 2011-04-28 22:24 526人阅读 评论(0) 收藏 举报 Crystal Reports 10 Advanced Developer ...
- 【Win 10 应用开发】RTM版的UAP项目解剖
原文:[Win 10 应用开发]RTM版的UAP项目解剖 Windows 10 发布后,其实SDK也偷偷地在VS的自定义安装列表中出现了,今天开发人员中心也更新了下载.正式版的SDK在API结构上和以 ...
- 张高兴的 Windows 10 IoT 开发笔记:RTC 时钟模块 DS3231
原文:张高兴的 Windows 10 IoT 开发笔记:RTC 时钟模块 DS3231 GitHub:https://github.com/ZhangGaoxing/windows-iot-demo/ ...
- 【Win 10应用开发】Adaptive磁贴模板的XML文档结构
原文:[Win 10应用开发]Adaptive磁贴模板的XML文档结构 在若干天之前,老周给大家讲了Adaptive Toast通知的XML模板,所以相应地,今天老周给大家介绍一下Adaptive磁贴 ...
- 【Windows 10 应用开发】细说文本资源文件(resw)
原文:[Windows 10 应用开发]细说文本资源文件(resw) 最近,小戏骨版<红楼梦>很是火热,老周一口气看完了9集,一直看到 Surface 的风扇呼呼响.林黛玉和薛宝钗这两个角 ...
最新文章
- 摄像头标定入门资料整理
- 【Linux系统编程】Linux进程调度
- 360画报屏保,放大营销“感官力”
- go kegg_玩转GO和KEGG富集因子图的N种姿势: 3种数据处理(含在线筛选条目),3种排序方式,本地交互图片...
- 细谈最近上线的Vue2.0项目(一)
- 如何让自己的视频号作品上热门
- WEB API Filter的使用以及执行顺序
- 云原生的基石,一文读懂容器、Docker、Pod到底是什么!
- 【PostgreSQL-9.6.3】物化视图
- 西瓜书读书笔记3-对数几率回归(logistic回归)公式推导
- ActiveMQ 命令行启动 与 嵌入式启动、MessageListener 监听消息
- Java二叉树的完全性检验
- 云端软件平台 封装了诺基亚PC套件无法找到驱动怎么办
- Excel数据分析--客户对象分析
- 使用npm运行react程序报错The 'mode' option has not been set, webpack will fallback to 'production' for th
- ubuntu16.04下安装为知笔记
- 平均年薪40万!为什么却很少见程序员炫富?
- Qlikview---日期字段
- 地图位置开发解析(一)
- android 照片特效,Android使用Gallery实现照片拖动的特效