Skip to content

psaraiva/squash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

9 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽฎ Squash Game

project License

Go Report Card codecov

Language: Portuguรชs

A classic Squash game developed in Go (TinyGO) and compiled to WebAssembly (WASM), running directly in the browser without any plugins.


๐Ÿ“‘ Quick Navigation

๐Ÿ‘พ For Players:

๐Ÿ‘จโ€๐Ÿ’ป For Developers:

๐Ÿ—๏ธ For Software Engineers:


๐Ÿ“‹ About the Game

Squash is an arcade game where you control a paddle and must bounce the ball against the wall, preventing it from escaping through the left side. With each successful hit, you earn points and the game becomes progressively more challenging.

๐ŸŽฌ Game Preview

Squash Gameplay

๐Ÿ•น๏ธ How to Play

Objective

  • Bounce the ball with the paddle
  • Prevent the ball from escaping through the left side
  • Each hit earns you points (10 points)
  • Every 100 points, you advance to the next level and the ball gets faster
  • You start with 3 lives (default)

Controls

Note: The game requires a mouse or stylus (pen) for tablets. Touch controls are not supported.

  • Move paddle: Move the mouse (or stylus) vertically
  • Start game: Left click
  • Pause: Right click
  • Restart: Left click (on Game Over screen)

๐ŸŽ›๏ธ URL Configuration

You can customize the game through query parameters:

http://localhost:8080?debug=true&lives=5&level=10&boost=0.8&ballsize=0.7&fps=60

Available parameters:

Parameter Type Range Description
debug boolean true/false Enables debug mode with information
lives int 1 - 99 Initial number of lives
level int 0 - 50 Starting game level
boost float 0.0 - 1.0 Speed increment per level
ballsize float 0.0 - 1.0 Ball size scale
fps int 30 or 60 Frames per second (update rate)

โš™๏ธ Installation and Execution

๐Ÿ“ฆ Prerequisites and Installation (click to expand)

Prerequisites

Option 1: Local Execution

  • Go 1.23+
  • TinyGo (to compile to WASM)

Option 2: Docker Execution ๐Ÿณ

  • Docker installed

Installation

# Clone the repository
git clone https://github.com/psaraiva/squash.git
cd squash

Build and Execution

๐Ÿณ Option 1: Docker (Recommended)

Simpler! No need to install Go or TinyGo.

# Build and run in a single command
make docker-deploy

Access: http://localhost:8080

Available Docker commands:

make docker-build    # Build Docker image
make docker-run      # Run container
make docker-stop     # Stop and remove container
make docker-clean    # Remove container and image

๐Ÿ’ป Option 2: Local Execution

Requires Go 1.23+ and TinyGo installed.

# Install dependencies
go mod download

# Build and start local server
make web-deploy-local

# Or run commands separately:
make web-build        # Compile to WASM
make web-serve-start  # Start HTTP server

Access: http://localhost:8080

Cleanup:

make web-clean  # Remove compiled files (local)
๐Ÿงช Tests (click to expand)
# Run all tests with coverage
make go-test-all

# Run only unit tests
make go-test

# Run only WASM tests
make go-test-wasm

# Generate interface mocks
make go-mock

Coverage: 100% of statements tested


๐Ÿ—๏ธ Technical Data

For software engineers: This project demonstrates Clean Architecture and Hexagonal Architecture (Ports & Adapters) in Go with WebAssembly, 100% testable and extensible.

๐ŸŽฏ Technical Features (summary)
  • ๐ŸŒ Runs in the browser via WebAssembly
  • ๐ŸŽฎ Control via mouse or stylus (does not support touch)
  • ๐ŸŽš๏ธ Progressive level system with increasing difficulty
  • ๐ŸŽจ Clean and responsive interface
  • ๐Ÿ› Debug mode for developers
  • โš™๏ธ Customizable settings via query string
  • โœ… 100% test coverage
๐Ÿš€ Technology Stack (click to expand)

Core

  • Go 1.23 - Main programming language
  • TinyGo - Optimized compiler for WebAssembly
  • WebAssembly (WASM) - Technology to run Go code in the browser
  • JavaScript - Integration with browser APIs via syscall/js

Architecture

  • Clean Architecture - Clear separation of layers (domain, ports, adapters)
  • Hexagonal Architecture - Ports & Adapters pattern
  • Dependency Injection - Interfaces for decoupling
  • Strategy Pattern - Mouse input strategy

Testing

  • Go Testing - Native testing framework
  • Custom Mocks - Own implementation without external dependencies
  • Table-Driven Tests - Go-recommended testing pattern
  • TinyGo Test - WASM target compatible tests

Development

  • Make - Build and deployment automation
  • Docker - Containerization with multi-stage build
  • Go Modules - Dependency management
๐Ÿ—๏ธ Project Structure (click to expand)
squash/
โ”œโ”€โ”€ cmd/                  # Entry points (delivery interfaces)
โ”‚   โ””โ”€โ”€ wasm/             # WebAssembly implementation
โ”‚       โ”œโ”€โ”€ main.go       # Wire-up and initialization
โ”‚       โ””โ”€โ”€ index.html    # HTML interface
โ”‚
โ”œโ”€โ”€ internal/             # Domain core (business logic)
โ”‚   โ”œโ”€โ”€ app/              # Game engine and business rules
โ”‚   โ”‚   โ”œโ”€โ”€ config.go     # Configuration and default values
โ”‚   โ”‚   โ”œโ”€โ”€ engine.go     # Physics and game mechanics
โ”‚   โ”‚   โ””โ”€โ”€ game.go       # State and game entities
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ ports/            # Contracts/Interfaces
โ”‚       โ”œโ”€โ”€ config.go     # ConfigProvider interface
โ”‚       โ”œโ”€โ”€ renderer.go   # Renderer interface
โ”‚       โ””โ”€โ”€ mocks/        # Generated mocks
โ”‚
โ”œโ”€โ”€ pkg/                  # Reusable code (infrastructure)
โ”‚   โ””โ”€โ”€ adapters/         # Port implementations
โ”‚       โ”œโ”€โ”€ input/        # Input adapters
โ”‚       โ”‚   โ”œโ”€โ”€ wasm/     # WASM config loader
โ”‚       โ”‚   โ””โ”€โ”€ web/      # UI and rendering
โ”‚       โ””โ”€โ”€ output/       # Output adapters  
โ”‚           โ””โ”€โ”€ web/      # Canvas renderer
โ”‚
โ””โ”€โ”€ bin/                  # Compiled artifacts
    โ””โ”€โ”€ web/              # WASM assets
๐Ÿ“Š Architecture and Design Patterns (click to expand)

This project was developed following the principles of Clean Architecture and Hexagonal Architecture (Ports & Adapters), making the code highly testable, maintainable, and extensible for different platforms.

๐ŸŽฏ Architecture Layers

1. Core Domain (internal/app/)

  • Responsibility: Pure business logic, game rules, physics
  • Files: engine.go (physics and mechanics), game.go (state), config.go
  • Independent: Doesn't know infrastructure details (Web, CLI, etc)
  • Testable: 100% testable without external dependencies

2. Ports (internal/ports/)

  • Responsibility: Contracts/interfaces that the domain expects
  • Interfaces: ConfigProvider, Renderer
  • Dependency Inversion: Domain defines, adapters implement

3. Adapters (pkg/adapters/)

  • Responsibility: Concrete implementations of ports
  • Input Adapters:
    • input/wasm/config_loader.go - Reads config from query string
    • input/wasm/handler.go - Captures mouse events
    • input/web/ui.go - UI rendering logic
  • Output Adapters:
    • output/web/canvas.go - Canvas 2D Renderer
    • output/web/jscontext.go - Wrapper for syscall/js
  • Interchangeable: Easy to swap implementations without affecting the core

4. Entry Points (cmd/)

  • Responsibility: Composition (wire-up) and initialization
  • Minimal logic: Only instantiates and connects components

๐Ÿ”Œ Extensibility: New Implementations

The architecture allows easily creating new versions of the game for different platforms:

๐Ÿ–ฅ๏ธ Example: New Version

cmd/new/
  โ””โ”€โ”€ main.go                    # entry point

pkg/adapters/
  โ”œโ”€โ”€ input/new/
  โ”‚   โ”œโ”€โ”€ config_loader.go       # Reads config from flags/env
  โ”‚   โ””โ”€โ”€ keyboard.go            # Captures input
  โ””โ”€โ”€ output/new/
      โ””โ”€โ”€ renderer.go            # rendering

Usage example:

go run cmd/new/main.go

The core (internal/app) remains 100% unchanged!

๐Ÿงฉ SOLID Principles Applied

Principle Application in Project
SRP Each package has a single responsibility
OCP Extensible via new adapters without modifying the core
LSP Renderer, ConfigProvider interfaces are substitutable
ISP Small and focused interfaces
DIP internal/app depends on abstractions (ports), not implementations

๐ŸŽจ Design Patterns Used

  • Hexagonal/Ports & Adapters: Isolated core, adapters connect infrastructure
  • Dependency Injection: Components receive dependencies via constructor
  • Strategy Pattern: Mouse input strategy
  • Factory Pattern: NewSquash(), NewRenderer(), NewConfigLoader()
  • Template Method: Renderer.Render() with specific implementations

โœจ Architecture Benefits

โœ… Testability: Core testable without complex mocks (100% coverage)
โœ… Maintainability: Changes isolated to specific layers
โœ… Reusability: Game logic reusable on any platform
โœ… Evolution: Easy to add features without breaking existing code
โœ… Independence: Core doesn't depend on external frameworks
โœ… Portability: Same core for Web, CLI, Mobile, Desktop


License

This project is open source and available under the MIT License.

๐Ÿ‘จโ€๐Ÿ’ป Author

Developed by @psaraiva


Have fun playing! ๐ŸŽ‰