Skip to content

Latest commit

ย 

History

History
402 lines (326 loc) ยท 10.7 KB

File metadata and controls

402 lines (326 loc) ยท 10.7 KB

Tech Stack - Solo Blackjack Game Documentation

๐Ÿ“– Overview

Tech Stack is a solo blackjack game built with Laravel and Vue.js, featuring programming technology cards instead of traditional playing cards. Players compete against an AI opponent to get as close to 21 points as possible without going over, using cards representing popular development tools and frameworks.

๐ŸŽฎ Game Mechanics

Core Rules

  • Goal: Beat the AI by getting as close to 21 points as possible without going over
  • Turn Flow: Player acts first (Hit or Stand), then AI plays automatically
  • Winning: Higher score โ‰ค 21 wins the round
  • Game Over: First loss ends the run; number of rounds survived = final score

Special Game Features

1. Full-Stack Jackpot

  • Trigger: Hand contains at least one card from each category:
    • Frontend (Vue.js, React, Alpine.js)
    • Backend (Laravel Core, Laravel Jetstream, Express.js)
    • Database (MySQL, PostgreSQL, Redis)
    • DevOps (Docker, Github Actions)
  • Effect: Auto-win the round, even if below 21 points
  • Strategy: Encourages variety, mirrors real-world tech stacks

2. Laravel Cloud Wild Card

  • Effect: Instantly sets hand total to exactly 21 (automatic stand)
  • Quantity: Only one card in the entire deck
  • Visual: Purple border and star indicator

3. Synergy Bonuses (+2 points)

Certain card combinations add +2 to your total without increasing bust threshold:

  • Vue.js + Vite
  • Laravel Core + MySQL
  • Laravel Jetstream + MySQL
  • React + Vite
  • Express.js + PostgreSQL
  • Docker + Github Actions
  • PEST + Laravel Core
  • PHPUnit + Laravel Core

AI Logic

  1. AI draws cards until total โ‰ฅ 16
  2. AI stands immediately if it achieves Full-Stack Jackpot
  3. Uses same bust rule (> 21)
  4. Cards are revealed sequentially with animation

Scoring System

  • Win: Current points + round points, then multiply by 1.5
  • Loss: Current points รท 2
  • Starting Points: 0 for new games
  • Carry Over: Points persist between rounds until loss

๐Ÿƒ Card Deck

Frontend Cards

  • Alpine.js: 2 points (alpine.jpg)
  • React: 4 points (react.jpg)
  • Vue.js: 4 points (vue.jpg)

Build/Utility Cards

  • Vite: 3 points (vite.jpg)
  • TailwindCSS: 3 points (tailwind.jpg)

Backend Cards

  • Laravel Core: 7 points (laravelcore.jpg)
  • Laravel Jetstream: 8 points (laraveljetstream.jpg)
  • Express.js: 4 points (expressjs.jpg)

Database Cards

  • MySQL: 4 points (mysql.jpg)
  • PostgreSQL: 4 points (postgresql.jpg)
  • Redis: 2 points (redis.jpg)

DevOps Cards

  • Docker: 3 points (docker.jpg)
  • Github Actions: 2 points (githubactions.jpg)

Testing Cards

  • PHPUnit: 2 points (phpunit.jpg)
  • Cypress: 3 points (cypress.jpg)
  • PEST: 4 points (pest.jpg)

Wild Card

  • Laravel Cloud: 21 points (instant win) (laravelcloud.jpg)

Total: 17 unique cards in deck

๐Ÿ—๏ธ Technical Architecture

Backend (Laravel 12)

  • Framework: Laravel 12 with PHP 8.2+
  • Database: SQLite (development) with Eloquent ORM
  • API: RESTful endpoints for game operations
  • Validation: Multi-layer input sanitization
  • Security: XSS protection, CSRF tokens

Frontend (Vue 3 + TypeScript)

  • Framework: Vue 3 with Composition API
  • Language: TypeScript for type safety
  • Styling: Tailwind CSS 4.x
  • UI Components: Custom component library with Reka UI
  • Build Tool: Vite 7
  • SPA: Inertia.js for seamless navigation

Database Schema

Cards Table

- id (primary key)
- name (string) - Card display name
- points (integer) - Point value
- category (string) - Card category
- image_filename (string) - Image file reference
- is_wild_card (boolean) - Wild card flag
- timestamps

Games Table

- id (primary key)
- user_id (foreign key, nullable) - Associated user
- player_hand (json) - Player's cards
- ai_hand (json) - AI's cards
- player_score (integer) - Player's current score
- ai_score (integer) - AI's current score
- round_number (integer) - Current round
- total_points (integer) - Accumulated points
- status (enum) - Game state
- player_turn (boolean) - Turn indicator
- game_over (boolean) - Game completion flag
- timestamps

Leaderboard Entries Table

- id (primary key)
- player_name (string) - Sanitized player name
- total_points (integer) - Final score
- rounds_survived (integer) - Rounds completed
- timestamps

๐ŸŽจ User Interface

Title Screen

  • Background: Casino image with 30% opacity overlay
  • Centerpiece: Large Laravel Core card display
  • Actions: Play button, Leaderboard button
  • Styling: Dark theme with casino atmosphere

Game Screen

  • Layout: Centered, responsive design
  • Score Display: Prominent header with current points and round
  • AI Hand: Top section with sequential card reveals
  • Player Hand: Bottom section with immediate card display
  • Actions: Hit/Stand buttons during play
  • Status: Win/lose messaging with continue options

Card Design

  • Size: 128x176px (32x44 Tailwind units)
  • Layout: Image on top (112px), info section below (64px)
  • Borders: Color-coded by category
  • Content: Card name, points, category
  • Special: Wild card star indicator

Leaderboard

  • Display: Top 10 scores in descending order
  • Columns: Rank, Player Name, Total Points, Rounds Survived
  • Styling: Medal indicators for top 3 positions
  • Navigation: Back to game button

๐Ÿ”’ Security Implementation

XSS Protection (Multi-Layer)

Backend Security

  1. Input Validation:

    'player_name' => 'required|string|max:255|regex:/^[a-zA-Z0-9\s\-_.]+$/'
  2. Sanitization:

    $sanitizedName = strip_tags(trim($request->player_name));
    $sanitizedName = htmlspecialchars($sanitizedName, ENT_QUOTES, 'UTF-8');
  3. Model Mutator:

    public function setPlayerNameAttribute($value) {
        $this->attributes['player_name'] = htmlspecialchars(
            strip_tags(trim($value)), ENT_QUOTES, 'UTF-8'
        );
    }

Frontend Security

  1. Real-time Input Filtering:

    const sanitizePlayerName = (event) => {
        event.target.value = event.target.value.replace(/[^a-zA-Z0-9\s\-_.]/g, '')
    }
  2. HTML5 Validation:

    <input pattern="[a-zA-Z0-9\s\-_.]+" maxlength="255" />
  3. Vue Template Safety: Uses {{ }} interpolation (auto-escapes HTML)

Allowed Characters

  • Letters (a-z, A-Z)
  • Numbers (0-9)
  • Spaces, hyphens (-), underscores (_), periods (.)
  • Blocked: HTML tags, special characters, scripts

๐Ÿ› ๏ธ Development Setup

Prerequisites

  • PHP 8.2+
  • Node.js 18+
  • Composer
  • NPM

Installation

# Clone repository
git clone [repository-url]
cd TechStack

# Install PHP dependencies
composer install

# Install Node dependencies
npm install

# Setup environment
cp .env.example .env
php artisan key:generate

# Database setup
php artisan migrate --seed

# Build assets
npm run build

# Start development server
php artisan serve

Development Commands

# Frontend development
npm run dev           # Vite dev server
npm run build         # Production build
npm run lint          # ESLint

# Backend development
php artisan serve     # Laravel dev server
php artisan migrate   # Run migrations
php artisan db:seed   # Seed database

# Testing
php artisan test      # Laravel tests

๐Ÿ”„ API Endpoints

Game Routes

  • GET / - Game title screen (homepage)
  • GET /game - Game title screen (alternative)
  • GET /game/leaderboard - Leaderboard display
  • POST /game/start - Start new game/round
  • PATCH /game/{game}/hit - Draw a card
  • PATCH /game/{game}/stand - End player turn
  • POST /game/submit-score - Submit leaderboard entry

Request/Response Examples

Start Game

POST /game/start
Body: {
    total_points: 0,    // Previous points (0 for new game)
    round_number: 1     // Round number (1 for new game)
}

Response: {
    game: {
        id: 1,
        player_hand: [...],
        ai_hand: [...],
        player_score: 8,
        ai_score: 12,
        // ... other game data
    }
}

Submit Score

POST /game/submit-score
Body: {
    player_name: "TechGamer",
    total_points: 450,
    rounds_survived: 5
}

Response: {
    entry: { ... },
    message: "Score submitted successfully!"
}

๐ŸŽฏ Features Implemented

Core Features โœ…

  • Solo blackjack gameplay
  • Tech stack themed cards
  • AI opponent with strategic logic
  • Point-based scoring system
  • Round-based progression

Special Mechanics โœ…

  • Full-Stack Jackpot (auto-win with all categories)
  • Laravel Cloud Wild Card (instant 21)
  • Synergy Bonuses (+2 for specific combinations)
  • Point multiplication/division system

User Experience โœ…

  • Casino-themed background
  • Sequential AI card reveals
  • Responsive card design with real images
  • Leaderboard system
  • Score submission
  • Continue/restart options

Technical Features โœ…

  • XSS protection (input sanitization)
  • CSRF protection
  • Form validation
  • Database persistence
  • RESTful API design
  • TypeScript type safety

๐Ÿš€ Deployment Considerations

Production Checklist

  • Environment variables configured
  • Database optimized (consider MySQL/PostgreSQL)
  • Assets compiled and optimized
  • HTTPS enabled
  • Rate limiting implemented
  • Backup strategy in place
  • Monitoring setup

Performance Optimizations

  • Database indexing on leaderboard queries
  • Asset compression and caching
  • Image optimization for card files
  • API response caching for static data

๐Ÿ“ Game Balance Notes

Point Values Rationale

  • High-value cards (Laravel Core: 7, Laravel Jetstream: 8): Reflect complexity and learning curve
  • Mid-value cards (Framework cards: 4): Balanced for standard hands
  • Low-value cards (Utilities: 2-3): Allow for flexible hand building
  • Wild card (Laravel Cloud: 21): Conference special, instant win

Difficulty Tuning

  • AI threshold of 16 provides reasonable challenge
  • 1.5x win multiplier encourages continued play
  • 0.5x loss penalty creates risk/reward tension
  • Full-Stack Jackpot encourages diverse card collection

๐Ÿ”ฎ Future Enhancement Ideas

Gameplay

  • Multiple difficulty levels (AI thresholds)
  • Daily challenges
  • Achievement system
  • Multiplayer modes

Technical

  • Real-time multiplayer with WebSockets
  • Progressive Web App (PWA) features
  • Mobile app versions
  • Social sharing integration

Content

  • Additional card sets (languages, cloud providers)
  • Seasonal events
  • Custom card creation tools
  • Historical stats tracking

Built with โค๏ธ using Laravel and Vue.js Documentation last updated: July 2025