亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino 井字棋游戏:MAX7219 点阵屏 + 纸板外壳 DIY

元器件清单

元器件数量备注
Arduino UNO1主控板
MAX7219 LED 点阵模块 (8×8)1显示棋盘与图案
薄膜按键键盘 (4×3)1玩家输入

所需工具

所需软件

项目简介

这是一个基于 Arduino 的井字棋游戏,使用 MAX7219 驱动的 8×8 LED 点阵显示棋盘,薄膜键盘输入坐标。外壳采用纸板和热熔胶自制,成本极低且极具创意。游戏支持双人对战,自动判断胜负并在屏幕显示获胜玩家编号,按键"0"可重置游戏。

Arduino 井字棋游戏:MAX7219 点阵屏 + 纸板外壳 DIY
完成品正面视图
Arduino 井字棋游戏:MAX7219 点阵屏 + 纸板外壳 DIY
侧面结构视图
Arduino 井字棋游戏:MAX7219 点阵屏 + 纸板外壳 DIY
背面电路布局

游戏规则与交互

硬件接线

模块Arduino 引脚
MAX7219 DIN12
MAX7219 CLK10
MAX7219 CS11
键盘行引脚 (4根)8, 7, 6, 5
键盘列引脚 (3根)4, 3, 2

完整代码

#include 
#include 
#include 
#include 

#define Reset_AVR() wdt_enable(WDTO_30MS); while(1) {}

// MAX7219: DIN=12, CLK=10, CS=11, 1个设备
LedControl lc = LedControl(12, 10, 11, 1);

bool player1 = true;           // 当前玩家标志
bool q[9] = {false};           // 9个位置是否已占用
int plays[3][3] = {{0}};       // 棋盘状态:0=空,1=玩家1,2=玩家2
int winner = 0;                // 获胜者:0=未分胜负,1=玩家1,2=玩家2

// 键盘映射
char hexaKeys[4][3] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[4] = {8, 7, 6, 5};
byte colPins[3] = {4, 3, 2};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, 4, 3);

void setup() {
  lc.shutdown(0, false);      // 唤醒 MAX7219
  lc.setIntensity(0, 0);      // 亮度最低(0-15)
  lc.clearDisplay(0);         // 清屏
}

void loop() {
  char key = customKeypad.getKey();
  painting(key);              // 处理落子
  win();                      // 检查胜负
  
  // 玩家1获胜显示
  if (winner == 1) {
    lc.clearDisplay(0);
    while (winner == 1) {
      char key = customKeypad.getKey();
      if (key == '0') Reset_AVR(); // 重启
      drawPlayer1Win();            // 显示"1"字样
    }
  }
  // 玩家2获胜显示
  else if (winner == 2) {
    lc.clearDisplay(0);
    while (winner == 2) {
      char key = customKeypad.getKey();
      if (key == '0') Reset_AVR();
      drawPlayer2Win();            // 显示"2"字样
    }
  }
}

// 切换玩家并返回当前玩家编号
int round_player() {
  if (player1) {
    player1 = false;
    return 1;
  } else {
    player1 = true;
    return 2;
  }
}

// 检查胜负
void win() {
  int p = (player1) ? 2 : 1; // 上一步落子的玩家
  // 检查行、列、对角线
  for (int i = 0; i < 3; i++) {
    if (plays[i][0]==p && plays[i][1]==p && plays[i][2]==p) { winner = p; return; }
    if (plays[0][i]==p && plays[1][i]==p && plays[2][i]==p) { winner = p; return; }
  }
  if (plays[0][0]==p && plays[1][1]==p && plays[2][2]==p) { winner = p; return; }
  if (plays[0][2]==p && plays[1][1]==p && plays[2][0]==p) { winner = p; return; }
}

// 点亮对应位置 LED 并记录落子
void switch_on_led(int col, int row, int colPlays, int rowPlays) {
  if (player1) { // 玩家1显示"\"
    lc.setLed(0, col, row, true);
    lc.setLed(0, col+1, row-1, true);
  } else {       // 玩家2显示"/"
    lc.setLed(0, col, row-1, true);
    lc.setLed(0, col+1, row, true);
  }
  plays[rowPlays][colPlays] = round_player();
}

// 按键处理
void painting(char key) {
  switch (key) {
    case '1': if (!q[0]) { switch_on_led(0,7,0,0); q[0]=true; } break;
    case '2': if (!q[1]) { switch_on_led(3,7,0,1); q[1]=true; } break;
    case '3': if (!q[2]) { switch_on_led(6,7,0,2); q[2]=true; } break;
    case '4': if (!q[3]) { switch_on_led(0,4,1,0); q[3]=true; } break;
    case '5': if (!q[4]) { switch_on_led(3,4,1,1); q[4]=true; } break;
    case '6': if (!q[5]) { switch_on_led(6,4,1,2); q[5]=true; } break;
    case '7': if (!q[6]) { switch_on_led(0,1,2,0); q[6]=true; } break;
    case '8': if (!q[7]) { switch_on_led(3,1,2,1); q[7]=true; } break;
    case '9': if (!q[8]) { switch_on_led(6,1,2,2); q[8]=true; } break;
    case '0': Reset_AVR(); break; // 重启游戏
  }
}

// 显示玩家1获胜图案("1")
void drawPlayer1Win() {
  lc.setLed(0,1,4,true); lc.setLed(0,2,5,true); lc.setLed(0,3,6,true);
  lc.setLed(0,4,7,true); lc.setLed(0,4,6,true); lc.setLed(0,4,5,true);
  lc.setLed(0,4,4,true); lc.setLed(0,4,3,true); lc.setLed(0,4,2,true);
  lc.setLed(0,4,1,true); lc.setLed(0,4,0,true); lc.setLed(0,5,0,true);
  lc.setLed(0,6,0,true); lc.setLed(0,3,0,true); lc.setLed(0,2,0,true);
}

// 显示玩家2获胜图案("2")
void drawPlayer2Win() {
  lc.setLed(0,2,0,true); lc.setLed(0,3,0,true); lc.setLed(0,4,0,true);
  lc.setLed(0,5,0,true); lc.setLed(0,2,1,true); lc.setLed(0,2,2,true);
  lc.setLed(0,2,3,true); lc.setLed(0,2,4,true); lc.setLed(0,3,4,true);
  lc.setLed(0,4,4,true); lc.setLed(0,5,4,true); lc.setLed(0,5,5,true);
  lc.setLed(0,5,6,true); lc.setLed(0,5,7,true); lc.setLed(0,4,7,true);
  lc.setLed(0,3,7,true); lc.setLed(0,2,7,true);
}

代码亮点

外壳制作提示

作者使用纸板和热熔胶制作外壳,建议:

  1. 先用纸板剪切面板,预留屏幕和键盘开孔
  2. 热熔胶固定电路板和模块,注意绝缘
  3. 可根据个人喜好设计造型(如作者的心形/宇宙主题)
  4. 留出 USB 口和电源开关位置

制造工艺

  1. 用 Arduino 打造绚丽显示器 Ambilight 系统
  2. 用 Arduino UNO 和 OLED 显示屏制作经典 Pong 游戏:分步教程
  3. 自制巨型乐高迷你人偶动画操作游戏:Arduino 控制舵机与音效
  4. Arduino 音频频率检测:基于 FFT 测量最响亮声音峰值
  5. 自制 Arduino 电子宠物「Tamaguino」:复刻经典 Tamagotchi 全攻略
  6. 智能无线开关控制器:Arduino + 433MHz 远程操控墙壁开关
  7. 基于 Arduino Nano 的智能运动感应水枪
  8. 使用 SparkFun 7 段数码管构建可靠的 Arduino 倒计时器
  9. 语音控制家电:Google Assistant + 蓝牙 + Arduino UNO
  10. Arduino 向日葵:制作电子向日葵追踪阳光
  11. 自制 Arduino 遥控保时捷赛车:从改装底盘到手机 App 控制全攻略
  12. Arduino 合成乐音:从零实现 88 键钢琴全音域