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.
- 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
- 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
- Effect: Instantly sets hand total to exactly 21 (automatic stand)
- Quantity: Only one card in the entire deck
- Visual: Purple border and star indicator
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 draws cards until total โฅ 16
- AI stands immediately if it achieves Full-Stack Jackpot
- Uses same bust rule (> 21)
- Cards are revealed sequentially with animation
- 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
- Alpine.js: 2 points (
alpine.jpg) - React: 4 points (
react.jpg) - Vue.js: 4 points (
vue.jpg)
- Vite: 3 points (
vite.jpg) - TailwindCSS: 3 points (
tailwind.jpg)
- Laravel Core: 7 points (
laravelcore.jpg) - Laravel Jetstream: 8 points (
laraveljetstream.jpg) - Express.js: 4 points (
expressjs.jpg)
- MySQL: 4 points (
mysql.jpg) - PostgreSQL: 4 points (
postgresql.jpg) - Redis: 2 points (
redis.jpg)
- Docker: 3 points (
docker.jpg) - Github Actions: 2 points (
githubactions.jpg)
- PHPUnit: 2 points (
phpunit.jpg) - Cypress: 3 points (
cypress.jpg) - PEST: 4 points (
pest.jpg)
- Laravel Cloud: 21 points (instant win) (
laravelcloud.jpg)
Total: 17 unique cards in deck
- 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
- 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
- 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- 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- id (primary key)
- player_name (string) - Sanitized player name
- total_points (integer) - Final score
- rounds_survived (integer) - Rounds completed
- timestamps- Background: Casino image with 30% opacity overlay
- Centerpiece: Large Laravel Core card display
- Actions: Play button, Leaderboard button
- Styling: Dark theme with casino atmosphere
- 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
- 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
- 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
-
Input Validation:
'player_name' => 'required|string|max:255|regex:/^[a-zA-Z0-9\s\-_.]+$/'
-
Sanitization:
$sanitizedName = strip_tags(trim($request->player_name)); $sanitizedName = htmlspecialchars($sanitizedName, ENT_QUOTES, 'UTF-8');
-
Model Mutator:
public function setPlayerNameAttribute($value) { $this->attributes['player_name'] = htmlspecialchars( strip_tags(trim($value)), ENT_QUOTES, 'UTF-8' ); }
-
Real-time Input Filtering:
const sanitizePlayerName = (event) => { event.target.value = event.target.value.replace(/[^a-zA-Z0-9\s\-_.]/g, '') }
-
HTML5 Validation:
<input pattern="[a-zA-Z0-9\s\-_.]+" maxlength="255" />
-
Vue Template Safety: Uses
{{ }}interpolation (auto-escapes HTML)
- Letters (a-z, A-Z)
- Numbers (0-9)
- Spaces, hyphens (-), underscores (_), periods (.)
- Blocked: HTML tags, special characters, scripts
- PHP 8.2+
- Node.js 18+
- Composer
- NPM
# 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# 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 testsGET /- Game title screen (homepage)GET /game- Game title screen (alternative)GET /game/leaderboard- Leaderboard displayPOST /game/start- Start new game/roundPATCH /game/{game}/hit- Draw a cardPATCH /game/{game}/stand- End player turnPOST /game/submit-score- Submit leaderboard entry
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
}
}POST /game/submit-score
Body: {
player_name: "TechGamer",
total_points: 450,
rounds_survived: 5
}
Response: {
entry: { ... },
message: "Score submitted successfully!"
}- Solo blackjack gameplay
- Tech stack themed cards
- AI opponent with strategic logic
- Point-based scoring system
- Round-based progression
- Full-Stack Jackpot (auto-win with all categories)
- Laravel Cloud Wild Card (instant 21)
- Synergy Bonuses (+2 for specific combinations)
- Point multiplication/division system
- Casino-themed background
- Sequential AI card reveals
- Responsive card design with real images
- Leaderboard system
- Score submission
- Continue/restart options
- XSS protection (input sanitization)
- CSRF protection
- Form validation
- Database persistence
- RESTful API design
- TypeScript type safety
- Environment variables configured
- Database optimized (consider MySQL/PostgreSQL)
- Assets compiled and optimized
- HTTPS enabled
- Rate limiting implemented
- Backup strategy in place
- Monitoring setup
- Database indexing on leaderboard queries
- Asset compression and caching
- Image optimization for card files
- API response caching for static data
- 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
- 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
- Multiple difficulty levels (AI thresholds)
- Daily challenges
- Achievement system
- Multiplayer modes
- Real-time multiplayer with WebSockets
- Progressive Web App (PWA) features
- Mobile app versions
- Social sharing integration
- 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