Project 3.06 Section 3 ⚡ Embedded Relevance: Core State Machines Enums Transition Matrix Modularity Game Logic

3.06 Modular Game State Loops, Enum Representations & Transition Matrices

Executive Summary: Building interactive decision trees and win/loss resolution matrices. We model cyclical dominance relationships (Rock beats Scissors, Scissors beats Paper, Paper beats Rock) using compact lookup matrices and clean scoped enums.

💻 1. Annotated Source Code

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {
	char userMove;
	char computerMove;

	srand(time(nullptr));

	cout << "Welcome to Rock, Paper, Scissors!" << endl;
	cout << "Enter your move (R, P, or S): ";
	cin >> userMove;

	int randNum = rand() % 3;

	if (randNum == 0) {
		computerMove = 'R';
	}
	else if (randNum == 1) {
		computerMove = 'P';
	}
	else {
		computerMove = 'S';
	}

	cout << "You played: " << userMove << endl;
	cout << "Computer played: " << computerMove << endl;

	if (userMove == computerMove) {
		cout << "It's a tie!" << endl;
	}
	else if (
			(userMove == 'R' && computerMove == 'S') ||
			(userMove == 'S' && computerMove == 'P') ||
			(userMove == 'P' && computerMove == 'R')
		) {
		cout << "You win!" << endl;
	}
	else {
		cout << "Computer wins" << endl;
	}


	return 0;
}

📐 2. Architecture & UML Class Model

📐 Rock Paper Scissors State Machine & Matrix Model
+ Public - Private # Protected
<<enum class : uint8_t>> HandMove Move Enum
+ROCK : uint8_t = 0
+PAPER : uint8_t = 1
+SCISSORS : uint8_t = 2
<<compilation-unit>> RpsGameEngine Decision Matrix
-userMove : HandMove
-cpuMove : HandMove
+determineWinner(p1: HandMove, p2: HandMove) : int32_t[1: P1, -1: P2, 0: Tie]
+generateCpuMove() : HandMove
🔗 Architectural Relationships & Hierarchy
RpsGameEngine ─ ─ > switches on ─ ─ > HandMove

📚 3. Core C++ Concepts Deep-Dive

1. Cyclical Win/Loss Dominance

Rock-Paper-Scissors represents a 3-state cyclical dominance ring. Rather than writing 9 nested if-else branches, the result can be computed via a $3\times 3$ transition lookup matrix.

⚡ 4. Embedded Systems & Hardware Reality

1. Lookup Matrix vs Conditional Branching

A $3\times 3$ matrix stored in Flash ROM resolves the winner in a single array access with 0 conditional branches, demonstrating lookup-table optimization.

💡 5. Production-Ready Embedded Refactoring

Zero-branch matrix lookup for game outcome:

💡 Production-Ready Refactor
#include <cstdint>

enum class Move : uint8_t { Rock = 0, Paper = 1, Scissors = 2 };
enum class Outcome : int8_t { Loss = -1, Tie = 0, Win = 1 };

// Stored in Flash ROM (.rodata)
constexpr Outcome OUTCOME_MATRIX[3][3] = {
    // Player: Rock, Paper, Scissors vs CPU:
    /* Rock */     { Outcome::Tie,  Outcome::Loss, Outcome::Win  },
    /* Paper */    { Outcome::Win,  Outcome::Tie,  Outcome::Loss },
    /* Scissors */ { Outcome::Loss, Outcome::Win,  Outcome::Tie  }
};

constexpr Outcome evaluateGame(Move player, Move cpu) noexcept {
    return OUTCOME_MATRIX[static_cast<size_t>(player)][static_cast<size_t>(cpu)];
}

📝 Knowledge Verification Quiz

Test your understanding of the C++ concepts and embedded microcontroller trade-offs covered in this guide. Click any option for instant feedback.

Q1. What is the advantage of using a 2D lookup table matrix over 9 nested if-else branches to resolve game outcomes?
A It evaluates the outcome in constant O(1) time with a single memory load and zero conditional branch instructions
B It uses more RAM
C It requires floating-point hardware
D It converts the game to multithreaded mode
Detailed Explanation: Matrix indexing (table[player][cpu]) executes in $O(1)$ time with zero branch instructions, eliminating branch misprediction penalties.
Q2. Why should scoped enum classes (enum class Move : uint8_t) be used instead of raw unscoped enums?
A They prevent accidental implicit conversions to integer and enforce strict type safety and specified 1-byte storage
B They run in parallel across CPU cores
C They allocate enums in the heap
D They make enums dynamic
Detailed Explanation: Scoped enum classes enforce explicit typing and prevent naming collisions and unsafe implicit promotions.
Q3. How much Flash ROM does a 3x3 lookup matrix of int8_t values consume?
A Exactly 9 bytes
B 36 bytes
C 1024 bytes
D 0 bytes
Detailed Explanation: A $3\times 3$ array of 1-byte integers takes exactly $3 \times 3 \times 1 = 9$ bytes in Flash ROM.
Q4. What is the mathematical modulo formula for cyclical Rock-Paper-Scissors win evaluation (0=Rock, 1=Paper, 2=Scissors)?
A (player - cpu + 3) % 3 (where 1 = Win, 2 = Loss, 0 = Tie)
B (player + cpu) % 2
C (player * cpu) % 3
D player / cpu
Detailed Explanation: The modular distance (player - cpu + 3) % 3 yields 0 for Tie, 1 for Player Win, and 2 for CPU Win.