hnyzcj 发表于 2021-2-19 09:46:02

用Arduino制作智能军棋项目分享

本帖最后由 hnyzcj 于 2025-1-12 20:02 编辑

【项目源起】      军棋的玩法通常有三种:明棋、暗棋和翻棋,其中暗棋是一种知己不知彼的玩法,每人使用一种颜色的棋子,立起来,正面朝向自己摆放,布置自己喜欢的阵法。然后按照规定的行棋方式走棋。想要吃棋的时候,并不知道对面是什么棋,也不能看。这时候,需要第三个人来担任裁判。裁判查看双方的棋子,比大小,小的一方被吃,拿出棋盘(拿出棋盘后也不能暴露是什么棋),大的一方留在棋盘上,直到分出胜负。于是我们决定设计制作一套智能军棋,只需两个玩家对战,不仅解脱裁判的尴尬与无聊,更能让玩家专注局势的博弈,不受裁判影响,极大提升玩家体验,如图1-3所示。【项目展示】

【功能简介】      (1)智能识别:智能军棋通过Huskylens视觉识别传感器扫描放置于擂台上军棋标签,对双方的棋子进行准确识别。      (2)智能评判:智能军棋通过内置算法判断双方出棋等级高低,从而给出胜负的判定。      (3)声光效果:智能军棋搭配音效搭配LED光效,紧张刺激又烧脑,增加玩家的代入感。      (4)磁力吸附:棋子的底部设计有三枚强磁铁,与擂台上的磁铁相互吸附,避免错误摆放。
【硬件材料】
序号名称数量
1Arduino uno1
2IO 传感器扩展板 V7.11
3HuskyLens AI 视觉传感器1
4炫彩 WS2812 RGB LED可剪裁黑色灯带1
5蜂鸣器1
65*5mm强磁铁200
7600*400松木板3

【制作过程】       1.系统设计      在进行系统设计前,我们先来了解下传统军棋的玩法。   (1)吃子规则       一副军旗双方共含有50个棋子,两方各有25个棋子,分别是司令、军长、师长、旅长、团长、营长、连长、排长、工兵、地雷、炸弹、军旗。司令→军长→师长→旅长→团长→营长→连长→排长→工兵,小棋遇大棋被吃,相同棋子相遇,则同归于尽;工兵能排除地雷,其它棋子不能排雷;炸弹与任何棋子相遇时同归于尽,也就是说,在军棋中,司令是最大的,就是司令可以吃一切的棋子。    (2)棋子识别      本作品最初设计时,是想在每枚棋子中放置不同阻值的电阻来予以区分,但通过串口读取数据发现数据误差较大。因此放弃这种方案,采用AprilTag标签进行标识,Huskylens视觉识别传感器进行识别的方案。同时为了防止对方记棋,我们对每一颗棋子都标记了AprilTag,这样一套棋子就需要50个AprilTag标签。这样问题就转换成Huskylens识别标签了问题了。    (3)棋子PK算法      依据军棋的吃子规则,我们对于两个上擂台棋子的PK,只要以下几类问题:   ▲军衔PK:这类棋子属于进攻型棋子,只需按照上述军衔等级高低判断胜负,等级相同同归于尽。   ▲工兵拆雷:工兵遇到地雷,则工兵拆除地雷。   ▲工兵扛旗:军棋必须在棋盘中两个大本营中的其中之一,且不可移动。工兵可扛旗,结束棋局。   ▲炸弹处理:防御型棋子,此棋子在棋盘上不可动,只能被动接受PK,任何可动棋子与之相遇两者同归于尽。   ▲地雷处理:防御型棋子,此棋子在棋盘上不可动,只能被动接受PK,除工兵以外的棋子与之相遇两者同归于尽。   针对上述问题进行算法设计,作为双方PK的核心算法。通过Huskylens识别出棋子的ID来判断棋子PK的胜负。   (4)声光效果   为了增加棋局的娱乐性,我们在系统中增加的了声光效果,用绿色光代表胜利,红色光代表失败,并配以适当的音效。
   2.结构设计   本次作品结构设计涉及两部分:一部分是棋盘结构,使用LaserMaker绘制结构图。另一部分是3D打印棋子结构件。   (1)棋盘结构件设计(松木板)   首先以3mm厚的松木板为原料,使用“快速造盒工具”,生成一个盒体。然后删除盒体左右两侧,并在盒体顶部,添加“棋盘”图片,并绘制蜂鸣器、Huskylens安装孔位和擂台孔位。具体设计如下图8-9所示。      其次依据上步生成盒体宽(内部)的尺寸绘制棋子收纳盒,具体设计图如下图10所示。      最后绘制出25个棋子的面板,如下图11所示   棋子结构件设计(3D打印)   我们在Fusion 360中,设计绘制棋子外壳结构和擂台结构如下图12-13所示。      电路连线      智能军棋系统电路连接如图14所示。两条灯带分别接D7,D8口,蜂鸣器模块接D4口,Huskylens视觉识别传感器通过I2C口与主控Arduino连接。       代码编写       主程序如下图15所示,包含了两个函数“定位识别”、“判断结果”,其中“定位识别”是通过识别到的两个方框中X的坐标值进行比较从而判断,从而判断所对应ID的两颗棋子左右位置;“判断结果”则依据前面定义的算法对两颗棋子进行胜负判定。<font face="微软雅黑" size="4">/*!
* MindPlus
* uno
*
*/
#include <DFRobot_NeoPixel.h>
#include <DFRobot_HuskyLens.h>
#include <DFRobot_Libraries.h>

// 动态变量
String         mind_s_M1, mind_s_M2;
volatile float mind_n_N1, mind_n_N2;
// 函数声明
void DF_DingWeiShiBie();
void DF_CeLiangZuoBiao();
void DF_N1DaYuN2();
void DF_N1XiaoYuN2();
void DF_PanDuanJieGuo();
void DF_MingChen();
void DF_DiLeiChuLi();
void DF_TongGuiYuJin();
void DF_ZuoBianSheng();
void DF_ZhaDanChuLi();
void DF_YouBianSheng();
void DF_GongBingChaiLei();
void DF_KangQi();
void DF_XiangDeng();
void DF_LXiaoYuR();
void DF_LDaYuR();
// 创建对象
DFRobot_HuskyLens huskylens;
DFRobot_NeoPixelneoPixel_7;
DFRobot_NeoPixelneoPixel_8;
DFRobot_Tone      DFTone;


// 主程序开始
void setup() {
      huskylens.beginI2CUntilSuccess();
      huskylens.writeAlgorithm(ALGORITHM_TAG_RECOGNITION);
      neoPixel_7.begin(7, 6);
      neoPixel_8.begin(8, 6);
      neoPixel_7.setBrightness(255);
      neoPixel_8.setBrightness(255);
      mind_n_N1 = 0;
      mind_n_N2 = 0;
      huskylens.clearOSD();
      delay(1000);
      huskylens.writeOSD(String("system is ok"), 84, 35);
      delay(1000);
}
void loop() {
      huskylens.request();

      DF_DingWeiShiBie();

      DF_PanDuanJieGuo();
}


// 自定义函数
void DF_DingWeiShiBie() {
      mind_n_N1 = (String(huskylens.readBlockParameterDirect(1).xCenter).toInt());
      mind_n_N2 = (String(huskylens.readBlockParameterDirect(2).xCenter).toInt());
      DF_N1XiaoYuN2();
      DF_N1DaYuN2();
}
void DF_CeLiangZuoBiao() {
      huskylens.writeOSD(String((String((String(mind_n_N1) + String("===="))) + String(mind_n_N2))), 103, 21);
      delay(1000);
}
void DF_N1DaYuN2() {
      if (((mind_n_N2 - mind_n_N1)<0)) {
                huskylens.clearOSD();
                mind_n_N1 = (String(huskylens.readBlockParameterDirect(2).ID).toInt());
                mind_n_N2 = (String(huskylens.readBlockParameterDirect(1).ID).toInt());
                huskylens.writeOSD(String((String((String(mind_n_N1) + String("-------"))) + String(mind_n_N2))), 20, 130);
                delay(500);
      }
}
void DF_N1XiaoYuN2() {
      if (((mind_n_N1 - mind_n_N2)<0)) {
                huskylens.clearOSD();
                mind_n_N1 = (String(huskylens.readBlockParameterDirect(1).ID).toInt());
                mind_n_N2 = (String(huskylens.readBlockParameterDirect(2).ID).toInt());
                huskylens.writeOSD(String((String((String(mind_n_N1) + String("-------"))) + String(mind_n_N2))), 20, 130);
                delay(500);
      }
}
void DF_PanDuanJieGuo() {
      // 军棋中军衔高低判定
      if ((((2<mind_n_N1) && (mind_n_N1<41)) && ((5<mind_n_N2) && (mind_n_N2<41)))) {
                DF_XiangDeng();
                DF_LXiaoYuR();
                DF_LDaYuR();
      }
      DF_GongBingChaiLei();
      DF_DiLeiChuLi();
      DF_ZhaDanChuLi();
      DF_KangQi();
}
void DF_MingChen() {
      if ((mind_n_N1==1)) {
                mind_s_M1 = "chess:";
      }
      if ((mind_n_N2==2)) {
                mind_s_M1 = "chess:";
      }
      if (((3<=mind_n_N1) && (mind_n_N1<=5))) {
                mind_s_M1 = "engineer:";
      }
      if (((6<=mind_n_N2) && (mind_n_N2<=8))) {
                mind_s_M2 = "engineer:";
      }
      if (((9<=mind_n_N1) && (mind_n_N1<=11))) {
                mind_s_M1 = "platoon:";
      }
      if (((12<=mind_n_N2) && (mind_n_N2<=14))) {
                mind_s_M2 = "platoon:";
      }
      if (((15<=mind_n_N1) && (mind_n_N1<=17))) {
                mind_s_M1 = "Company:";
      }
      if (((18<=mind_n_N2) && (mind_n_N2<=20))) {
                mind_s_M2 = "Company:";
      }
      if (((21<=mind_n_N1) && (mind_n_N1<=22))) {
                mind_s_M1 = "battalion :";
      }
      if (((23<=mind_n_N2) && (mind_n_N2<=24))) {
                mind_s_M2 = "battalion:";
      }
      if (((25<=mind_n_N1) && (mind_n_N1<=26))) {
                mind_s_M1 = "regimental ";
      }
      if (((27<=mind_n_N2) && (mind_n_N2<=28))) {
                mind_s_M2 = "regimental: ";
      }
      if (((29<=mind_n_N1) && (mind_n_N1<=30))) {
                mind_s_M1 = "brigade: ";
      }
      if (((31<=mind_n_N2) && (mind_n_N2<=32))) {
                mind_s_M2 = "brigade: ";
      }
      if (((33<=mind_n_N1) && (mind_n_N1<=34))) {
                mind_s_M1 = "teacher:";
      }
      if (((35<=mind_n_N2) && (mind_n_N2<=36))) {
                mind_s_M2 = "teacher:";
      }
      if ((mind_n_N1==37)) {
                mind_s_M1 = "army:";
      }
      if ((mind_n_N2==38)) {
                mind_s_M2 = "army:";
      }
      if ((mind_n_N1==39)) {
                mind_s_M1 = "commander:";
      }
      if ((mind_n_N2==40)) {
                mind_s_M2 = "commander:";
      }
      if (((41<=mind_n_N1) && (mind_n_N1<=43))) {
                mind_s_M1 = "mine:";
      }
      if (((44<=mind_n_N2) && (mind_n_N2<=46))) {
                mind_s_M2 = "mine:";
      }
      if (((47<=mind_n_N1) && (mind_n_N1<=48))) {
                mind_s_M1 = "bomb:";
      }
      if (((49<=mind_n_N2) && (mind_n_N2<=50))) {
                mind_s_M2 = "bomb:";
      }
}
void DF_DiLeiChuLi() {
      if ((((9<=mind_n_N1) && (mind_n_N1<=39)) && ((44<=mind_n_N2) && (mind_n_N2<=46)))) {
                huskylens.writeOSD(String("boom_RD"), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((41<=mind_n_N1) && (mind_n_N1<=43)) && ((12<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("boom_LD"), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((41<=mind_n_N1) && (mind_n_N1<=43)) && ((44<=mind_n_N2) && (mind_n_N2<=46)))) {
                huskylens.writeOSD(String("boom_LRD"), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
}
void DF_TongGuiYuJin() {
      neoPixel_7.setRangeColor(0, 6, 0xFF0000);
      neoPixel_7.setRangeColor(0, 6, 0xFF0000);
      DFTone.play(4, 131, 500);
      delay(1000);
      neoPixel_7.clear();
      neoPixel_8.clear();
}
void DF_ZuoBianSheng() {
      neoPixel_7.setRangeColor(0, 6, 0x00FF00);
      neoPixel_7.setRangeColor(0, 6, 0xFF0000);
      DFTone.play(4, 196, 500);
      delay(1000);
      neoPixel_7.clear();
      neoPixel_8.clear();
}
void DF_ZhaDanChuLi() {
      if ((((47<=mind_n_N1) && (mind_n_N1<=48)) && ((6<=mind_n_N2) && (mind_n_N2<=46)))) {
                huskylens.writeOSD(String("boom-LZ"), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((3<=mind_n_N1) && (mind_n_N1<=46)) && ((49<=mind_n_N2) && (mind_n_N2<=50)))) {
                huskylens.writeOSD(String("boom_RZ"), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((47<=mind_n_N1) && (mind_n_N1<=48)) && ((49<=mind_n_N2) && (mind_n_N2<=50)))) {
                huskylens.writeOSD(String("boom_LRZ"), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
}
void DF_YouBianSheng() {
      neoPixel_7.setRangeColor(0, 6, 0xFF0000);
      neoPixel_7.setRangeColor(0, 6, 0x00FF00);
      DFTone.play(4, 262, 500);
      delay(1000);
      neoPixel_7.clear();
      neoPixel_8.clear();
}
void DF_GongBingChaiLei() {
      if ((((3<=mind_n_N1) && (mind_n_N1<=5)) && ((44<=mind_n_N2) && (mind_n_N2<=46)))) {
                huskylens.writeOSD(String("L-CHAI"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if ((((41<=mind_n_N1) && (mind_n_N1<=43)) && ((6<=mind_n_N2) && (mind_n_N2<=8)))) {
                huskylens.writeOSD(String("R_CHAI"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
}
void DF_KangQi() {
      if (((1==mind_n_N1) && ((6<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("R-winner"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
      if (((2==mind_n_N2) && ((3<=mind_n_N1) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("L-winner"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
}
void DF_XiangDeng() {
      if ((((3<=mind_n_N1) && (mind_n_N1<=5)) && ((6<=mind_n_N2) && (mind_n_N2<=8)))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((9<=mind_n_N1) && (mind_n_N1<=11)) && ((12<=mind_n_N2) && (mind_n_N2<=14)))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((15<=mind_n_N1) && (mind_n_N1<=17)) && ((18<=mind_n_N2) && (mind_n_N2<=20)))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((mind_n_N1==21) || (mind_n_N1==22)) && ((mind_n_N2==23) || (mind_n_N2==24)))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((mind_n_N1==25) || (mind_n_N1==26)) && ((mind_n_N2==27) || (mind_n_N2==28)))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((mind_n_N1==29) || (mind_n_N1==30)) && ((mind_n_N2==31) || (mind_n_N2==32)))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if ((((mind_n_N1==33) || (mind_n_N1==34)) && ((mind_n_N2==35) || (mind_n_N2==36)))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if (((mind_n_N1==37) && (mind_n_N2==38))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
      if (((mind_n_N1==39) && (mind_n_N2==40))) {
                huskylens.writeOSD(String("====="), 5, 10);
                delay(1000);
                DF_TongGuiYuJin();
      }
}
void DF_LXiaoYuR() {
      if ((((3<=mind_n_N1) && (mind_n_N1<=5)) && ((12<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("R"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
      if ((((9<=mind_n_N1) && (mind_n_N1<=11)) && ((18<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("R"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if ((((15<=mind_n_N1) && (mind_n_N1<=17)) && ((23<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("R"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
      if ((((21<=mind_n_N1) && (mind_n_N1<=22)) && ((27<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("R"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
      if ((((25<=mind_n_N1) && (mind_n_N1<=26)) && ((31<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("R"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
      if ((((29<=mind_n_N1) && (mind_n_N1<=30)) && ((35<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("R"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
      if ((((33<=mind_n_N1) && (mind_n_N1<=34)) && ((38<=mind_n_N2) && (mind_n_N2<=40)))) {
                huskylens.writeOSD(String("R"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
      if (((mind_n_N1==37) && (mind_n_N2==40))) {
                huskylens.writeOSD(String("R"), 5, 10);
                delay(1000);
                DF_YouBianSheng();
      }
}
void DF_LDaYuR() {
      if ((((9<=mind_n_N1) && (mind_n_N1<=11)) && ((6<=mind_n_N2) && (mind_n_N2<=8)))) {
                huskylens.writeOSD(String("L"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if ((((15<=mind_n_N1) && (mind_n_N1<=17)) && ((6<=mind_n_N2) && (mind_n_N2<=14)))) {
                huskylens.writeOSD(String("L"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if ((((21<=mind_n_N1) && (mind_n_N1<=22)) && ((6<=mind_n_N2) && (mind_n_N2<=20)))) {
                huskylens.writeOSD(String("L"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if ((((25<=mind_n_N1) && (mind_n_N1<=26)) && ((6<=mind_n_N2) && (mind_n_N2<=24)))) {
                huskylens.writeOSD(String("L"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if ((((29<=mind_n_N1) && (mind_n_N1<=30)) && ((6<=mind_n_N2) && (mind_n_N2<=28)))) {
                huskylens.writeOSD(String("L"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if ((((33<=mind_n_N1) && (mind_n_N1<=34)) && ((6<=mind_n_N2) && (mind_n_N2<=32)))) {
                huskylens.writeOSD(String("L"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if (((mind_n_N1==37) && ((6<=mind_n_N2) && (mind_n_N2<=36)))) {
                huskylens.writeOSD(String("L"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
      if (((mind_n_N1==39) && ((6<=mind_n_N2) && (mind_n_N2<=38)))) {
                huskylens.writeOSD(String("L"), 5, 10);
                delay(1000);
                DF_ZuoBianSheng();
      }
}
</font>设备组装       第一步:3D打印棋子外壳结构件如下图25-27所示,取出 3颗强磁铁,将其安装在3个孔位。       第二步:取出切割好的棋子表面,将其安装在棋子外壳上,如下图28所示。       第三步:3D打印出擂台结构件,并拿出6颗强磁铁安装在对应的孔位上,如图30所示。具体安装磁铁的级性要与蓝橙色棋子匹配。例如,一侧擂台外露为N极,则对应棋子外露为S极;另一侧擂台外露为S极,则对应棋子外露为N极。安装后以后,使用棋子测试。       第四步:为Huskylens加装支架和铜柱,如下图32所示。       第五步:将Huskylens、蜂鸣器、擂台固定在棋盘上,如下图33所示。       第六步:用热熔胶将LED灯带安装固定到指示灯区域,如下图34所示。             第七步:将上步中的棋盘于底板侧板组合安装,主控固定在底板对应孔位,从而完成安装如图35所示。另外使用热熔胶将棋子收纳盒,粘贴完成如下图36所示。      第八步:启动MaixPy.ide编程软件,选择“工具”——“机器视觉”——“AprilTag生成器——TAG36H11”生成相应的标签如图37所示。               第九步:从生成标签中选取其中的50个标签,用热敏打印机打印出来,如下图38所示。      第十步:分配标签,以下表为依据将生成的标签依次分配给蓝方和橙方对应棋子。并将打印出的标签粘贴在棋子的顶部,如下图39所示。       6.系统测试       在测试前,先要完成对50个棋子标签的学习,嗯,这是个力气活,而且需要有耐心!具体操作这里不再赘述。系统加电对其进行测试,分别军衔PK(大于、等于、小于)、工兵拆雷、炸弹处理、地雷处理、工兵扛旗的所有情况进行测试,验证其结果的有效性。

老玩家 发表于 2021-8-29 23:04:03

感谢分享,这里特意注册账号提个缺点,看看有没有什么好的优化方式
       这个码毕竟是大家都能看到的信息,并且不是特别复杂(8x8?),
经常玩的话,很难不会去记住关键棋子的码征,比如对面司令

       之前也看到过市面上卖的智能军旗,应该用的是ic线圈判定的
(没有研究过,主要玩法是比大小的时候,双方将自己棋子放到棋盘中央的专用平台上就会出现结果)

不过这个读码识别还是挺新颖的,值得借鉴。

hnyzcj 发表于 2025-1-12 20:00:26

老玩家 发表于 2021-8-29 23:04
感谢分享,这里特意注册账号提个缺点,看看有没有什么好的优化方式
       这个码毕竟是大家都能看到的信息 ...

感谢感谢,目前以我能有器材和能力去解决这个问题。

hnyzcj 发表于 2021-8-30 10:44:27

老玩家 发表于 2021-8-29 23:04
感谢分享,这里特意注册账号提个缺点,看看有没有什么好的优化方式
       这个码毕竟是大家都能看到的信息 ...

是的,是的您说的很对,如果后面有时间继续修改

云天 发表于 2021-2-19 12:02:32

很好的作品,工程量也很大!

szjuliet 发表于 2021-2-20 07:55:23

这个作品太太天才了!
唤起了遥远的童年回忆。话说现在的小朋友还玩这种游戏吗?

hnyzcj 发表于 2021-2-20 08:20:54

szjuliet 发表于 2021-2-20 07:55
这个作品太太天才了!
唤起了遥远的童年回忆。话说现在的小朋友还玩这种游戏吗? ...


hnyzcj 发表于 2021-2-20 08:39:26

https://v.qq.com/x/page/p3228fhkgdf.html

还是很好玩的

发表于 2021-2-20 18:04:42

很好的项目

szjuliet 发表于 2021-2-20 20:57:08

hnyzcj 发表于 2021-2-20 08:39
还是很好玩的

哈哈,厉害厉害!

微笑的rockets 发表于 2021-2-26 10:46:09

用语音合成模块,或者mp3模块增加一个语音提示,另外可以把二哈的显示关掉。

hnyzcj 发表于 2021-2-26 16:05:14

微笑的rockets 发表于 2021-2-26 10:46
用语音合成模块,或者mp3模块增加一个语音提示,另外可以把二哈的显示关掉。 ...

YES

佛系唐法官 发表于 2021-2-26 17:03:48

这个项目非常的妙啊!以后可以两个人玩棋了!{:6_202:}

MRX 发表于 2021-2-28 15:50:05

这个项目真不错。

沧海笑 发表于 2021-3-10 10:36:26

非常好的创意与实践,完成度很高。赞

霹雳豆沙包 发表于 2021-7-4 20:53:44

怎么能想到这么好的创意!!!

刘昌胜 发表于 2021-9-29 11:26:23

有种回到童年的感觉,与科技结合

hmilycheng 发表于 2021-11-4 09:35:45

6666666666

丨偏执狂丨 发表于 2021-11-6 17:07:30

让人看着眼前一亮

QQQQQQQ 发表于 2022-1-5 14:56:24

厉害!!!!!!!!!!!!!!!!!!!!!!!!!

赤星三春牛! 发表于 2022-1-17 11:46:56

厉害!!!

淘气的一丁 发表于 2022-3-8 11:23:26

您好 老师··请问这个程序可以学习下么??
页: [1] 2
查看完整版本: 用Arduino制作智能军棋项目分享