// 4桁7セグメントスロットマシン
// ピン定義
const int LATCH_PIN = 4; // 74HC595 STCP
const int CLOCK_PIN = 3; // 74HC595 SHCP
const int DATA_PIN = 2; // 74HC595 DS
const int DIGIT_PINS[] = {5, 6, 7, 8}; // 桁選択ピン
const int START_BTN = A0; // スタートボタン(緑)
const int STOP_BTN1 = A1; // ストップボタン1(赤)
const int STOP_BTN2 = A2; // ストップボタン2(赤)
const int STOP_BTN3 = A3; // ストップボタン3(赤)
const int LED_PINS[] = {9, 10, 11}; // 演出用LED
// 7セグメント数字パターン
const byte DIGIT_PATTERNS[] = {
0b11111100, // 0
0b01100000, // 1
0b11011010, // 2
0b11110010, // 3
0b01100110, // 4
0b10110110, // 5
0b10111110, // 6
0b11100000, // 7
0b11111110, // 8
0b11110110 // 9
};
// ゲーム状態
enum GameState {
IDLE,
SPINNING,
STOPPING1,
STOPPING2,
STOPPING3,
JACKPOT
};
GameState gameState = IDLE;
int reels[4] = {0, 0, 0, 0}; // 各リールの値
bool reelStopped[] = {false, false, false, false};
unsigned long lastUpdate = 0;
unsigned long jackpotStart = 0;
bool jackpotLedState = false;
void setup() {
// ピン初期化
pinMode(LATCH_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(DATA_PIN, OUTPUT);
for (int i = 0; i < 4; i++) {
pinMode(DIGIT_PINS[i], OUTPUT);
digitalWrite(DIGIT_PINS[i], HIGH); // 共通カソードなのでHIGHで消灯
}
for (int i = 0; i < 3; i++) {
pinMode(LED_PINS[i], OUTPUT);
digitalWrite(LED_PINS[i], LOW);
}
pinMode(START_BTN, INPUT_PULLUP);
pinMode(STOP_BTN1, INPUT_PULLUP);
pinMode(STOP_BTN2, INPUT_PULLUP);
pinMode(STOP_BTN3, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("🎰 スロットマシン開始!");
// 初期表示
reels[0] = 0; reels[1] = 0; reels[2] = 0; reels[3] = 0;
}
void loop() {
handleButtons();
updateGame();
updateDisplay();
delay(1);
}
void handleButtons() {
static bool startPressed = false;
static bool stop1Pressed = false;
static bool stop2Pressed = false;
static bool stop3Pressed = false;
// スタートボタン
if (!digitalRead(START_BTN) && !startPressed) {
startPressed = true;
if (gameState == IDLE || gameState == JACKPOT) {
startGame();
}
} else if (digitalRead(START_BTN)) {
startPressed = false;
}
// ストップボタン1
if (!digitalRead(STOP_BTN1) && !stop1Pressed) {
stop1Pressed = true;
if (gameState == SPINNING || gameState == STOPPING1) {
stopReel(1);
}
} else if (digitalRead(STOP_BTN1)) {
stop1Pressed = false;
}
// ストップボタン2
if (!digitalRead(STOP_BTN2) && !stop2Pressed) {
stop2Pressed = true;
if (gameState == SPINNING || gameState == STOPPING1 || gameState == STOPPING2) {
stopReel(2);
}
} else if (digitalRead(STOP_BTN2)) {
stop2Pressed = false;
}
// ストップボタン3
if (!digitalRead(STOP_BTN3) && !stop3Pressed) {
stop3Pressed = true;
if (gameState == SPINNING || gameState == STOPPING1 ||
gameState == STOPPING2 || gameState == STOPPING3) {
stopReel(3);
}
} else if (digitalRead(STOP_BTN3)) {
stop3Pressed = false;
}
}
void startGame() {
Serial.println("🎰 ゲーム開始!");
gameState = SPINNING;
// リール初期化
for (int i = 0; i < 4; i++) {
reelStopped[i] = false;
}
// LED消灯
for (int i = 0; i < 3; i++) {
digitalWrite(LED_PINS[i], LOW);
}
}
void stopReel(int reelNum) {
if (reelNum >= 1 && reelNum <= 3 && !reelStopped[reelNum]) {
reelStopped[reelNum] = true;
Serial.print("リール"); Serial.print(reelNum); Serial.println("停止!");
// ゲーム状態更新
if (reelNum == 1) gameState = STOPPING1;
else if (reelNum == 2) gameState = STOPPING2;
else if (reelNum == 3) gameState = STOPPING3;
// 全リール停止チェック
if (reelStopped[1] && reelStopped[2] && reelStopped[3]) {
checkJackpot();
}
}
}
void updateGame() {
if (millis() - lastUpdate < 100) return; // 100ms間隔で更新
lastUpdate = millis();
if (gameState == SPINNING || gameState == STOPPING1 ||
gameState == STOPPING2 || gameState == STOPPING3) {
// 回転中のリール更新
for (int i = 1; i <= 3; i++) {
if (!reelStopped[i]) {
reels[i] = random(0, 10);
}
}
}
// ジャックポット演出
if (gameState == JACKPOT) {
if (millis() - jackpotStart > 500) { // 500ms間隔で点滅
jackpotStart = millis();
jackpotLedState = !jackpotLedState;
// LED点滅
for (int i = 0; i < 3; i++) {
digitalWrite(LED_PINS[i], jackpotLedState ? HIGH : LOW);
}
}
}
}
void checkJackpot() {
Serial.print("結果: ");
for (int i = 1; i <= 3; i++) {
Serial.print(reels[i]);
}
Serial.println();
// 777チェック
if (reels[1] == 7 && reels[2] == 7 && reels[3] == 7) {
Serial.println("🎉 ジャックポット!!! 🎉");
gameState = JACKPOT;
jackpotStart = millis();
jackpotLedState = true;
// 即座にLED点灯
for (int i = 0; i < 3; i++) {
digitalWrite(LED_PINS[i], HIGH);
}
} else {
Serial.println("残念... もう一度挑戦!");
gameState = IDLE;
}
}
void updateDisplay() {
static int currentDigit = 0;
static unsigned long lastDisplayUpdate = 0;
if (millis() - lastDisplayUpdate < 2) return; // 2ms間隔で桁切り替え
lastDisplayUpdate = millis();
// 全桁消灯
for (int i = 0; i < 4; i++) {
digitalWrite(DIGIT_PINS[i], HIGH);
}
// ジャックポット時の点滅効果
if (gameState == JACKPOT && !jackpotLedState) {
return; // 点滅のため表示しない
}
// 現在の桁を表示
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, DIGIT_PATTERNS[reels[currentDigit]]);
digitalWrite(LATCH_PIN, HIGH);
digitalWrite(LATCH_PIN, LOW);
digitalWrite(DIGIT_PINS[currentDigit], LOW); // 現在の桁を点灯
currentDigit = (currentDigit + 1) % 4;
}