Click on a game to jump to the code:
Copy and paste this code into the editor and then open the Serial Monitor.
#include <Arduino.h>
// Define specific values for moves to make code readable
enum Move {
NONE,
ROCK,
PAPER,
SCISSORS
};
// Function declarations
Move getComputerChoice();
void printWinner(Move user, Move computer);
const char* moveToString(Move move); // Helper to print names
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
// F() macro saves RAM by keeping strings in Flash memory
Serial.println(F("--- Rock, Paper, Scissors ---"));
Serial.println(F("Enter 'R' for Rock, 'P' for Paper, or 'S' for Scissors:"));
}
void loop() {
if (Serial.available() > 0) {
char input = Serial.read();
// Ignore newline and carriage return characters from the Serial Monitor
if (input == '\n' || input == '\r' || input == ' ') {
return;
}
Move userMove = NONE;
// Convert to uppercase for easier comparison
input = toupper(input);
switch (input) {
case 'R': userMove = ROCK; break;
case 'P': userMove = PAPER; break;
case 'S': userMove = SCISSORS; break;
default:
Serial.println(F("Invalid input. Please use R, P, or S."));
return; // Exit loop early
}
// If we have a valid move, play the game
Move compMove = getComputerChoice();
Serial.print(F("You chose: "));
Serial.println(moveToString(userMove));
Serial.print(F("Computer chose: "));
Serial.println(moveToString(compMove));
printWinner(userMove, compMove);
Serial.println(); // Empty line
Serial.println(F("Play again? (R/P/S):"));
}
}
Move getComputerChoice() {
int randNumber = random(0, 3); // random(min, max) - max is exclusive
if (randNumber == 0) return ROCK;
if (randNumber == 1) return PAPER;
return SCISSORS;
}
void printWinner(Move user, Move computer) {
if (user == computer) {
Serial.println(F("It's a tie!"));
}
// Logic for user winning
else if ((user == ROCK && computer == SCISSORS) ||
(user == SCISSORS && computer == PAPER) ||
(user == PAPER && computer == ROCK)) {
Serial.println(F("You win!"));
}
else {
Serial.println(F("You lose!"));
}
}
// Helper function to convert the Enum back to text for printing
const char* moveToString(Move move) {
switch (move) {
case ROCK: return "Rock";
case PAPER: return "Paper";
case SCISSORS: return "Scissors";
default: return "";
}
}
#include <Arduino.h>
int numberToGuess;
int numberOfTries;
// Using 'const' is good, but '#define' uses 0 memory
#define LOWER_BOUND 1
#define UPPER_BOUND 100
void startNewGame(); // Forward declaration
void setup() {
Serial.begin(9600);
// CRITICAL FIX: Reduce the wait time for input from 1000ms to 50ms
// This makes the game respond instantly when you press Enter.
Serial.setTimeout(50);
randomSeed(analogRead(0));
startNewGame();
}
void loop() {
// Check if data is available
if (Serial.available() > 0) {
// Peek at the first character without removing it
char c = Serial.peek();
// If the input is just a New Line (Enter key) or space, ignore it
if (c == '\n' || c == '\r' || c == ' ') {
Serial.read(); // Clear it from buffer
return; // Skip the rest of the loop
}
int guess = Serial.parseInt();
// 0 is returned on timeout or invalid text (like "abc")
// Since our range starts at 1, 0 is effectively an error code here.
if (guess == 0) {
Serial.println(F("Invalid input. Enter a number 1-100."));
// Clear any garbage text left in the buffer (like "abc")
while(Serial.available() > 0) Serial.read();
return;
}
numberOfTries++;
if (guess == numberToGuess) {
Serial.print(F("Correct! The number was "));
Serial.println(numberToGuess);
Serial.print(F("It took you "));
Serial.print(numberOfTries);
Serial.println(F(" tries."));
Serial.println(F("-------------------")); // Visual separator
startNewGame();
}
else if (guess < numberToGuess) {
Serial.println(F("Too low. Try again."));
}
else {
Serial.println(F("Too high. Try again."));
}
}
}
void startNewGame() {
// +1 is correct because the max is exclusive!
numberToGuess = random(LOWER_BOUND, UPPER_BOUND + 1);
numberOfTries = 0;
Serial.println(F("I'm thinking of a number between 1 and 100."));
}
#include <Arduino.h>
const int LOWEST_CARD = 2;
const int HIGHEST_CARD = 14; // 14 represents Ace
int currentCard;
int score = 0;
// Function Prototypes
void printCardName(int value);
int drawNewCard(int excludeCard);
void startNewGame();
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
Serial.println(F("--- HIGH or LOW ---"));
startNewGame();
}
void loop() {
if (Serial.available() > 0) {
char input = Serial.read();
// 1. Sanitize Input: Ignore Invisible characters
if (input == '\n' || input == '\r' || input == ' ') {
return;
}
// 2. Normalize Input: Force uppercase
input = toupper(input);
if (input == 'H' || input == 'L') {
// Draw the next card, ensuring it isn't a tie
int nextCard = drawNewCard(currentCard);
Serial.print(F("Next card is: "));
printCardName(nextCard);
Serial.println();
bool userWon = false;
if (input == 'H' && nextCard > currentCard) userWon = true;
else if (input == 'L' && nextCard < currentCard) userWon = true;
if (userWon) {
score++;
Serial.print(F("Correct! Score: "));
Serial.println(score);
// The next card becomes the current card for the next round
currentCard = nextCard;
Serial.println(F("-----------------------"));
Serial.print(F("Current card: "));
printCardName(currentCard);
Serial.println(F("\nHigher (H) or Lower (L)?"));
}
else {
Serial.print(F("WRONG! Game Over. Final Score: "));
Serial.println(score);
Serial.println(F("-----------------------"));
delay(1000); // Small pause before reset
startNewGame();
}
}
else {
// Handle invalid letters (like 'Z' or 'X')
Serial.println(F("Invalid input. Please enter 'H' or 'L'."));
}
}
}
void startNewGame() {
score = 0;
// Draw random card, -1 means "don't exclude anything" (first draw)
currentCard = drawNewCard(-1);
Serial.println(F("\nNEW GAME STARTED"));
Serial.print(F("The first card is: "));
printCardName(currentCard);
Serial.println(F("\nWill the next be Higher (H) or Lower (L)?"));
}
// Generates a random card.
// If excludeCard is passed, it ensures we don't draw a tie.
int drawNewCard(int excludeCard) {
int card;
do {
// max is exclusive, so we use +1
card = random(LOWEST_CARD, HIGHEST_CARD + 1);
} while (card == excludeCard);
return card;
}
// Instead of returning a String, we print directly to Serial.
// This saves a significant amount of RAM.
void printCardName(int value) {
switch (value) {
case 11: Serial.print(F("Jack")); break;
case 12: Serial.print(F("Queen")); break;
case 13: Serial.print(F("King")); break;
case 14: Serial.print(F("Ace")); break;
default: Serial.print(value); break;
}
}
#include <Arduino.h>
// Game Settings
const int WIDTH = 10; // Smaller grid = Smoother drawing
const int HEIGHT = 10;
struct Point {
int x;
int y;
};
// Game Variables
Point snake[100];
Point food;
int snakeLength;
char currentDir;
char nextDir;
unsigned long lastUpdate = 0;
bool gameOver = false;
int gameSpeed = 600; // Default to slower speed (Higher number = Slower)
void initGame();
void updateGame();
void spawnFood();
void printGame();
void handleInput();
void selectDifficulty();
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
selectDifficulty();
initGame();
}
void loop() {
if (gameOver) {
if (Serial.available()) {
while(Serial.available()) Serial.read(); // Clear buffer
selectDifficulty(); // Re-select speed on restart
initGame();
}
return;
}
handleInput();
if (millis() - lastUpdate > gameSpeed) {
lastUpdate = millis();
updateGame();
printGame();
}
}
void selectDifficulty() {
Serial.println(F("\n\n--- SNAKE GAME SETUP ---"));
Serial.println(F("Select Speed:"));
Serial.println(F("1. Slow (Easy)"));
Serial.println(F("2. Medium (Normal)"));
Serial.println(F("3. Fast (Hard)"));
Serial.println(F("Enter 1, 2, or 3:"));
Serial.println(F("Enter WASD to change direction."));
while (true) {
if (Serial.available() > 0) {
char c = Serial.read();
if (c == '1') { gameSpeed = 800; break; } // Very Slow
if (c == '2') { gameSpeed = 500; break; } // Normal
if (c == '3') { gameSpeed = 200; break; } // Fast
}
}
Serial.println(F("Game Starting..."));
delay(1000);
}
void handleInput() {
if (Serial.available() > 0) {
char c = Serial.read();
c = toupper(c);
// Filter out invisible characters to prevent lag
if (c == '\n' || c == '\r' || c == ' ') return;
// Buffer the direction to prevent suicide turns
if (c == 'W' && currentDir != 'S') nextDir = 'W';
if (c == 'S' && currentDir != 'W') nextDir = 'S';
if (c == 'A' && currentDir != 'D') nextDir = 'A';
if (c == 'D' && currentDir != 'A') nextDir = 'D';
}
}
void updateGame() {
currentDir = nextDir;
// Move body
for (int i = snakeLength - 1; i > 0; i--) {
snake[i] = snake[i - 1];
}
// Move Head
if (currentDir == 'W') snake[0].y--;
if (currentDir == 'S') snake[0].y++;
if (currentDir == 'A') snake[0].x--;
if (currentDir == 'D') snake[0].x++;
// Wall Collision
if (snake[0].x < 0 || snake[0].x >= WIDTH || snake[0].y < 0 || snake[0].y >= HEIGHT) {
gameOver = true;
Serial.println(F("\n!!! CRASHED !!! Press key to reset."));
return;
}
// Self Collision
for (int i = 1; i < snakeLength; i++) {
if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
gameOver = true;
Serial.println(F("\n!!! BIT TAIL !!! Press key to reset."));
return;
}
}
// Food Collision
if (snake[0].x == food.x && snake[0].y == food.y) {
snakeLength++;
spawnFood();
}
}
void spawnFood() {
bool onSnake;
do {
onSnake = false;
food.x = random(0, WIDTH);
food.y = random(0, HEIGHT);
for (int i = 0; i < snakeLength; i++) {
if (snake[i].x == food.x && snake[i].y == food.y) onSnake = true;
}
} while (onSnake);
}
void initGame() {
snakeLength = 3;
snake[0] = {WIDTH / 2, HEIGHT / 2};
snake[1] = {WIDTH / 2, HEIGHT / 2 + 1};
snake[2] = {WIDTH / 2, HEIGHT / 2 + 2};
currentDir = 'W';
nextDir = 'W';
gameOver = false;
spawnFood();
}
void printGame() {
// Use a String buffer to print the whole frame at once.
// This reduces the "flicker" effect significantly.
String frame = "";
// Clear screen (newlines)
for (int i = 0; i < 30; i++) frame += "\n";
frame += "Score: " + String(snakeLength - 3) + "\n";
frame += "------------\n"; // Top Wall
for (int y = 0; y < HEIGHT; y++) {
frame += "|"; // Left Wall
for (int x = 0; x < WIDTH; x++) {
bool isSnake = false;
// Check Head
if (x == snake[0].x && y == snake[0].y) {
frame += "O";
isSnake = true;
} else {
// Check Body
for (int i = 1; i < snakeLength; i++) {
if (x == snake[i].x && y == snake[i].y) {
frame += "o";
isSnake = true;
break;
}
}
}
if (!isSnake) {
if (x == food.x && y == food.y) frame += "X";
else frame += ".";
}
}
frame += "|\n"; // Right Wall + Newline
}
frame += "------------"; // Bottom Wall
Serial.println(frame);
}
#include <Arduino.h>
// Game States
enum State {
WAITING, // Waiting to start
PLAYER_TURN,
DEALER_TURN,
GAME_OVER
};
State currentState = WAITING;
// Hand Variables
int playerTotal = 0;
int playerAces = 0; // Tracks how many Aces we have counted as 11
int dealerTotal = 0;
int dealerAces = 0;
int dealerHiddenCard = 0; // To reveal later
// Function Prototypes
void startGame();
void hitPlayer();
void stand();
void playDealer();
int drawCard(int &aceCount);
void printCard(int value);
int getCardValue(int rawRank, int &aceCount);
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
Serial.println(F("--- ARDUINO BLACKJACK ---"));
Serial.println(F("Press 'D' to Deal"));
}
void loop() {
if (Serial.available() > 0) {
char input = Serial.read();
// Clean input
if (input == '\n' || input == '\r' || input == ' ') return;
input = toupper(input);
// STATE MACHINE
switch (currentState) {
case WAITING:
case GAME_OVER:
if (input == 'D') startGame();
else Serial.println(F("Press 'D' to deal."));
break;
case PLAYER_TURN:
if (input == 'H') hitPlayer();
else if (input == 'S') stand();
else Serial.println(F("Hit (H) or Stand (S)?"));
break;
case DEALER_TURN:
// Input ignored while dealer plays (logic happens automatically)
break;
}
}
}
void startGame() {
// Reset Variables
playerTotal = 0; playerAces = 0;
dealerTotal = 0; dealerAces = 0;
Serial.println(F("\n--------------------------"));
Serial.println(F("Dealing cards..."));
// Draw Player Cards
playerTotal += drawCard(playerAces);
playerTotal += drawCard(playerAces);
// Draw Dealer Cards
dealerTotal += drawCard(dealerAces); // Visible card
dealerHiddenCard = drawCard(dealerAces); // Hidden hole card
// Note: We don't add hidden card to dealerTotal yet to keep suspense!
// Show status
Serial.print(F("Dealer shows: "));
printCard(dealerTotal);
Serial.println(F(" [ ? ]"));
Serial.print(F("You have: "));
Serial.print(playerTotal);
Serial.println(F(" (Total)"));
// Instant Blackjack check
if (playerTotal == 21) {
Serial.println(F("BLACKJACK! You win 1.5x!"));
currentState = GAME_OVER;
return;
}
currentState = PLAYER_TURN;
Serial.println(F("Hit (H) or Stand (S)?"));
}
void hitPlayer() {
int newCard = drawCard(playerAces);
playerTotal += newCard;
// CHECK FOR SOFT ACE REDUCTION
// If we bust but have an Ace counted as 11, turn it into a 1
if (playerTotal > 21 && playerAces > 0) {
playerTotal -= 10;
playerAces--;
Serial.println(F("(Ace reduced to 1)"));
}
Serial.print(F("You drew: "));
printCard(newCard);
Serial.print(F(" -> New Total: "));
Serial.println(playerTotal);
if (playerTotal > 21) {
Serial.println(F("BUST! You lose."));
currentState = GAME_OVER;
Serial.println(F("Press 'D' to play again."));
}
}
void stand() {
Serial.println(F("You stand. Dealer's turn..."));
// Reveal Dealer's hidden card
dealerTotal += dealerHiddenCard;
// Check if dealer needs to reduce Ace immediately (e.g., Ace + Ace)
if (dealerTotal > 21 && dealerAces > 0) {
dealerTotal -= 10;
dealerAces--;
}
Serial.print(F("Dealer reveals: "));
printCard(dealerHiddenCard);
Serial.print(F(" -> Total: "));
Serial.println(dealerTotal);
currentState = DEALER_TURN;
playDealer();
}
void playDealer() {
delay(800); // Dramatic pause
// Dealer must hit on 16 or less
while (dealerTotal < 17) {
Serial.print(F("Dealer hits... "));
int card = drawCard(dealerAces);
dealerTotal += card;
if (dealerTotal > 21 && dealerAces > 0) {
dealerTotal -= 10;
dealerAces--;
}
printCard(card);
Serial.print(F(" -> Total: "));
Serial.println(dealerTotal);
delay(1000);
}
// Determine Winner
if (dealerTotal > 21) {
Serial.println(F("Dealer BUSTS! You Win!"));
} else if (dealerTotal > playerTotal) {
Serial.println(F("Dealer Wins."));
} else if (dealerTotal < playerTotal) {
Serial.println(F("YOU WIN!"));
} else {
Serial.println(F("Push (Tie)."));
}
currentState = GAME_OVER;
Serial.println(F("Press 'D' to play again."));
}
// Logic to simulate a real deck
int drawCard(int &aceCount) {
// Random 1 to 13 (Ace through King)
int rank = random(1, 14);
if (rank == 1) {
aceCount++; // Track that we have a reduction available
return 11;
} else if (rank > 10) {
return 10; // J, Q, K are all worth 10
} else {
return rank;
}
}
void printCard(int value) {
Serial.print(F("["));
if (value == 11) Serial.print("A");
else Serial.print(value);
Serial.print(F("]"));
}
#include <Arduino.h>
enum GameState {
IDLE,
WAITING_FOR_SIGNAL,
SIGNAL_GIVEN,
SHOW_RESULT
};
GameState state = IDLE;
unsigned long signalTime;
unsigned long randomDelay;
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
Serial.println(F("--- REFLEX TRAINER (Fixed) ---"));
Serial.println(F("1. Type 'S' and hit Enter to Start."));
Serial.println(F("2. Wait for 'GO!', then type anything and hit Enter FAST."));
}
void loop() {
char input = 0;
// --- INPUT FILTER ---
if (Serial.available() > 0) {
char raw = Serial.read();
// Only accept actual letters or numbers. Ignore Enter keys (\n, \r)
if (raw != '\n' && raw != '\r' && raw != ' ') {
input = raw;
}
}
switch (state) {
case IDLE:
if (toupper(input) == 'S') {
Serial.println(F("Get ready..."));
state = WAITING_FOR_SIGNAL;
randomDelay = millis() + random(2000, 6000);
}
break;
case WAITING_FOR_SIGNAL:
// FALSE START CHECK
// Since we filtered input above, 'input' will only be non-zero
// if you actually typed a letter/number.
if (input != 0) {
Serial.println(F("TOO EARLY! False start. Press 'S' to retry."));
state = IDLE;
}
else if (millis() >= randomDelay) {
Serial.println(F("\n!!! GO !!!"));
Serial.println(F("!!! GO !!!"));
Serial.println(F("!!! GO !!!"));
signalTime = millis();
state = SIGNAL_GIVEN;
}
break;
case SIGNAL_GIVEN:
if (input != 0) {
unsigned long reactionTime = millis() - signalTime;
Serial.print(F("Time: "));
Serial.print(reactionTime);
Serial.println(F(" ms"));
if (reactionTime < 200) Serial.println(F("Rank: PRO GAMER"));
else if (reactionTime < 300) Serial.println(F("Rank: AVERAGE"));
else Serial.println(F("Rank: SLOW"));
Serial.println(F("\nPress 'S' to go again."));
state = IDLE;
}
break;
}
}
#include <Arduino.h>
// --- PLAYER STATS ---
int playerHP = 20;
int maxHP = 20;
int playerGold = 0;
int potions = 1;
// Equipment Levels (0 = Basic)
int weaponTier = 0;
int armorTier = 0;
// Game State
bool inCombat = false;
int monsterHP;
int monsterMaxHP;
// Function Prototypes
void handleExploration(char cmd);
void handleCombat(char cmd);
void encounter();
void usePotion();
void printStats();
void printShop();
const char* getWeaponName(int tier);
const char* getArmorName(int tier);
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
Serial.println(F("\n========================================"));
Serial.println(F(" ARDUINO DUNGEON: COMPLETE "));
Serial.println(F("========================================"));
Serial.println(F("You stand at the entrance of the dark ruins."));
Serial.println(F("Commands: (E)xplore, (H)eal, (S)tats, (M)erchant"));
}
void loop() {
if (Serial.available() > 0) {
char input = toupper(Serial.read());
// Ignore invisible characters (newlines/spaces)
if (input == '\n' || input == '\r' || input == ' ') return;
if (inCombat) {
handleCombat(input);
} else {
switch (input) {
case 'E':
Serial.println(F("\nYou walk into the darkness..."));
delay(800);
encounter();
break;
case 'H':
usePotion(); // Safe healing (no monster attack)
break;
case 'S':
printStats();
break;
case 'M':
printShop();
break;
default:
Serial.println(F("Invalid Command. Try (E)xplore, (M)erchant, (S)tats."));
}
}
}
}
// --- ENCOUNTERS ---
void encounter() {
int roll = random(1, 101);
if (roll < 25) {
int foundGold = random(5, 15);
Serial.print(F("You found a chest! +"));
Serial.print(foundGold); Serial.println(F(" Gold."));
playerGold += foundGold;
}
else if (roll < 40) {
Serial.println(F("You found a Health Potion hidden in a crate!"));
potions++;
}
else {
// Combat Start
Serial.println(F("\n!!! A MONSTER APPEARS !!!"));
// Monsters get harder as you get better gear (Game Balancing)
int difficultyMod = (weaponTier + armorTier) * 2;
monsterMaxHP = random(2, 6) + difficultyMod;
monsterHP = monsterMaxHP;
Serial.print(F("Enemy HP: ")); Serial.println(monsterHP);
Serial.println(F("Action: (A)ttack, (H)eal, or (R)un?"));
inCombat = true;
}
}
// --- COMBAT LOGIC ---
void handleCombat(char cmd) {
bool playerActed = false;
// 1. PLAYER TURN
if (cmd == 'A') {
// Attack Calculation
int dmg = random(2, 7) + (weaponTier * 3);
monsterHP -= dmg;
Serial.print(F("You attack with your "));
Serial.print(getWeaponName(weaponTier));
Serial.print(F(" for ")); Serial.print(dmg); Serial.println(F(" dmg!"));
if (monsterHP <= 0) {
Serial.println(F("VICTORY! The monster bursts into smoke."));
int reward = random(5, 12);
Serial.print(F("You looted ")); Serial.print(reward); Serial.println(F(" Gold."));
playerGold += reward;
inCombat = false;
Serial.println(F("Back to exploration..."));
return;
}
playerActed = true;
}
else if (cmd == 'H') {
// Combat Healing
usePotion();
// You healed, but that counts as your turn!
playerActed = true;
}
else if (cmd == 'R') {
// Run Calculation
Serial.println(F("You scramble away into the shadows... Escaped!"));
inCombat = false;
return; // Exit function immediately (Monster doesn't get to hit you)
}
else {
Serial.println(F("Invalid Combat Command. Use A, H, or R."));
return;
}
// 2. MONSTER TURN
// Only happens if the player Attacked or Healed
if (playerActed && inCombat) {
int rawDmg = random(3, 9);
int reduction = (armorTier * 2);
int finalDmg = rawDmg - reduction;
if (finalDmg < 0) finalDmg = 0;
playerHP -= finalDmg;
Serial.print(F("The monster hits you! Damage: "));
Serial.print(rawDmg);
Serial.print(F(" (Blocked: ")); Serial.print(reduction); Serial.println(F(")"));
if (playerHP <= 0) {
Serial.println(F("\n=== YOU DIED ==="));
Serial.println(F("Press Reset button on Arduino to restart."));
while(1); // Freeze Game
}
Serial.print(F("Your HP: ")); Serial.println(playerHP);
}
}
// --- MERCHANT SYSTEM ---
void printShop() {
Serial.println(F("\n--- THE TRAVELING MERCHANT ---"));
Serial.print(F("Your Gold: ")); Serial.println(playerGold);
Serial.println(F("1. (P)otion - 15 Gold (Restores 15 HP)"));
Serial.println(F("2. (W)eapon Upgrade - 50 Gold"));
Serial.println(F("3. (A)rmor Upgrade - 50 Gold"));
Serial.println(F("Type 'P', 'W', or 'A' to buy. Type 'E' to leave."));
// Hijack the loop logic slightly to wait for shop input
while (true) {
if (Serial.available() > 0) {
char shopInput = toupper(Serial.read());
// Clear buffer junk
if (shopInput == '\n' || shopInput == '\r' || shopInput == ' ') continue;
if (shopInput == 'P') {
if (playerGold >= 15) {
playerGold -= 15;
potions++;
Serial.println(F("Bought a Potion!"));
} else Serial.println(F("Not enough gold!"));
}
else if (shopInput == 'W') {
if (weaponTier >= 3) {
Serial.println(F("Weapon is already Max Level!"));
} else if (playerGold >= 50) {
playerGold -= 50;
weaponTier++;
Serial.print(F("Equipped: ")); Serial.println(getWeaponName(weaponTier));
} else Serial.println(F("Not enough gold (Need 50)."));
}
else if (shopInput == 'A') {
if (armorTier >= 3) {
Serial.println(F("Armor is already Max Level!"));
} else if (playerGold >= 50) {
playerGold -= 50;
armorTier++;
Serial.print(F("Equipped: ")); Serial.println(getArmorName(armorTier));
} else Serial.println(F("Not enough gold (Need 50)."));
}
else if (shopInput == 'E') {
Serial.println(F("You leave the shop."));
break; // Exit the while loop
}
Serial.print(F("Gold remaining: ")); Serial.println(playerGold);
}
}
}
void usePotion() {
if (potions > 0) {
potions--;
playerHP += 15;
if (playerHP > maxHP) playerHP = maxHP; // Cap HP
Serial.println(F("Glug glug... You feel refreshed (+15HP)."));
Serial.print(F("HP: ")); Serial.print(playerHP); Serial.print(F("/")); Serial.println(maxHP);
} else {
Serial.println(F("You reach into your bag... but find no potions!"));
}
}
// --- HELPER FUNCTIONS ---
void printStats() {
Serial.println(F("\n--- CHARACTER SHEET ---"));
Serial.print(F("HP: ")); Serial.print(playerHP); Serial.print(F("/")); Serial.println(maxHP);
Serial.print(F("Gold: ")); Serial.println(playerGold);
Serial.print(F("Potions: ")); Serial.println(potions);
Serial.print(F("Weapon: ")); Serial.println(getWeaponName(weaponTier));
Serial.print(F("Armor: ")); Serial.println(getArmorName(armorTier));
Serial.println(F("-----------------------"));
}
const char* getWeaponName(int tier) {
switch(tier) {
case 0: return "Rusty Dagger";
case 1: return "Iron Sword";
case 2: return "Transmuted Spear";
case 3: return "Automail Arm"; // FMA Reference
default: return "God Killer";
}
}
const char* getArmorName(int tier) {
switch(tier) {
case 0: return "Cloth Shirt";
case 1: return "Leather Vest";
case 2: return "Chainmail";
case 3: return "Alchemist's Coat";
default: return "Force Field";
}
}