Skip to content

Portfolio · est. golden hour

George Zhang

CS at the University of Waterloo, building thoughtful software — from Android Automotive at Ford to computer-vision rehab tools and a few too many games.

Currently: Software Developer Intern @ Ford Motor Company

an explorable, pixel-art version

The Collection

Selected Work

A few things I've built — games, tools, and research apps. Step inside the museum to see them on pedestals.

No. 01

Portfolio Website

An interactive personal portfolio with two faces: a fast, content-first web portfolio at /, and a lazy-loaded pixel-art museum game you can step into — built on a custom HTML5 Canvas game engine with a 60fps requestAnimationFrame loop, tile-based AABB collision, A\ pathfinding, particle systems, and a procedurally generated map. Walk a character through auto-built themed rooms and open exhibits showcasing projects, skills, experience, and contact info; both faces render from a single content source. Other visitors drift through the museum as warm glowing "ghost" wisps — a lightweight multiplayer-presence feature that records anonymous movement paths and replays them with their own exhibit-visiting AI. Project, skills, and competitive-programming data (GitHub, LeetCode, DMOJ) refreshes automatically through a daily GitHub Actions pipeline. Built with Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS, and Upstash Redis. Dual experience — a fast static web portfolio and an explorable canvas museum, both driven by one projects.ts content source (edit once, both update).; Seamless portal — a continuous camera-pan transition hands off from the DOM site into the game and back, with a prefers-reduced-motion crossfade fallback.; Explorable museum — move with WASD / arrow keys / click-to-move / an on-screen touch joystick; press E to inspect glowing exhibits.; Ghost trails (multiplayer presence) — other visitors appear as drifting wisps that wander between exhibits and linger to "view" them; their paths are recorded, stored, and replayed back to future visitors.; Live, self-updating content — GitHub repos populate Projects + Skills (with skills also drawn from work experience and coursework) and LeetCode/DMOJ stats populate a competitive-programming panel — all refreshed daily, no manual edits.; Skills wing — skill-group orbs sized by how many skills each holds; click one to zoom in and reveal its skills as an auto-scrolling, infinite list. Each orb is one category, aggregated and de-duplicated across every project, work-experience entry, and coursework, with no hand-maintained allowlist.; Dynamic documents — résumé and transcript PDFs are parsed at build time into structured JSON, then served to themed popups.; Tactile web surface — a contextual custom cursor (an ink dot over anything clickable, a labelled disc over content, with light magnetism on buttons) plus a subtle canvas water-ripple background that flows as you move and ripples on tap — all motion-safe.; Atmosphere — a slow golden-hour day/night colour wash, ambient dust, footstep audio, a live minimap, and a hidden easter egg. Engine ↔ React split. A standalone canvas GameEngine runs the 60fps game loop and never imports React; it talks to the UI only through an onEvent callback. The web portfolio (SiteShell / Portfolio) is server-rendered for instant load, and the heavier GameCanvas is lazy-mounted only once a visitor steps inside. Rendering & world. The scene draws in three y-sorted passes (floor/walls → entities → glow) for a top-down 2.5D depth effect — entities further south draw last and appear in front. The whole museum map (rooms, doorways, perimeter walls) is procedurally generated from a list of branch definitions, so adding a room is one array entry. Movement uses tile-based AABB collision detection decoupled from tile type (sprites can overhang their tiles), and click-to-move / minimap taps run A\ pathfinding — 8-directional with diagonal corner-cut prevention and a line-of-sight string-pulling smoothing pass. Ghost trails. The engine samples the player's path; on leave it's POSTed to a route handler and stored in Redis (Upstash REST API) as a capped, trimmed list. New visitors fetch the recent paths and a GhostSystem replays them as additive-blended particle wisps that pathfind between exhibits, respect collisions, hover, and never revisit the same one — degrading gracefully to fully procedural wanderers when the store is empty or unconfigured.

TypeScriptJavaScriptTeXGitHub ActionsVitestFramer MotionNext.jsReact
No. 02

RAG Codebase

A code-aware retrieval-augmented generation (RAG) system for asking natural-language questions about a codebase and getting grounded, citation-backed answers. It chunks source on AST boundaries with tree-sitter (not character windows), retrieves with hybrid dense + BM25 search fused by Reciprocal Rank Fusion (with an optional cross-encoder and the measured-best listwise LLM reranker), builds a code graph (imports / calls / containment) with personalized PageRank for connected context, answers with Claude using [n] citations plus an LLM-as-judge faithfulness check, and — the centerpiece — ships a rigorous evaluation harness (recall@k / MRR / NDCG, bootstrap confidence intervals, paired significance tests). Provider-agnostic (Anthropic or any OpenAI-compatible endpoint, incl. local Ollama); semantic search via sentence-transformers embeddings with an optional HNSW (approximate nearest neighbor) backend for scale. New to RAG / embeddings / the eval methodology? Start with docs/LEARN.md, a from-scratch walkthrough. Design rationale lives in outline.md; the full measured write-up is RESULTS.md. language specs (Python, JS, TS, Go, Rust, Ruby, Java, C/C++, C, PHP, Kotlin, Scala, Swift, Lua, Bash, Perl, Objective-C) + a generic pattern classifier, with line-window fallback. by Reciprocal Rank Fusion; an optional cross-encoder and a validated listwise LLM reranker refine the pool (the cross-encoder is off by default — measured net-negative on code, §3d). resolution; personalized-PageRank traversal for connected, token-cheap context. don't cover this"), and a RAGAS-style faithfulness check that verifies each claim against its cited source. endpoint (OpenRouter, Together, Groq, Azure, local Ollama / LM Studio / vLLM). confidence intervals, paired-bootstrap significance, a holdout split, and ablations. (full retriever), so quality is validated off the self-made golden set. lever — it significantly sharpens ranking (MRR/NDCG, p<0.001) and lifts answer-correctness, with a setup-dependent recall gain. brute-force matmul is the default. hierarchical layouts) plus a live localhost server with persistent edits + reset. Cursor, Claude Desktop). (retry/backoff + timeouts), and secret hygiene (gitignored dotenv + secret scanner, CI). The pipeline is digest once, probe per query. At index time: discover files → AST-chunk → embed (header + code) into a vector store → tokenize into a BM25 index → build the code graph → persist. At query time: embed the question → dense + BM25 search → RRF fuse → (rerank) → grounded answer with citations → faithfulness verification. Design decisions, each empirically motivated: retrieves as noise. Chunks land on definition boundaries: methods are their own chunks, classes get a summary chunk, oversized functions are windowed carrying their signature, and a module chunk captures imports + top-level code. A chunk's id is its file:line location, so the retrieved unit is already its own citation. / docstring — the embedding then carries location and signature, exactly what code queries key off. (The header is embedded, not displayed.) embeddings smear together; BM25 nails them, aided by a code-aware tokenizer that splits getcurrentuser / getCurrentUser. Dense and lexical lists are fused by Reciprocal Rank Fusion (rank-based, so no score calibration). A cross-encoder reranker is wired in but off by default (measured net-negative on code retrieval — §3d); the listwise LLM reranker (--accurate) is the validated accuracy lever. connected chunks (callees, callers, imports, enclosing class) via a dictionary lookup, so the model gets a few precise neighbors plus a compact structural map instead of whole files. into atomic claims and checks each against its cited source (faithfulness = supported / total), backed by a free structural check that every [n] resolves to a real source. contribution, reported with confidence intervals and paired significance rather than vibes.

PythonGitHub ActionspipNumPyPyTorchOpenAI APIAnthropic APITransformers
No. 03

RLHF Pipeline

An end-to-end Reinforcement Learning from Human Feedback (RLHF) pipeline that reproduces the post-training recipe behind aligned large language models — supervised fine-tuning → reward modeling → PPO — with the reinforcement-learning core written from scratch in PyTorch: generalized advantage estimation (GAE), the clipped policy-gradient surrogate, a per-token KL-to-reference penalty, and an adaptive KL controller. It also implements DPO and GRPO as modern alternatives, plus LoRA parameter-efficient fine-tuning, multi-GPU training, and an independent LLM-as-judge evaluation. Built on HuggingFace Transformers for the backbone models and tokenizers; every reward-modeling and RL component is hand-implemented, not wrapped from a higher-level library. Three alignment methods, one codebase — PPO (reward-model-based RL), DPO (reward-model-free), and GRPO (critic-free, DeepSeek-style).; PPO written from scratch — on-policy rollouts, GAE, the clipped surrogate objective, clipped value loss, entropy bonus, per-token KL-to-reference reward shaping, and an adaptive KL controller.; Reward model — a scalar reward head on a pretrained trunk, trained with the Bradley-Terry pairwise preference loss, scored at the last real token (robust to left/right padding).; Supervised fine-tuning — teacher forcing with prompt-masked labels as the policy initializer and PPO reference.; Parameter-efficient fine-tuning — LoRA adapters everywhere via PEFT; the frozen RL reference is recovered by disabling the adapter (no second copy of weights).; Scales out — multi-GPU data parallelism via HuggingFace Accelerate (DDP-ready) and gradient checkpointing for the supervised trainers.; RL stability knobs — running reward normalization, length and missing-EOS penalties to curb reward hacking, and KL-vs-reward logging.; Checkpoint resume — optimizer, global step, and KL-controller state save and restore for long runs.; Independent evaluation — an LLM-as-judge win-rate computed via the Anthropic Claude API with position-bias control, alongside reward-model accuracy.; Optional fast rollouts — a flag-gated vLLM generation backend that auto-falls back to HuggingFace generation if unavailable.; Validated to actually optimize — unit tests for the RL/RM math plus an end-to-end harness that proves the reward model learns a separable signal and a PPO step increases the log-prob of positive-advantage tokens.; Laptop-to-GPU — runs a tiny end-to-end smoke test on a CPU in seconds; trains real models on a free Kaggle GPU. The repository mirrors the standard post-training stack. The RL and reward-modeling logic (GAE, the PPO surrogate, KL shaping, the Bradley-Terry / DPO / GRPO objectives) is implemented by hand; HuggingFace Transformers supplies only the pretrained backbones and tokenizers, and PEFT supplies optional LoRA. Reward model. A scalar head reads the trunk's last non-pad hidden state and is trained with −log σ(rchosen − rrejected), the maximum-likelihood objective of the Bradley-Terry preference model.; PPO reward shaping. Each response token's reward is a KL-to-reference penalty −β·(log π − log πref); the scalar reward-model score is added at the final token. β is adapted toward a target KL, which keeps the policy from drifting off-distribution while chasing reward (reward hacking).; Advantages. GAE(γ, λ) over the value head's per-token estimates, then whitened. Token/value alignment is handled explicitly: the log-prob and value of response token j come from the model output at position j−1.; DPO. Optimizes the same Bradley-Terry preference likelihood but with the implicit reward β·log(π/πref), removing the separate reward model and RL loop. Supports sigmoid / IPO / hinge losses and optional length normalization.; GRPO. Replaces the value critic with a group baseline — sample G responses per prompt, advantage = (reward − group mean) / group std — with an unbiased k3 KL penalty. Cheaper and stable; the DeepSeek-R1 recipe. Engineering notes.

PythonJupyter NotebookpipNumPyPyTorchAnthropic APITransformersTesting
No. 04

Web Agent

An autonomous LLM web agent built from scratch — a ReAct + reflection loop that drives a real headless browser (Playwright) over an accessibility-tree observation layer — paired with an honest evaluation harness over WebArena and Online-Mind2Web. The LLM layer is provider-agnostic (native Anthropic Claude / OpenAI / Gemini adapters plus a LiteLLM universal adapter for any other model), and the harness reports Wilson confidence intervals, pass@k, a failure taxonomy, and LLM-as-judge scoring. The scaffold is table stakes; the signal is the measurement — quantifying how much of any headline web-agent number comes from scoring methodology and task curation rather than capability. Claude Sonnet 4.6 driving the agent on a live Wikipedia task — search → navigate → extract → answer. (Frames from a real captured run.) action space, memory, and a ReAct loop; no agent-framework wrapper. ON vs OFF on identical tasks (the headline engineering contribution). LiteLLM universal adapter for any other model; swapping models is a config change. text, and pagination detection, with an optional Set-of-Marks screenshot modality. Online-Mind2Web LLM-as-judge, with 3-valued logic that never silently passes the unverifiable. taxonomy, and Matplotlib/pandas charts, all from reproducible JSONL trajectories. scoring, a verify-before-done gate, and site confinement. prompt caching. shopping subset the agent scores ~0.43 exact-match; a fair full-suite number would be mid-teens–30% (vs production ~60%, SOTA 71.6%, human ~78%). A solid from-scratch scaffold, not a production agent — and the writeup says exactly that. measurement/mechanism, not raw capability: +14pt from implementing WebArena's own fuzzymatch LLM scoring (I'd been under-counting "N/A" answers), +4pt from the one research-identified lever (an AgentOccam-style note scratchpad that cracked a 14-item extraction task). offline cross-evaluator audit holds the agent fixed and varies only the scorer: a deterministic, judge-free type-aware re-score lifts the 24-task WebArena number 0.43 → 0.61 (matching the LLM judge), and the substring-vs-type-aware disagreement is 100% one-directional (κ = 0.66) — substring systematically under-counts. That's the rule-based-under-counts direction (AgentRewardBench); the lenient WebJudge 100% on the realistic slice is the over-counts direction (Online-Mind2Web). Neither matches expert humans. scoring (strict exact-match vs lenient LLM judge), not venue — the same agent reads ~0.6 or ~1.0 depending on how you score it. but a cheaper budget/commit fix captured most of it; on saturated slices ON ≈ OFF. lowest cost; Opus matches at ~2×; Haiku is a false economy (worse and pricier). Bigger ≠ better. reported negative result); a real sandbox found three agent bugs the synthetic tests missed (all fixed). Full blow-by-blow numbers, CIs, and every caveat are in Measured results below. Every component is small and explainable: browser control, an accessibility-tree observation layer, a typed action space, a model-agnostic LLM client, and a ReAct + reflection loop. agent/ never imports eval/ — the agent doesn't know it's being benchmarked, which is what keeps the measurement honest and the agent reusable. testable module rather than a black-box framework call. it can be ablated ON vs OFF on the same tasks. adapters; any other model works through the LiteLLM universal adapter (Mistral, Llama via Ollama, Bedrock, Groq, …) via the adapter + factory pattern. Observations are a numbered list of interactable elements; the model can only act on a ref it actually saw, so hallucinated targets are caught before execution. The screenshot + vision modality is a fallback (fires when the a11y tree is empty/sparse or the agent is stuck) and how often it fires is a tracked metric. ReAct agent loop — perceive → plan → act → reflect cycle with step-budgeted termination; Reflection / self-correction — ablatable post-action self-critique that feeds the next plan;

PythonPlaywrightPandasMatplotlibOpenAI APIAnthropic APILiteLLMReact
No. 05

Rubiks Cube

An interactive 3D Rubik's Cube built from scratch in Processing 4 (Java / P3D OpenGL), with a from-scratch CFOP solver that solves any scramble and animates the solution move-by-move. The solver runs on a background thread, was property-tested against thousands of random scrambles, and uses no external cube or solving libraries. ▶ Watch the demo on YouTube Real-time 3D cube — 27 chamfered cubies with per-face lighting, beveled edges, and z-fight-free stickers, rendered in P3D (OpenGL).; Natural controls — grab any face and drag to turn it (ray-cast picking + axis-locked slice dragging), spin the whole cube to look around, or drive it from the keyboard.; From-scratch CFOP auto-solver — Cross → F2L → OLL → PLL, no external libraries. Solve the whole thing automatically, or step through it one move at a time.; Runs off the UI thread — the solver computes on a background worker so the interface never freezes; the solution is streamed into the animation queue when ready.; Polished UX — scramble, timer with persisted best time, move counter, undo (animated, reaches back through scrambles and solves), light/dark themes that follow the OS, and cross-platform fonts/labels (macOS · Windows · Linux). A complete CFOP ("Fridrich method") pipeline implemented over the cube's sticker model: The whole pipeline was validated against thousands of random scrambles (a standalone Java port of the cube + solver) before shipping — 0 failures over 1500 scrambles. A hidden t key re-runs that self-check live from the console. While building the solver I discovered the cube model itself was subtly wrong: it passed casual play but failed the classic identity (R U R' U')⁶ = solved. Property-style testing (checking cubie groupings across thousands of scrambles, then move-order identities) isolated a corner-cycling bug that was invisible to edges and centers — a reversed strip in two of the turn functions. Fixing it made the model a mathematically valid cube and the solver correct. The sketch is split into focused tabs: 3D graphics programming — real-time P3D / OpenGL rendering of 27 chamfered cubies with lighting and bevels; Ray-cast picking — face selection via ray–geometry intersection; Interaction design — axis-locked slice dragging for natural click-and-drag face turns; Algorithm design — a from-scratch CFOP (Cross → F2L → OLL → PLL) solver with no libraries; Breadth-first search — optimal cross over a reduced ~190k state space; State-space reduction — cross-preserving F2L search and bounded last-layer coset searches; Multithreading & concurrency — solver runs on a background worker; the UI thread never blocks; Producer–consumer queue — one animation queue fed by scramble, solve, step, and undo; Property-based testing — validated over 1500+ random scrambles with a standalone Java port (0 failures); Debugging with invariants — isolated a corner-cycling bug via move-order identities ((R U R' U')⁶); Object-oriented design — focused modules for cube, solver, renderer, input, and raycasting; Data modelling — six char[3][3] faces and the 18 canonical face turns; Persistence — best time and theme saved as JSON in the home directory; Cross-platform packaging — jpackage produces self-contained apps for macOS, Windows, and Linux; CI/CD automation — GitHub Actions builds and attaches all three OS apps on v tags; UX engineering — animated undo through scrambles/solves, OS-following dark mode, live timer Java; Processing 4 (PApplet, P3D renderer); OpenGL via JOGL / GlueGen (the P3D backend); Python (a small build-time sketch preprocessor); jpackage (self-contained native app bundles); GitHub Actions (multi-OS release CI); JSON persistence (~/.rubikscubeprefs.json) 📺 Watch the demo on YouTube; ⬇️ Download the latest release

ProcessingGitHub ActionsConcurrencyTesting3D GraphicsJavaROpenGL

Archive

No. 11

Biquadris

A two-player competitive Tetris variant built in C++ with an object-oriented design. Originally developed as a final project for CS 246: Object-Oriented Software Development at the University of Waterloo (Fall 2025) by a team of three students, then refactored and extended into a cross-platform, SDL2-rendered game. The game has since been refactored and extended beyond the original submission: bugs fixed, the X11 graphics layer replaced with SDL2 for cross-platform support, and the build system migrated to CMake for easy packaging. Biquadris is a turn-based, two-player spin on Tetris. Both players share one screen — each managing their own 11×18 board. Players alternate turns: you make one move, then your opponent does. Clear two or more lines in a single drop and you earn a special action to punish your opponent. The game ends when a player can no longer place a new block. The codebase is organized around a small set of well-encapsulated classes. Game owns the two Board models and drives the turn loop; each Board tracks its grid, score, level, and active effects; Block encodes the seven tetromino shapes and their rotations; Level generates the next block according to the current difficulty; and the rendering is handled by interchangeable views — a TextDisplay for the terminal and an SDL2 Xwindow for graphics. Two design ideas carry most of the weight. Special actions are a polymorphic effect system (Strategy-style): an abstract Effect base class declares apply, onDrop, isExpired, and getName, and concrete BlindEffect, HeavyEffect, and ForceEffect subclasses implement each behaviour. An EffectManager holds the active effects per board, applies them on activation, ticks them after every drop, and retires them when they expire — so new actions can be added without touching the board logic. The model is fully decoupled from the views: the boards know nothing about how they're drawn, so the same game state renders identically to the terminal or to SDL2. Memory is managed entirely through std::uniqueptr (RAII — no manual new/delete), collision detection validates every move and rotation against the walls and settled cells before committing it, and a single codebase compiles either text-only or with graphics via conditional compilation (ifdef BIQUADRISGRAPHICS). Commands are parsed with unique-prefix matching and numeric multipliers, the high score persists between sessions, and a ghost-block preview shows where the current piece will land. Clearing 2 or more lines in a single drop earns a special action against your opponent: Line clear: (currentlevel + linescleared)² points; A block that scores zero lines resets the combo; clearing any lines resets the no-clear counter (relevant for Level 4 penalty blocks); High score is saved across sessions in .biquadrishighscore Object-oriented design — encapsulated Game, Board, Block, Level, and Effect classes; Polymorphism & abstract base classes — Effect interface with Blind / Heavy / Force subclasses; Inheritance — virtual methods and virtual destructors across the effect hierarchy; Strategy-style effect system — runtime special actions managed by an EffectManager; Model–view separation (MVC) — board state decoupled from the text and SDL2 renderers; RAII & smart pointers — std::uniqueptr ownership throughout, no manual memory management; Modern C++20 — const-correctness, standard containers, move semantics; Collision detection — move and rotation validation against walls and settled cells; Conditional compilation — one codebase builds text-only or with SDL2 graphics; Command parsing — unique-prefix matching with numeric multipliers; File I/O — high-score persistence and script-driven block sequences; Cross-platform build system — CMake with Homebrew SDL2 discovery on macOS; CI/CD release automation — GitHub Actions builds and bundles a distributable macOS app; Game logic — line clearing, level progression, ghost-block preview, and squared scoring C++20;

C++GitHub ActionsCMake
No. 12

Minesweeper

A fully-featured Minesweeper clone built in Java with a custom dark-themed UI, a probability-based AI solver, BFS flood-fill reveals, and dynamic tile scaling. Custom rendered board — 3D bevel tiles drawn with Graphics2D, distinct highlight/shadow edges for unrevealed vs. revealed states; Probability-based AI solver — constraint propagation fixpoint loop deduces guaranteed mines; remaining cells ranked by local mine probability; random tie-breaking when probabilities are equal; Auto Solve mode — checkbox triggers the AI on a 500 ms Swing Timer; runs on the EDT without blocking the UI; Configurable grid — dialog lets you set columns, rows, and mine count; tile size auto-scales to fill the screen while keeping tiles between 20–60 px; Restart — resets board, AI state, and mine counter without reopening the setup dialog; Instructions dialog — in-game "How to Play" reference; Dynamic mine counter — tracks remaining unflagged mines in real time; Platform-aware icon — programmatically generated app icon reusing the same drawRaised / drawMine helpers; set on the macOS dock via the Taskbar API The game logic, AI, and UI are kept in separate classes (MineSweeper, AI, Main). Revealing an empty cell triggers a BFS flood-fill that cascades outward through all connected zero-count cells, opening their neighbours in one sweep. The AI solver runs a constraint-propagation fixpoint loop: it repeatedly scans every numbered cell, and whenever a cell's number equals its count of adjacent unknowns it flags those as guaranteed mines (and conversely opens cells that are provably safe), iterating until no new deductions are possible. When pure deduction stalls, it falls back to probabilistic reasoning — ranking the remaining unknown cells by their local mine probability and breaking ties randomly — so it can keep making the statistically best move. Auto-solve mode steps this engine on a 500 ms Swing Timer, entirely on the Event Dispatch Thread so the UI never freezes. Object-oriented design — game logic, AI solver, and UI in separate classes; Event-driven programming — Swing mouse and window listeners, timer-driven auto-solve; 2D rendering — Graphics2D 3D-bevel tiles with highlight/shadow edges; BFS flood-fill — cascading reveal of connected zero-count cells; Constraint-propagation solver — fixpoint deduction of guaranteed mines and safe cells; Probabilistic reasoning — local mine-probability ranking with random tie-breaking; Algorithm design — combined deterministic + probabilistic AI strategy; Dynamic UI scaling — tile size auto-scales (20–60 px) to grid and screen size; Procedural graphics — programmatically generated app icon and dock integration via Taskbar; Input handling — mouse listener for reveal/flag, window listener for lifecycle; Layout management — Swing layout managers and SpringUtilities; JAR packaging — distributed as a standalone runnable JAR Java 17; Java Swing / AWT (JFrame, JPanel, Graphics2D, javax.swing.Timer, layout managers); Taskbar API for the macOS dock icon; Packaged as a standalone runnable JAR (MineSweeper.jar)

JavaSwingObject-oriented design
No. 13

Image To Text

A desktop Java application that converts raster images into ASCII art in real time. Built from scratch with a fully custom Swing GUI, an off-screen rendering pipeline for O(1) scroll/zoom, background processing via SwingWorker, and smooth zoom/pan interaction. The app takes any JPG, PNG, or GIF image, converts each pixel to a grayscale luminance value using the Rec. 601 standard, and maps it to one of 70 ASCII characters ordered by visual density (Paul Bourke gradient). The result is rendered into a scrollable, zoomable panel and the intermediate grayscale image is saved to disk automatically. Conversion reads pixels directly from a BufferedImage (getRGB), computes per-pixel luminance with the Rec. 601 luma coefficients (0.299R + 0.587G + 0.114B), and maps each value through a static lookup table to one of 70 density-ordered ASCII characters. The hot pixel loop uses a StringBuilder for O(n) assembly, and the whole conversion runs on a SwingWorker so the UI never blocks. The rendered ASCII is drawn once into an off-screen buffer, so scrolling and zooming stay O(1) regardless of image size — nearest-neighbor interpolation keeps it crisp when zoomed in, bilinear keeps it smooth when zoomed out. Interaction is handled with a MouseAdapter for drag-to-pan (using screen coordinates for stable deltas) and getPreciseWheelRotation for smooth Ctrl+scroll zoom, with an InputMap/ActionMap shortcut system scoped to the focused window. Swing GUI from scratch — custom layouts, components, and event handling; Multithreading & concurrency — SwingWorker keeps the UI responsive during conversion; Off-screen rendering — pre-rendered BufferedImage makes scroll and zoom O(1) at any image size; Image processing — pixel-level RGB manipulation via getRGB / setRGB; Grayscale conversion — Rec. 601 luma coefficients (0.299R + 0.587G + 0.114B); Algorithm/data-structure use — static lookup table for the brightness → character mapping; Image scaling — SCALESMOOTH downscaling with zoom-aware nearest-neighbor / bilinear interpolation; Keyboard shortcut system — InputMap / ActionMap with WHENINFOCUSEDWINDOW scope; Performance optimization — StringBuilder over concatenation in hot pixel loops for O(n); Pan & zoom UX — drag-to-pan, precise Ctrl+scroll zoom, and fit-to-window on every transform; Layout management — responsive nested BorderLayout so zoom controls stay visible at any width; Error handling — IOException propagation with user-facing dialogs, no silent failures; Object-oriented design — separate converter, text panel, and prompt components; JAR packaging — distributed as a standalone runnable JAR Java 17+; Java Swing / AWT (BufferedImage, Graphics2D, SwingWorker, InputMap / ActionMap, MouseAdapter); Packaged as a standalone runnable JAR (ImageToText.jar)

JavaConcurrencyProcessing
No. 14

Instagram Non Follower Finder

A desktop app that automates finding Instagram accounts you follow that don't follow you back. Built with Python, Selenium WebDriver, and CustomTkinter — it drives a real browser to scroll and extract your follower/following lists, applies hand-rolled anti-bot stealth, and presents the diff in a clean dark-mode GUI with cross-browser support. Cross-browser — Chrome, Firefox, Edge, Safari; Stealth mode — patches automation fingerprints to reduce bot detection across browsers; Manual login flow with full 2FA and captcha support; Auto-downloads browser drivers (no PATH setup required); Accumulates users across virtual-scroll batches so no one is missed; Results copyable to clipboard The app launches a real browser through Selenium WebDriver and lets you log in manually (so 2FA and captchas just work). To reduce automation detection, it injects a small stealth script that redefines navigator.webdriver — via the Chrome DevTools Protocol (Page.addScriptToEvaluateOnNewDocument) on Chromium browsers and executescript on Firefox — alongside flags like --disable-blink-features=AutomationControlled and Firefox's dom.webdriver.enabled = false. It then opens your followers and following dialogs and uses ActionChains with ScrollOrigin to scroll the virtual-scrolling lists, accumulating usernames across batches until the full list is captured. A set difference between following and followers yields the accounts that don't follow you back. All of this runs on a background threading worker so the CustomTkinter UI stays responsive, with per-browser error dialogs when a driver fails to start. Browser automation — Selenium WebDriver driving Chrome, Firefox, Edge, and Safari; Cross-browser abstraction — per-browser options and driver setup behind one flow (match/case); Anti-bot stealth — CDP navigator.webdriver patching and disabling automation fingerprints; Dynamic web scraping — ActionChains + ScrollOrigin to drive virtual-scroll list extraction; Set operations — diff of following vs. followers to surface non-followers; Multithreading & concurrency — background threading worker keeps the GUI responsive; GUI development — CustomTkinter dark-mode desktop interface; Robust error handling — per-browser driver-failure dialogs and captcha/2FA-friendly login; Automatic driver management — webdriver-manager for Firefox/Edge; Chrome 115+ self-manages; Clipboard integration — one-click copy of results; Application packaging — PyInstaller native build via build.py Python 3.10+ (match/case); Selenium WebDriver (Chrome, Firefox, Edge, Safari); CustomTkinter (dark-mode GUI); webdriver-manager (Firefox / Edge driver management); Chrome DevTools Protocol (stealth script injection); threading (responsive UI); PyInstaller (native app packaging)

PythonpipSelenium
No. 15

PONG

A fully playable Pong game built in Java with Swing, featuring local two-player multiplayer and a single-player mode against a predictive AI that simulates the ball's full trajectory — including wall bounces — to anticipate where it will land. Single-player mode — AI that simulates the ball's full trajectory (including wall bounces) to predict its landing position, with a speed cap and randomised error margin so it's challenging but beatable; Two-player local multiplayer — both players share the keyboard; Physics-based ball mechanics — bounce angle depends on where the ball strikes the paddle; ball speed increases 5% per volley up to a maximum, rewarding longer rallies; Clean menu UI with keyboard navigation The game runs on a javax.swing.Timer firing at 60 FPS on the Event Dispatch Thread, so updates and repaints stay smooth without ever blocking the EDT with Thread.sleep. Ball physics are vector-based: each return angle is computed from the hit position relative to the paddle centre (rel × 60°), so edge hits produce steep angles and centre hits produce flat returns, with the velocity decomposed via cos/sin. Speed builds 5% per volley up to a hard cap (MAXSPEED), making long rallies progressively harder to control. The AI opponent projects where the ball will land by running a frame-by-frame physics simulation (predictBallY) that mirrors the wall-bounce logic. To stay beatable, it recomputes its target only every ~15 frames, applies a ±25px position error, moves slightly slower than the player, and drifts back to centre when the ball is travelling away — so it can be consistently beaten by pushing the ball into the corners at high speed. Object-oriented design — game state, rendering, and input separated across classes; Event-driven programming — Java Swing event dispatch and key handling; Game loop architecture — javax.swing.Timer at 60 FPS, no blocking on the EDT; Game physics — vector velocity, trigonometric bounce angles, per-volley speed ramping; Collision detection — ball-versus-paddle and ball-versus-wall response; Game AI — predictive opponent via frame-by-frame trajectory simulation; Vector math & trigonometry — cos/sin angle decomposition from paddle hit position; 2D rendering — custom Graphics drawing of paddles, ball, scores, and menu; Input handling — multi-key state tracking and keyboard menu navigation; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17+; Java Swing / AWT (JPanel, JFrame, Graphics, javax.swing.Timer); Java Platform Module System (module-info.java, requires java.desktop); Packaged as a runnable modular JAR (PONG.jar)

JavaGame PhysicsGame AI
No. 16

Cockroach

A real-time 2D Java desktop game where cockroaches swarm in from the edges of the screen. Squash them before they eat your crumbs. The cockroaches run a lightweight greedy-steering AI to seek food and flee from fast cursor movement, all rendered with procedural Graphics2D animation. Cockroaches spawn continuously from all four edges and wander across the screen. Drop bread crumbs to lure them — cockroaches use greedy steering to seek the nearest crumb and will eat it down to nothing. Move your cursor too quickly near a cockroach and it will scatter. Left-click to squash; a splat mark fades on the floor where it died. Swing game loop — javax.swing.Timer drives all updates on the EDT, giving thread-safe state mutation without locks while keeping repaint latency low.; Greedy steering AI — cockroaches find the nearest crumb and pick the 8-directional heading with the highest dot product against the target bearing, replacing an earlier pixel-level BFS that allocated a fresh 600 × 600 visited array per entity per tick.; Flee behaviour — peak cursor speed is sampled between direction-update cycles; any cockroach within 100 px when the speed threshold is exceeded steers directly away for ~0.8 s.; Custom 2D renderer — entities are drawn with Graphics2D transforms (translate → rotate → scale): body oval, head, eyes, antennae, and three leg pairs, all rotated to face the direction of travel. Death plays a squish-and-fade animation by scaling the transform over 100 frames.; Persistent splat marks — squash events stamp a dark oval into a separate list that fades over ~5 seconds independently of the entity lifecycle.; Crumb consumption — each crumb has 10 health points; stopped cockroaches bite stochastically (~3 % chance per frame), and the crumb shrinks visually in proportion to remaining health. Object-oriented design — Cockroach, Entity, Mouse, and Layout classes; Event-driven programming — Java Swing mouse handling and timer-driven updates; Game loop architecture — javax.swing.Timer on the EDT for lock-free, thread-safe state; Game AI & steering behaviours — greedy seek toward nearest crumb, flee on fast cursor; Vector math — 8-directional heading chosen by maximum dot product against the target bearing; Performance optimisation — replaced a per-tick 600×600 BFS scan with O(1) greedy steering; Collision & hit detection — click-to-squash hit testing and crumb proximity; Custom 2D rendering — Graphics2D affine transforms (translate/rotate/scale), procedural sprites; Animation — squish-and-fade death and time-decaying splat marks; Object lifecycle management — independent entity, crumb, and splat lists; Stochastic behaviour — probabilistic crumb biting and randomised spawning; Input handling — left-click squash, drag-and-throw, right-click crumb placement; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17+; Java Swing / AWT (JPanel, Graphics2D, javax.swing.Timer, MouseListener); Java Platform Module System (module-info.java); Packaged as a runnable JAR (cockroach.jar); Eclipse IDE

JavaGame AITesting
No. 17

Exorcist

A 2D infinite climbing platformer built in Java (Swing). Jump between procedurally generated platforms, fight four enemy types with a responsive combat system, and climb as high as you can. Built on an object-oriented entity hierarchy with state-machine AI, custom collision physics, and a sprite-sheet animation system. Procedural generation — platforms, hazards, and enemy placements are generated on the fly with increasing difficulty as you ascend; Four enemy types with distinct AI behaviors: melee aggression, ranged cursing, aerial pursuit, and heavy tanking; Fluid combat — attack, double jump, and a stamina-based shield that rewards timing; Persistent high score saved between sessions; Polished animations — per-entity sprite sheets with state-driven animation (idle, walk, attack, death); Responsive game feel — fall damage, knockback, curse DoT with visual feedback, half-heart regeneration The game is organised around an object-oriented entity model: a shared Entity base provides movement, health, and animation state, and each enemy (Wolf, Golem, Witch, Bat) and the Player extends it with its own state-machine AI. GamePanel drives the update/render loop, CollisionChecker resolves platform and combat collisions, and TileManager builds the world from map files while scrolling infinitely upward and generating fresh content as you climb. Each entity animates from sprite sheets driven by its current state (idle, walk, attack, death). Physics covers gravity, jumping and double-jumping, knockback, and fall damage for long drops. Input is split between KeyHandler and MouseHandler, audio plays through javax.sound.sampled via a dedicated Sound class, and the high score persists to disk between sessions. Move, double jump, attack, and shield; 5 hearts HP with 2 bonus overflow hearts (earned from kills); Shield with stamina bar — blocks frontal attacks, depletes on sustained use; Half-heart regen every 20 seconds; Fall damage for drops over 10 tiles Object-oriented design — Entity base with Wolf / Golem / Witch / Bat / Player subclasses; Inheritance & polymorphism — shared entity behaviour specialised per enemy; State-machine AI — per-entity behaviour and animation states; Game AI — four distinct enemy behaviours (melee lunge, ranged kiting, aerial pursuit, tank); Procedural generation — infinite upward platform, hazard, and enemy generation with scaling difficulty; Collision detection & physics — CollisionChecker, gravity, double jump, knockback, fall damage; Sprite animation system — state-driven sprite-sheet animation (idle/walk/attack/death); Game loop architecture — GamePanel update/render cycle; Custom 2D rendering — Java Swing Graphics2D with AlphaComposite effects; Input handling — separate keyboard and mouse handlers; Audio playback — sound effects via javax.sound.sampled; Tile-map system — TileManager loading map files with infinite scrolling; File I/O — persistent high score and map loading; Combat systems design — stamina shield, curse DoT, half-heart regen, overflow hearts; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17; Java Swing / AWT (Graphics2D, AlphaComposite, 2D rendering); javax.sound.sampled (audio); Java Platform Module System (module-info.java); Packaged as a runnable modular JAR (Exorcist.jar); Eclipse IDE

JavaGame AISwing
No. 18

Go Board Game

A fully playable 19×19 Go board game built in Java using the Processing library. It enforces the Chinese ruleset, handles all the tricky game logic (ko, suicide, group capture via BFS liberty checking), and renders smooth 3D-style stones with real-time hover feedback. This project implements the ancient strategy game of Go as a standalone desktop application. It enforces Chinese ruleset scoring, handles all edge-case game logic (ko, suicide, group capture), and renders smooth 3D-style stones with real-time hover feedback — built on top of Processing's Java2D rendering pipeline. Chinese rules — area scoring (stones + territory) with 7.5 komi for White; Capture detection — BFS flood-fill liberty checking for individual stones and connected groups; Ko rule — rejects moves that recreate the previous board position; Suicide prevention — illegal self-capture moves are blocked before placement; Pass & Reset — pass your turn or restart the game at any time; Game end — two consecutive passes trigger automatic scoring and declare a winner; Territory visualisation — empty intersections are marked at game end to show each player's scored regions; 3D stone rendering — each stone is drawn with shadow, radial gradient, and specular highlight layers; Hover preview — semi-transparent ghost stone follows the cursor for precise placement; App icon — custom logo displayed on the window, taskbar, and macOS Dock The board state and rules live in a Go logic class, kept separate from the Sketch class that handles all Processing rendering and input. Captures are resolved with a BFS flood-fill: when a stone is placed, each adjacent enemy group is flooded to count its liberties, and any group with zero liberties is removed. The same liberty check, applied to the just-placed stone, enforces suicide prevention. The ko rule is implemented by snapshotting the previous board position and rejecting any move that would recreate it. At game end (two consecutive passes), the engine performs Chinese area scoring — counting each player's stones plus the empty territory they fully enclose, adding a 7.5 komi for White, and declaring the winner. Stones are rendered as layered 2D primitives (drop shadow, radial gradient body, specular highlight) for a 3D look, and a translucent ghost stone tracks the cursor for precise placement. Object-oriented design — game logic (Go) separated from rendering/input (Sketch); Game-rule engine — complete Go ruleset with Chinese area scoring and komi; BFS flood-fill — stone and connected-group liberty/capture detection; Graph connectivity — flooding adjacent groups to evaluate captures; Ko-rule detection — rejects moves that repeat the previous board position; Suicide-move prevention — illegal self-capture blocked before placement; Territory scoring — enclosed-region detection for end-game area scoring; Custom 2D rendering — layered 3D-style stones (shadow, radial gradient, specular highlight); Interactive UI — real-time hover ghost-stone preview; Game state management — turn order, pass, reset, and automatic end detection; Processing framework — PApplet with the Java2D renderer; Application packaging — window/taskbar/Dock icon and a runnable JAR Java 17; Processing (PApplet, Java2D renderer; core.jar); JOGL / GlueGen (bundled native libraries shipped with Processing for cross-platform support); Packaged as a runnable JAR (Go.jar)

JavaGoProcessing
No. 19

Snake

A fully playable, built-from-scratch Snake game written in Java Swing — my first independent software project. It implements a complete fixed-timestep game loop, custom 2D rendering, collision detection, and persistent high-score storage using only the Java standard library, with no game engine or third-party dependencies. Grid-based snake movement on a 60×30 board with wrap-around borders; Apple spawning that never lands on the snake's current body; Real-time score plus a persistent high score saved across sessions; Start and game-over overlays, with instant restart (R) without relaunching; WASD and arrow-key controls, with 180° reversal protection; Custom-drawn HUD, snake, food, and translucent message overlays The game is driven by an event-driven loop built on a javax.swing.Timer that fires about 12 times per second (FPS = 12). On each tick the game applies buffered input, advances the snake one cell, runs collision checks, and triggers a repaint. Input is deliberately decoupled from movement: a keypress only sets a pending direction (nextXv / nextYv), which is committed at the start of the next tick. A guard rejects any direct 180° reversal — this eliminates the classic bug where two quick keypresses between frames fold the snake back onto itself. The playfield wraps at every edge, so leaving one side re-enters from the opposite one. The snake's body is stored as a trail of grid coordinates; each tick appends the new head and trims the tail to the current length. Self-collision is detected by scanning the trail for the head's position, and food is re-rolled until it lands on an empty cell. The high score is persisted to a dotfile (~/.snakehighscore) in the user's home directory — loaded on startup, written on every new record, and flushed again on exit (window close or Esc). All visuals are produced in a single custom paintComponent override using AWT Graphics primitives. This was my first programming project, written to learn the fundamentals of Java, event-driven GUI design, and game-loop architecture from the ground up. It has since been refactored to fix several original bugs — timer misuse on the event dispatch thread, game logic embedded in the paint method, and incorrect high-score tracking — while preserving its original structure and scope. Object-oriented design — game model, rendering, and input separated across classes; Event-driven programming — built on Java Swing's event dispatch model; Game loop architecture — fixed-timestep loop via javax.swing.Timer (~12 FPS); 2D rendering — custom paintComponent / Graphics drawing of every element; Collision detection — self-collision and boundary wrap-around; Input handling — buffered direction changes with 180° reversal prevention; Separation of concerns — KeyListener decoupled from game and render logic; File I/O — persistent high-score storage across sessions; Application lifecycle handling — save-on-exit via a WindowListener; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 11+; Java Swing (JPanel, JFrame, javax.swing.Timer); AWT (Graphics, Color, Font, FontMetrics, KeyListener / KeyEvent); Java Platform Module System (module-info.java); java.io file I/O; Packaged as a runnable modular JAR (Snake.jar)

JavaSwingObject-oriented design
No. 20

Competitive Programming

Solutions to competitive programming problems from the Canadian Computing Competition (CCC) and DMOJ, written in C, C++, and Java. The collection spans 150+ solved problems across algorithms, data structures, dynamic programming, graph theory, string processing, and computational geometry. The CCC is Canada's premier annual high school programming competition, organized by the University of Waterloo. This repository contains Senior division solutions spanning 15 years (2000–2014), as well as class materials and practice problems from two competition seasons (2022–2024). Sorting & Searching — binary search, merge sort, quicksort, dual-pivot quicksort, BST; Graph Algorithms — BFS, DFS, shortest path, cycle detection, Eulerian paths; Dynamic Programming — coin change, knapsack, frog DP, sequence DP; Data Structures — binary search trees, hash tables, disjoint sets, segment trees; String Processing — pattern matching, compression, encoding (Huffman, Morse, CRC); Math & Combinatorics — modular inverse, fast exponentiation, RSA numbers, Fibonacci; Geometry — Voronoi diagrams, triangle problems, spiral patterns Solutions to problems from DMOJ: Modern Online Judge, an online judge for Canadian high school competitive programming. Competitive programming — CCC and DMOJ contest problem solving; Algorithms & data structures — broad coverage across 150+ solved problems; Graph algorithms — BFS, DFS, shortest path, cycle detection, Eulerian paths, max flow; Dynamic programming — coin change, knapsack, and sequence DP formulations; Sorting & searching — binary search and merge / quick / dual-pivot quicksort; Tree & set structures — binary search trees, disjoint sets, segment trees, hash tables; String processing — pattern matching, compression, and Huffman / Morse / CRC encoding; Math & combinatorics — modular inverse, fast exponentiation, RSA, Fibonacci; Computational geometry — Voronoi diagrams, triangle and spiral problems; Multi-language fluency — solving the same class of problems in C, C++, and Java; Complexity & optimization — meeting contest time and memory limits C; C++; Java; Eclipse IDE (CCC / DMOJ workspaces)

JavaC++C
No. 21

Learning

A collection of programming projects spanning my learning journey — from writing my first lines of Java and C++ through implementing classic graph algorithms and teaching others. It ranges across language fundamentals, data-structure and graph-algorithm implementations, small utilities, and material I prepared as a high-school programming instructor. Foundational Java projects built through a structured course, including GUI programs, sound playback, and user input handling. Entry point into object-oriented programming. Java practice workspace from 2022, used for experimenting with new concepts alongside formal coursework. Selected projects from a guided Java curriculum — includes a Length Converter, Word Counter, and an image display program. Focused on practical application of core Java APIs. Implementations of classic graph and tree algorithms in Java: Material prepared and taught as an instructor in a high school programming club. Includes introductory exercises and guided problems written to help beginners get started with Java. Small utilities written for personal use — prime number tools and helper scripts for everyday tasks. Stars and Bars — combinatorics calculator; Galois 2022 4 — solution to a Galois Contest problem; Change Finder — coin change problem variant 26 single-topic programs covering the full introductory C++ curriculum: Variables · Data Types · Numbers · Strings · Arrays · 2D Arrays · User Input · If Statements · Switch Statements · For Loops · While Loops · Functions · Return Values · Pointers · Classes & Objects · Constructor Functions · Getters & Setters · Object Functions · Inheritance · Calculator · Guessing Game · MadLibs · Exponent Function · Comments · HelloWorld Each program isolates one concept, making this a clean reference for C++ fundamentals. Object-oriented programming — Java and C++ fundamentals through to small projects; Data structures — binary search trees and disjoint-set union; Graph algorithms — Dijkstra's shortest path, Prim's & Kruskal's MST, Tarjan's & Kosaraju's SCC; Graph traversal & validation — Eulerian paths and directed/undirected cycle detection; Algorithm implementation — classic graph and tree algorithms written from scratch; Combinatorics & math — stars and bars, coin change, and contest math problems; GUI programming — Java Swing projects with sound playback and user input; C++ fundamentals — 26 single-topic programs (pointers, classes, inheritance, and more); Practical utilities — converters, a word counter, image display, and prime-number tools; Teaching & mentoring — prepared and taught high-school programming-club material; Self-directed learning — a multi-year progression across two languages Java; C++; Java Swing (GUI projects); Eclipse IDE

JavaCSSC++
No. 11

Biquadris

A two-player competitive Tetris variant built in C++ with an object-oriented design. Originally developed as a final project for CS 246: Object-Oriented Software Development at the University of Waterloo (Fall 2025) by a team of three students, then refactored and extended into a cross-platform, SDL2-rendered game. The game has since been refactored and extended beyond the original submission: bugs fixed, the X11 graphics layer replaced with SDL2 for cross-platform support, and the build system migrated to CMake for easy packaging. Biquadris is a turn-based, two-player spin on Tetris. Both players share one screen — each managing their own 11×18 board. Players alternate turns: you make one move, then your opponent does. Clear two or more lines in a single drop and you earn a special action to punish your opponent. The game ends when a player can no longer place a new block. The codebase is organized around a small set of well-encapsulated classes. Game owns the two Board models and drives the turn loop; each Board tracks its grid, score, level, and active effects; Block encodes the seven tetromino shapes and their rotations; Level generates the next block according to the current difficulty; and the rendering is handled by interchangeable views — a TextDisplay for the terminal and an SDL2 Xwindow for graphics. Two design ideas carry most of the weight. Special actions are a polymorphic effect system (Strategy-style): an abstract Effect base class declares apply, onDrop, isExpired, and getName, and concrete BlindEffect, HeavyEffect, and ForceEffect subclasses implement each behaviour. An EffectManager holds the active effects per board, applies them on activation, ticks them after every drop, and retires them when they expire — so new actions can be added without touching the board logic. The model is fully decoupled from the views: the boards know nothing about how they're drawn, so the same game state renders identically to the terminal or to SDL2. Memory is managed entirely through std::uniqueptr (RAII — no manual new/delete), collision detection validates every move and rotation against the walls and settled cells before committing it, and a single codebase compiles either text-only or with graphics via conditional compilation (ifdef BIQUADRISGRAPHICS). Commands are parsed with unique-prefix matching and numeric multipliers, the high score persists between sessions, and a ghost-block preview shows where the current piece will land. Clearing 2 or more lines in a single drop earns a special action against your opponent: Line clear: (currentlevel + linescleared)² points; A block that scores zero lines resets the combo; clearing any lines resets the no-clear counter (relevant for Level 4 penalty blocks); High score is saved across sessions in .biquadrishighscore Object-oriented design — encapsulated Game, Board, Block, Level, and Effect classes; Polymorphism & abstract base classes — Effect interface with Blind / Heavy / Force subclasses; Inheritance — virtual methods and virtual destructors across the effect hierarchy; Strategy-style effect system — runtime special actions managed by an EffectManager; Model–view separation (MVC) — board state decoupled from the text and SDL2 renderers; RAII & smart pointers — std::uniqueptr ownership throughout, no manual memory management; Modern C++20 — const-correctness, standard containers, move semantics; Collision detection — move and rotation validation against walls and settled cells; Conditional compilation — one codebase builds text-only or with SDL2 graphics; Command parsing — unique-prefix matching with numeric multipliers; File I/O — high-score persistence and script-driven block sequences; Cross-platform build system — CMake with Homebrew SDL2 discovery on macOS; CI/CD release automation — GitHub Actions builds and bundles a distributable macOS app; Game logic — line clearing, level progression, ghost-block preview, and squared scoring C++20;

C++GitHub ActionsCMake
No. 12

Minesweeper

A fully-featured Minesweeper clone built in Java with a custom dark-themed UI, a probability-based AI solver, BFS flood-fill reveals, and dynamic tile scaling. Custom rendered board — 3D bevel tiles drawn with Graphics2D, distinct highlight/shadow edges for unrevealed vs. revealed states; Probability-based AI solver — constraint propagation fixpoint loop deduces guaranteed mines; remaining cells ranked by local mine probability; random tie-breaking when probabilities are equal; Auto Solve mode — checkbox triggers the AI on a 500 ms Swing Timer; runs on the EDT without blocking the UI; Configurable grid — dialog lets you set columns, rows, and mine count; tile size auto-scales to fill the screen while keeping tiles between 20–60 px; Restart — resets board, AI state, and mine counter without reopening the setup dialog; Instructions dialog — in-game "How to Play" reference; Dynamic mine counter — tracks remaining unflagged mines in real time; Platform-aware icon — programmatically generated app icon reusing the same drawRaised / drawMine helpers; set on the macOS dock via the Taskbar API The game logic, AI, and UI are kept in separate classes (MineSweeper, AI, Main). Revealing an empty cell triggers a BFS flood-fill that cascades outward through all connected zero-count cells, opening their neighbours in one sweep. The AI solver runs a constraint-propagation fixpoint loop: it repeatedly scans every numbered cell, and whenever a cell's number equals its count of adjacent unknowns it flags those as guaranteed mines (and conversely opens cells that are provably safe), iterating until no new deductions are possible. When pure deduction stalls, it falls back to probabilistic reasoning — ranking the remaining unknown cells by their local mine probability and breaking ties randomly — so it can keep making the statistically best move. Auto-solve mode steps this engine on a 500 ms Swing Timer, entirely on the Event Dispatch Thread so the UI never freezes. Object-oriented design — game logic, AI solver, and UI in separate classes; Event-driven programming — Swing mouse and window listeners, timer-driven auto-solve; 2D rendering — Graphics2D 3D-bevel tiles with highlight/shadow edges; BFS flood-fill — cascading reveal of connected zero-count cells; Constraint-propagation solver — fixpoint deduction of guaranteed mines and safe cells; Probabilistic reasoning — local mine-probability ranking with random tie-breaking; Algorithm design — combined deterministic + probabilistic AI strategy; Dynamic UI scaling — tile size auto-scales (20–60 px) to grid and screen size; Procedural graphics — programmatically generated app icon and dock integration via Taskbar; Input handling — mouse listener for reveal/flag, window listener for lifecycle; Layout management — Swing layout managers and SpringUtilities; JAR packaging — distributed as a standalone runnable JAR Java 17; Java Swing / AWT (JFrame, JPanel, Graphics2D, javax.swing.Timer, layout managers); Taskbar API for the macOS dock icon; Packaged as a standalone runnable JAR (MineSweeper.jar)

JavaSwingObject-oriented design
No. 13

Image To Text

A desktop Java application that converts raster images into ASCII art in real time. Built from scratch with a fully custom Swing GUI, an off-screen rendering pipeline for O(1) scroll/zoom, background processing via SwingWorker, and smooth zoom/pan interaction. The app takes any JPG, PNG, or GIF image, converts each pixel to a grayscale luminance value using the Rec. 601 standard, and maps it to one of 70 ASCII characters ordered by visual density (Paul Bourke gradient). The result is rendered into a scrollable, zoomable panel and the intermediate grayscale image is saved to disk automatically. Conversion reads pixels directly from a BufferedImage (getRGB), computes per-pixel luminance with the Rec. 601 luma coefficients (0.299R + 0.587G + 0.114B), and maps each value through a static lookup table to one of 70 density-ordered ASCII characters. The hot pixel loop uses a StringBuilder for O(n) assembly, and the whole conversion runs on a SwingWorker so the UI never blocks. The rendered ASCII is drawn once into an off-screen buffer, so scrolling and zooming stay O(1) regardless of image size — nearest-neighbor interpolation keeps it crisp when zoomed in, bilinear keeps it smooth when zoomed out. Interaction is handled with a MouseAdapter for drag-to-pan (using screen coordinates for stable deltas) and getPreciseWheelRotation for smooth Ctrl+scroll zoom, with an InputMap/ActionMap shortcut system scoped to the focused window. Swing GUI from scratch — custom layouts, components, and event handling; Multithreading & concurrency — SwingWorker keeps the UI responsive during conversion; Off-screen rendering — pre-rendered BufferedImage makes scroll and zoom O(1) at any image size; Image processing — pixel-level RGB manipulation via getRGB / setRGB; Grayscale conversion — Rec. 601 luma coefficients (0.299R + 0.587G + 0.114B); Algorithm/data-structure use — static lookup table for the brightness → character mapping; Image scaling — SCALESMOOTH downscaling with zoom-aware nearest-neighbor / bilinear interpolation; Keyboard shortcut system — InputMap / ActionMap with WHENINFOCUSEDWINDOW scope; Performance optimization — StringBuilder over concatenation in hot pixel loops for O(n); Pan & zoom UX — drag-to-pan, precise Ctrl+scroll zoom, and fit-to-window on every transform; Layout management — responsive nested BorderLayout so zoom controls stay visible at any width; Error handling — IOException propagation with user-facing dialogs, no silent failures; Object-oriented design — separate converter, text panel, and prompt components; JAR packaging — distributed as a standalone runnable JAR Java 17+; Java Swing / AWT (BufferedImage, Graphics2D, SwingWorker, InputMap / ActionMap, MouseAdapter); Packaged as a standalone runnable JAR (ImageToText.jar)

JavaConcurrencyProcessing
No. 14

Instagram Non Follower Finder

A desktop app that automates finding Instagram accounts you follow that don't follow you back. Built with Python, Selenium WebDriver, and CustomTkinter — it drives a real browser to scroll and extract your follower/following lists, applies hand-rolled anti-bot stealth, and presents the diff in a clean dark-mode GUI with cross-browser support. Cross-browser — Chrome, Firefox, Edge, Safari; Stealth mode — patches automation fingerprints to reduce bot detection across browsers; Manual login flow with full 2FA and captcha support; Auto-downloads browser drivers (no PATH setup required); Accumulates users across virtual-scroll batches so no one is missed; Results copyable to clipboard The app launches a real browser through Selenium WebDriver and lets you log in manually (so 2FA and captchas just work). To reduce automation detection, it injects a small stealth script that redefines navigator.webdriver — via the Chrome DevTools Protocol (Page.addScriptToEvaluateOnNewDocument) on Chromium browsers and executescript on Firefox — alongside flags like --disable-blink-features=AutomationControlled and Firefox's dom.webdriver.enabled = false. It then opens your followers and following dialogs and uses ActionChains with ScrollOrigin to scroll the virtual-scrolling lists, accumulating usernames across batches until the full list is captured. A set difference between following and followers yields the accounts that don't follow you back. All of this runs on a background threading worker so the CustomTkinter UI stays responsive, with per-browser error dialogs when a driver fails to start. Browser automation — Selenium WebDriver driving Chrome, Firefox, Edge, and Safari; Cross-browser abstraction — per-browser options and driver setup behind one flow (match/case); Anti-bot stealth — CDP navigator.webdriver patching and disabling automation fingerprints; Dynamic web scraping — ActionChains + ScrollOrigin to drive virtual-scroll list extraction; Set operations — diff of following vs. followers to surface non-followers; Multithreading & concurrency — background threading worker keeps the GUI responsive; GUI development — CustomTkinter dark-mode desktop interface; Robust error handling — per-browser driver-failure dialogs and captcha/2FA-friendly login; Automatic driver management — webdriver-manager for Firefox/Edge; Chrome 115+ self-manages; Clipboard integration — one-click copy of results; Application packaging — PyInstaller native build via build.py Python 3.10+ (match/case); Selenium WebDriver (Chrome, Firefox, Edge, Safari); CustomTkinter (dark-mode GUI); webdriver-manager (Firefox / Edge driver management); Chrome DevTools Protocol (stealth script injection); threading (responsive UI); PyInstaller (native app packaging)

PythonpipSelenium
No. 15

PONG

A fully playable Pong game built in Java with Swing, featuring local two-player multiplayer and a single-player mode against a predictive AI that simulates the ball's full trajectory — including wall bounces — to anticipate where it will land. Single-player mode — AI that simulates the ball's full trajectory (including wall bounces) to predict its landing position, with a speed cap and randomised error margin so it's challenging but beatable; Two-player local multiplayer — both players share the keyboard; Physics-based ball mechanics — bounce angle depends on where the ball strikes the paddle; ball speed increases 5% per volley up to a maximum, rewarding longer rallies; Clean menu UI with keyboard navigation The game runs on a javax.swing.Timer firing at 60 FPS on the Event Dispatch Thread, so updates and repaints stay smooth without ever blocking the EDT with Thread.sleep. Ball physics are vector-based: each return angle is computed from the hit position relative to the paddle centre (rel × 60°), so edge hits produce steep angles and centre hits produce flat returns, with the velocity decomposed via cos/sin. Speed builds 5% per volley up to a hard cap (MAXSPEED), making long rallies progressively harder to control. The AI opponent projects where the ball will land by running a frame-by-frame physics simulation (predictBallY) that mirrors the wall-bounce logic. To stay beatable, it recomputes its target only every ~15 frames, applies a ±25px position error, moves slightly slower than the player, and drifts back to centre when the ball is travelling away — so it can be consistently beaten by pushing the ball into the corners at high speed. Object-oriented design — game state, rendering, and input separated across classes; Event-driven programming — Java Swing event dispatch and key handling; Game loop architecture — javax.swing.Timer at 60 FPS, no blocking on the EDT; Game physics — vector velocity, trigonometric bounce angles, per-volley speed ramping; Collision detection — ball-versus-paddle and ball-versus-wall response; Game AI — predictive opponent via frame-by-frame trajectory simulation; Vector math & trigonometry — cos/sin angle decomposition from paddle hit position; 2D rendering — custom Graphics drawing of paddles, ball, scores, and menu; Input handling — multi-key state tracking and keyboard menu navigation; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17+; Java Swing / AWT (JPanel, JFrame, Graphics, javax.swing.Timer); Java Platform Module System (module-info.java, requires java.desktop); Packaged as a runnable modular JAR (PONG.jar)

JavaGame PhysicsGame AI
No. 16

Cockroach

A real-time 2D Java desktop game where cockroaches swarm in from the edges of the screen. Squash them before they eat your crumbs. The cockroaches run a lightweight greedy-steering AI to seek food and flee from fast cursor movement, all rendered with procedural Graphics2D animation. Cockroaches spawn continuously from all four edges and wander across the screen. Drop bread crumbs to lure them — cockroaches use greedy steering to seek the nearest crumb and will eat it down to nothing. Move your cursor too quickly near a cockroach and it will scatter. Left-click to squash; a splat mark fades on the floor where it died. Swing game loop — javax.swing.Timer drives all updates on the EDT, giving thread-safe state mutation without locks while keeping repaint latency low.; Greedy steering AI — cockroaches find the nearest crumb and pick the 8-directional heading with the highest dot product against the target bearing, replacing an earlier pixel-level BFS that allocated a fresh 600 × 600 visited array per entity per tick.; Flee behaviour — peak cursor speed is sampled between direction-update cycles; any cockroach within 100 px when the speed threshold is exceeded steers directly away for ~0.8 s.; Custom 2D renderer — entities are drawn with Graphics2D transforms (translate → rotate → scale): body oval, head, eyes, antennae, and three leg pairs, all rotated to face the direction of travel. Death plays a squish-and-fade animation by scaling the transform over 100 frames.; Persistent splat marks — squash events stamp a dark oval into a separate list that fades over ~5 seconds independently of the entity lifecycle.; Crumb consumption — each crumb has 10 health points; stopped cockroaches bite stochastically (~3 % chance per frame), and the crumb shrinks visually in proportion to remaining health. Object-oriented design — Cockroach, Entity, Mouse, and Layout classes; Event-driven programming — Java Swing mouse handling and timer-driven updates; Game loop architecture — javax.swing.Timer on the EDT for lock-free, thread-safe state; Game AI & steering behaviours — greedy seek toward nearest crumb, flee on fast cursor; Vector math — 8-directional heading chosen by maximum dot product against the target bearing; Performance optimisation — replaced a per-tick 600×600 BFS scan with O(1) greedy steering; Collision & hit detection — click-to-squash hit testing and crumb proximity; Custom 2D rendering — Graphics2D affine transforms (translate/rotate/scale), procedural sprites; Animation — squish-and-fade death and time-decaying splat marks; Object lifecycle management — independent entity, crumb, and splat lists; Stochastic behaviour — probabilistic crumb biting and randomised spawning; Input handling — left-click squash, drag-and-throw, right-click crumb placement; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17+; Java Swing / AWT (JPanel, Graphics2D, javax.swing.Timer, MouseListener); Java Platform Module System (module-info.java); Packaged as a runnable JAR (cockroach.jar); Eclipse IDE

JavaGame AITesting
No. 17

Exorcist

A 2D infinite climbing platformer built in Java (Swing). Jump between procedurally generated platforms, fight four enemy types with a responsive combat system, and climb as high as you can. Built on an object-oriented entity hierarchy with state-machine AI, custom collision physics, and a sprite-sheet animation system. Procedural generation — platforms, hazards, and enemy placements are generated on the fly with increasing difficulty as you ascend; Four enemy types with distinct AI behaviors: melee aggression, ranged cursing, aerial pursuit, and heavy tanking; Fluid combat — attack, double jump, and a stamina-based shield that rewards timing; Persistent high score saved between sessions; Polished animations — per-entity sprite sheets with state-driven animation (idle, walk, attack, death); Responsive game feel — fall damage, knockback, curse DoT with visual feedback, half-heart regeneration The game is organised around an object-oriented entity model: a shared Entity base provides movement, health, and animation state, and each enemy (Wolf, Golem, Witch, Bat) and the Player extends it with its own state-machine AI. GamePanel drives the update/render loop, CollisionChecker resolves platform and combat collisions, and TileManager builds the world from map files while scrolling infinitely upward and generating fresh content as you climb. Each entity animates from sprite sheets driven by its current state (idle, walk, attack, death). Physics covers gravity, jumping and double-jumping, knockback, and fall damage for long drops. Input is split between KeyHandler and MouseHandler, audio plays through javax.sound.sampled via a dedicated Sound class, and the high score persists to disk between sessions. Move, double jump, attack, and shield; 5 hearts HP with 2 bonus overflow hearts (earned from kills); Shield with stamina bar — blocks frontal attacks, depletes on sustained use; Half-heart regen every 20 seconds; Fall damage for drops over 10 tiles Object-oriented design — Entity base with Wolf / Golem / Witch / Bat / Player subclasses; Inheritance & polymorphism — shared entity behaviour specialised per enemy; State-machine AI — per-entity behaviour and animation states; Game AI — four distinct enemy behaviours (melee lunge, ranged kiting, aerial pursuit, tank); Procedural generation — infinite upward platform, hazard, and enemy generation with scaling difficulty; Collision detection & physics — CollisionChecker, gravity, double jump, knockback, fall damage; Sprite animation system — state-driven sprite-sheet animation (idle/walk/attack/death); Game loop architecture — GamePanel update/render cycle; Custom 2D rendering — Java Swing Graphics2D with AlphaComposite effects; Input handling — separate keyboard and mouse handlers; Audio playback — sound effects via javax.sound.sampled; Tile-map system — TileManager loading map files with infinite scrolling; File I/O — persistent high score and map loading; Combat systems design — stamina shield, curse DoT, half-heart regen, overflow hearts; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17; Java Swing / AWT (Graphics2D, AlphaComposite, 2D rendering); javax.sound.sampled (audio); Java Platform Module System (module-info.java); Packaged as a runnable modular JAR (Exorcist.jar); Eclipse IDE

JavaGame AISwing
No. 18

Go Board Game

A fully playable 19×19 Go board game built in Java using the Processing library. It enforces the Chinese ruleset, handles all the tricky game logic (ko, suicide, group capture via BFS liberty checking), and renders smooth 3D-style stones with real-time hover feedback. This project implements the ancient strategy game of Go as a standalone desktop application. It enforces Chinese ruleset scoring, handles all edge-case game logic (ko, suicide, group capture), and renders smooth 3D-style stones with real-time hover feedback — built on top of Processing's Java2D rendering pipeline. Chinese rules — area scoring (stones + territory) with 7.5 komi for White; Capture detection — BFS flood-fill liberty checking for individual stones and connected groups; Ko rule — rejects moves that recreate the previous board position; Suicide prevention — illegal self-capture moves are blocked before placement; Pass & Reset — pass your turn or restart the game at any time; Game end — two consecutive passes trigger automatic scoring and declare a winner; Territory visualisation — empty intersections are marked at game end to show each player's scored regions; 3D stone rendering — each stone is drawn with shadow, radial gradient, and specular highlight layers; Hover preview — semi-transparent ghost stone follows the cursor for precise placement; App icon — custom logo displayed on the window, taskbar, and macOS Dock The board state and rules live in a Go logic class, kept separate from the Sketch class that handles all Processing rendering and input. Captures are resolved with a BFS flood-fill: when a stone is placed, each adjacent enemy group is flooded to count its liberties, and any group with zero liberties is removed. The same liberty check, applied to the just-placed stone, enforces suicide prevention. The ko rule is implemented by snapshotting the previous board position and rejecting any move that would recreate it. At game end (two consecutive passes), the engine performs Chinese area scoring — counting each player's stones plus the empty territory they fully enclose, adding a 7.5 komi for White, and declaring the winner. Stones are rendered as layered 2D primitives (drop shadow, radial gradient body, specular highlight) for a 3D look, and a translucent ghost stone tracks the cursor for precise placement. Object-oriented design — game logic (Go) separated from rendering/input (Sketch); Game-rule engine — complete Go ruleset with Chinese area scoring and komi; BFS flood-fill — stone and connected-group liberty/capture detection; Graph connectivity — flooding adjacent groups to evaluate captures; Ko-rule detection — rejects moves that repeat the previous board position; Suicide-move prevention — illegal self-capture blocked before placement; Territory scoring — enclosed-region detection for end-game area scoring; Custom 2D rendering — layered 3D-style stones (shadow, radial gradient, specular highlight); Interactive UI — real-time hover ghost-stone preview; Game state management — turn order, pass, reset, and automatic end detection; Processing framework — PApplet with the Java2D renderer; Application packaging — window/taskbar/Dock icon and a runnable JAR Java 17; Processing (PApplet, Java2D renderer; core.jar); JOGL / GlueGen (bundled native libraries shipped with Processing for cross-platform support); Packaged as a runnable JAR (Go.jar)

JavaGoProcessing
No. 19

Snake

A fully playable, built-from-scratch Snake game written in Java Swing — my first independent software project. It implements a complete fixed-timestep game loop, custom 2D rendering, collision detection, and persistent high-score storage using only the Java standard library, with no game engine or third-party dependencies. Grid-based snake movement on a 60×30 board with wrap-around borders; Apple spawning that never lands on the snake's current body; Real-time score plus a persistent high score saved across sessions; Start and game-over overlays, with instant restart (R) without relaunching; WASD and arrow-key controls, with 180° reversal protection; Custom-drawn HUD, snake, food, and translucent message overlays The game is driven by an event-driven loop built on a javax.swing.Timer that fires about 12 times per second (FPS = 12). On each tick the game applies buffered input, advances the snake one cell, runs collision checks, and triggers a repaint. Input is deliberately decoupled from movement: a keypress only sets a pending direction (nextXv / nextYv), which is committed at the start of the next tick. A guard rejects any direct 180° reversal — this eliminates the classic bug where two quick keypresses between frames fold the snake back onto itself. The playfield wraps at every edge, so leaving one side re-enters from the opposite one. The snake's body is stored as a trail of grid coordinates; each tick appends the new head and trims the tail to the current length. Self-collision is detected by scanning the trail for the head's position, and food is re-rolled until it lands on an empty cell. The high score is persisted to a dotfile (~/.snakehighscore) in the user's home directory — loaded on startup, written on every new record, and flushed again on exit (window close or Esc). All visuals are produced in a single custom paintComponent override using AWT Graphics primitives. This was my first programming project, written to learn the fundamentals of Java, event-driven GUI design, and game-loop architecture from the ground up. It has since been refactored to fix several original bugs — timer misuse on the event dispatch thread, game logic embedded in the paint method, and incorrect high-score tracking — while preserving its original structure and scope. Object-oriented design — game model, rendering, and input separated across classes; Event-driven programming — built on Java Swing's event dispatch model; Game loop architecture — fixed-timestep loop via javax.swing.Timer (~12 FPS); 2D rendering — custom paintComponent / Graphics drawing of every element; Collision detection — self-collision and boundary wrap-around; Input handling — buffered direction changes with 180° reversal prevention; Separation of concerns — KeyListener decoupled from game and render logic; File I/O — persistent high-score storage across sessions; Application lifecycle handling — save-on-exit via a WindowListener; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 11+; Java Swing (JPanel, JFrame, javax.swing.Timer); AWT (Graphics, Color, Font, FontMetrics, KeyListener / KeyEvent); Java Platform Module System (module-info.java); java.io file I/O; Packaged as a runnable modular JAR (Snake.jar)

JavaSwingObject-oriented design
No. 20

Competitive Programming

Solutions to competitive programming problems from the Canadian Computing Competition (CCC) and DMOJ, written in C, C++, and Java. The collection spans 150+ solved problems across algorithms, data structures, dynamic programming, graph theory, string processing, and computational geometry. The CCC is Canada's premier annual high school programming competition, organized by the University of Waterloo. This repository contains Senior division solutions spanning 15 years (2000–2014), as well as class materials and practice problems from two competition seasons (2022–2024). Sorting & Searching — binary search, merge sort, quicksort, dual-pivot quicksort, BST; Graph Algorithms — BFS, DFS, shortest path, cycle detection, Eulerian paths; Dynamic Programming — coin change, knapsack, frog DP, sequence DP; Data Structures — binary search trees, hash tables, disjoint sets, segment trees; String Processing — pattern matching, compression, encoding (Huffman, Morse, CRC); Math & Combinatorics — modular inverse, fast exponentiation, RSA numbers, Fibonacci; Geometry — Voronoi diagrams, triangle problems, spiral patterns Solutions to problems from DMOJ: Modern Online Judge, an online judge for Canadian high school competitive programming. Competitive programming — CCC and DMOJ contest problem solving; Algorithms & data structures — broad coverage across 150+ solved problems; Graph algorithms — BFS, DFS, shortest path, cycle detection, Eulerian paths, max flow; Dynamic programming — coin change, knapsack, and sequence DP formulations; Sorting & searching — binary search and merge / quick / dual-pivot quicksort; Tree & set structures — binary search trees, disjoint sets, segment trees, hash tables; String processing — pattern matching, compression, and Huffman / Morse / CRC encoding; Math & combinatorics — modular inverse, fast exponentiation, RSA, Fibonacci; Computational geometry — Voronoi diagrams, triangle and spiral problems; Multi-language fluency — solving the same class of problems in C, C++, and Java; Complexity & optimization — meeting contest time and memory limits C; C++; Java; Eclipse IDE (CCC / DMOJ workspaces)

JavaC++C
No. 21

Learning

A collection of programming projects spanning my learning journey — from writing my first lines of Java and C++ through implementing classic graph algorithms and teaching others. It ranges across language fundamentals, data-structure and graph-algorithm implementations, small utilities, and material I prepared as a high-school programming instructor. Foundational Java projects built through a structured course, including GUI programs, sound playback, and user input handling. Entry point into object-oriented programming. Java practice workspace from 2022, used for experimenting with new concepts alongside formal coursework. Selected projects from a guided Java curriculum — includes a Length Converter, Word Counter, and an image display program. Focused on practical application of core Java APIs. Implementations of classic graph and tree algorithms in Java: Material prepared and taught as an instructor in a high school programming club. Includes introductory exercises and guided problems written to help beginners get started with Java. Small utilities written for personal use — prime number tools and helper scripts for everyday tasks. Stars and Bars — combinatorics calculator; Galois 2022 4 — solution to a Galois Contest problem; Change Finder — coin change problem variant 26 single-topic programs covering the full introductory C++ curriculum: Variables · Data Types · Numbers · Strings · Arrays · 2D Arrays · User Input · If Statements · Switch Statements · For Loops · While Loops · Functions · Return Values · Pointers · Classes & Objects · Constructor Functions · Getters & Setters · Object Functions · Inheritance · Calculator · Guessing Game · MadLibs · Exponent Function · Comments · HelloWorld Each program isolates one concept, making this a clean reference for C++ fundamentals. Object-oriented programming — Java and C++ fundamentals through to small projects; Data structures — binary search trees and disjoint-set union; Graph algorithms — Dijkstra's shortest path, Prim's & Kruskal's MST, Tarjan's & Kosaraju's SCC; Graph traversal & validation — Eulerian paths and directed/undirected cycle detection; Algorithm implementation — classic graph and tree algorithms written from scratch; Combinatorics & math — stars and bars, coin change, and contest math problems; GUI programming — Java Swing projects with sound playback and user input; C++ fundamentals — 26 single-topic programs (pointers, classes, inheritance, and more); Practical utilities — converters, a word counter, image display, and prime-number tools; Teaching & mentoring — prepared and taught high-school programming-club material; Self-directed learning — a multi-year progression across two languages Java; C++; Java Swing (GUI projects); Eclipse IDE

JavaCSSC++
No. 11

Biquadris

A two-player competitive Tetris variant built in C++ with an object-oriented design. Originally developed as a final project for CS 246: Object-Oriented Software Development at the University of Waterloo (Fall 2025) by a team of three students, then refactored and extended into a cross-platform, SDL2-rendered game. The game has since been refactored and extended beyond the original submission: bugs fixed, the X11 graphics layer replaced with SDL2 for cross-platform support, and the build system migrated to CMake for easy packaging. Biquadris is a turn-based, two-player spin on Tetris. Both players share one screen — each managing their own 11×18 board. Players alternate turns: you make one move, then your opponent does. Clear two or more lines in a single drop and you earn a special action to punish your opponent. The game ends when a player can no longer place a new block. The codebase is organized around a small set of well-encapsulated classes. Game owns the two Board models and drives the turn loop; each Board tracks its grid, score, level, and active effects; Block encodes the seven tetromino shapes and their rotations; Level generates the next block according to the current difficulty; and the rendering is handled by interchangeable views — a TextDisplay for the terminal and an SDL2 Xwindow for graphics. Two design ideas carry most of the weight. Special actions are a polymorphic effect system (Strategy-style): an abstract Effect base class declares apply, onDrop, isExpired, and getName, and concrete BlindEffect, HeavyEffect, and ForceEffect subclasses implement each behaviour. An EffectManager holds the active effects per board, applies them on activation, ticks them after every drop, and retires them when they expire — so new actions can be added without touching the board logic. The model is fully decoupled from the views: the boards know nothing about how they're drawn, so the same game state renders identically to the terminal or to SDL2. Memory is managed entirely through std::uniqueptr (RAII — no manual new/delete), collision detection validates every move and rotation against the walls and settled cells before committing it, and a single codebase compiles either text-only or with graphics via conditional compilation (ifdef BIQUADRISGRAPHICS). Commands are parsed with unique-prefix matching and numeric multipliers, the high score persists between sessions, and a ghost-block preview shows where the current piece will land. Clearing 2 or more lines in a single drop earns a special action against your opponent: Line clear: (currentlevel + linescleared)² points; A block that scores zero lines resets the combo; clearing any lines resets the no-clear counter (relevant for Level 4 penalty blocks); High score is saved across sessions in .biquadrishighscore Object-oriented design — encapsulated Game, Board, Block, Level, and Effect classes; Polymorphism & abstract base classes — Effect interface with Blind / Heavy / Force subclasses; Inheritance — virtual methods and virtual destructors across the effect hierarchy; Strategy-style effect system — runtime special actions managed by an EffectManager; Model–view separation (MVC) — board state decoupled from the text and SDL2 renderers; RAII & smart pointers — std::uniqueptr ownership throughout, no manual memory management; Modern C++20 — const-correctness, standard containers, move semantics; Collision detection — move and rotation validation against walls and settled cells; Conditional compilation — one codebase builds text-only or with SDL2 graphics; Command parsing — unique-prefix matching with numeric multipliers; File I/O — high-score persistence and script-driven block sequences; Cross-platform build system — CMake with Homebrew SDL2 discovery on macOS; CI/CD release automation — GitHub Actions builds and bundles a distributable macOS app; Game logic — line clearing, level progression, ghost-block preview, and squared scoring C++20;

C++GitHub ActionsCMake
No. 12

Minesweeper

A fully-featured Minesweeper clone built in Java with a custom dark-themed UI, a probability-based AI solver, BFS flood-fill reveals, and dynamic tile scaling. Custom rendered board — 3D bevel tiles drawn with Graphics2D, distinct highlight/shadow edges for unrevealed vs. revealed states; Probability-based AI solver — constraint propagation fixpoint loop deduces guaranteed mines; remaining cells ranked by local mine probability; random tie-breaking when probabilities are equal; Auto Solve mode — checkbox triggers the AI on a 500 ms Swing Timer; runs on the EDT without blocking the UI; Configurable grid — dialog lets you set columns, rows, and mine count; tile size auto-scales to fill the screen while keeping tiles between 20–60 px; Restart — resets board, AI state, and mine counter without reopening the setup dialog; Instructions dialog — in-game "How to Play" reference; Dynamic mine counter — tracks remaining unflagged mines in real time; Platform-aware icon — programmatically generated app icon reusing the same drawRaised / drawMine helpers; set on the macOS dock via the Taskbar API The game logic, AI, and UI are kept in separate classes (MineSweeper, AI, Main). Revealing an empty cell triggers a BFS flood-fill that cascades outward through all connected zero-count cells, opening their neighbours in one sweep. The AI solver runs a constraint-propagation fixpoint loop: it repeatedly scans every numbered cell, and whenever a cell's number equals its count of adjacent unknowns it flags those as guaranteed mines (and conversely opens cells that are provably safe), iterating until no new deductions are possible. When pure deduction stalls, it falls back to probabilistic reasoning — ranking the remaining unknown cells by their local mine probability and breaking ties randomly — so it can keep making the statistically best move. Auto-solve mode steps this engine on a 500 ms Swing Timer, entirely on the Event Dispatch Thread so the UI never freezes. Object-oriented design — game logic, AI solver, and UI in separate classes; Event-driven programming — Swing mouse and window listeners, timer-driven auto-solve; 2D rendering — Graphics2D 3D-bevel tiles with highlight/shadow edges; BFS flood-fill — cascading reveal of connected zero-count cells; Constraint-propagation solver — fixpoint deduction of guaranteed mines and safe cells; Probabilistic reasoning — local mine-probability ranking with random tie-breaking; Algorithm design — combined deterministic + probabilistic AI strategy; Dynamic UI scaling — tile size auto-scales (20–60 px) to grid and screen size; Procedural graphics — programmatically generated app icon and dock integration via Taskbar; Input handling — mouse listener for reveal/flag, window listener for lifecycle; Layout management — Swing layout managers and SpringUtilities; JAR packaging — distributed as a standalone runnable JAR Java 17; Java Swing / AWT (JFrame, JPanel, Graphics2D, javax.swing.Timer, layout managers); Taskbar API for the macOS dock icon; Packaged as a standalone runnable JAR (MineSweeper.jar)

JavaSwingObject-oriented design
No. 13

Image To Text

A desktop Java application that converts raster images into ASCII art in real time. Built from scratch with a fully custom Swing GUI, an off-screen rendering pipeline for O(1) scroll/zoom, background processing via SwingWorker, and smooth zoom/pan interaction. The app takes any JPG, PNG, or GIF image, converts each pixel to a grayscale luminance value using the Rec. 601 standard, and maps it to one of 70 ASCII characters ordered by visual density (Paul Bourke gradient). The result is rendered into a scrollable, zoomable panel and the intermediate grayscale image is saved to disk automatically. Conversion reads pixels directly from a BufferedImage (getRGB), computes per-pixel luminance with the Rec. 601 luma coefficients (0.299R + 0.587G + 0.114B), and maps each value through a static lookup table to one of 70 density-ordered ASCII characters. The hot pixel loop uses a StringBuilder for O(n) assembly, and the whole conversion runs on a SwingWorker so the UI never blocks. The rendered ASCII is drawn once into an off-screen buffer, so scrolling and zooming stay O(1) regardless of image size — nearest-neighbor interpolation keeps it crisp when zoomed in, bilinear keeps it smooth when zoomed out. Interaction is handled with a MouseAdapter for drag-to-pan (using screen coordinates for stable deltas) and getPreciseWheelRotation for smooth Ctrl+scroll zoom, with an InputMap/ActionMap shortcut system scoped to the focused window. Swing GUI from scratch — custom layouts, components, and event handling; Multithreading & concurrency — SwingWorker keeps the UI responsive during conversion; Off-screen rendering — pre-rendered BufferedImage makes scroll and zoom O(1) at any image size; Image processing — pixel-level RGB manipulation via getRGB / setRGB; Grayscale conversion — Rec. 601 luma coefficients (0.299R + 0.587G + 0.114B); Algorithm/data-structure use — static lookup table for the brightness → character mapping; Image scaling — SCALESMOOTH downscaling with zoom-aware nearest-neighbor / bilinear interpolation; Keyboard shortcut system — InputMap / ActionMap with WHENINFOCUSEDWINDOW scope; Performance optimization — StringBuilder over concatenation in hot pixel loops for O(n); Pan & zoom UX — drag-to-pan, precise Ctrl+scroll zoom, and fit-to-window on every transform; Layout management — responsive nested BorderLayout so zoom controls stay visible at any width; Error handling — IOException propagation with user-facing dialogs, no silent failures; Object-oriented design — separate converter, text panel, and prompt components; JAR packaging — distributed as a standalone runnable JAR Java 17+; Java Swing / AWT (BufferedImage, Graphics2D, SwingWorker, InputMap / ActionMap, MouseAdapter); Packaged as a standalone runnable JAR (ImageToText.jar)

JavaConcurrencyProcessing
No. 14

Instagram Non Follower Finder

A desktop app that automates finding Instagram accounts you follow that don't follow you back. Built with Python, Selenium WebDriver, and CustomTkinter — it drives a real browser to scroll and extract your follower/following lists, applies hand-rolled anti-bot stealth, and presents the diff in a clean dark-mode GUI with cross-browser support. Cross-browser — Chrome, Firefox, Edge, Safari; Stealth mode — patches automation fingerprints to reduce bot detection across browsers; Manual login flow with full 2FA and captcha support; Auto-downloads browser drivers (no PATH setup required); Accumulates users across virtual-scroll batches so no one is missed; Results copyable to clipboard The app launches a real browser through Selenium WebDriver and lets you log in manually (so 2FA and captchas just work). To reduce automation detection, it injects a small stealth script that redefines navigator.webdriver — via the Chrome DevTools Protocol (Page.addScriptToEvaluateOnNewDocument) on Chromium browsers and executescript on Firefox — alongside flags like --disable-blink-features=AutomationControlled and Firefox's dom.webdriver.enabled = false. It then opens your followers and following dialogs and uses ActionChains with ScrollOrigin to scroll the virtual-scrolling lists, accumulating usernames across batches until the full list is captured. A set difference between following and followers yields the accounts that don't follow you back. All of this runs on a background threading worker so the CustomTkinter UI stays responsive, with per-browser error dialogs when a driver fails to start. Browser automation — Selenium WebDriver driving Chrome, Firefox, Edge, and Safari; Cross-browser abstraction — per-browser options and driver setup behind one flow (match/case); Anti-bot stealth — CDP navigator.webdriver patching and disabling automation fingerprints; Dynamic web scraping — ActionChains + ScrollOrigin to drive virtual-scroll list extraction; Set operations — diff of following vs. followers to surface non-followers; Multithreading & concurrency — background threading worker keeps the GUI responsive; GUI development — CustomTkinter dark-mode desktop interface; Robust error handling — per-browser driver-failure dialogs and captcha/2FA-friendly login; Automatic driver management — webdriver-manager for Firefox/Edge; Chrome 115+ self-manages; Clipboard integration — one-click copy of results; Application packaging — PyInstaller native build via build.py Python 3.10+ (match/case); Selenium WebDriver (Chrome, Firefox, Edge, Safari); CustomTkinter (dark-mode GUI); webdriver-manager (Firefox / Edge driver management); Chrome DevTools Protocol (stealth script injection); threading (responsive UI); PyInstaller (native app packaging)

PythonpipSelenium
No. 15

PONG

A fully playable Pong game built in Java with Swing, featuring local two-player multiplayer and a single-player mode against a predictive AI that simulates the ball's full trajectory — including wall bounces — to anticipate where it will land. Single-player mode — AI that simulates the ball's full trajectory (including wall bounces) to predict its landing position, with a speed cap and randomised error margin so it's challenging but beatable; Two-player local multiplayer — both players share the keyboard; Physics-based ball mechanics — bounce angle depends on where the ball strikes the paddle; ball speed increases 5% per volley up to a maximum, rewarding longer rallies; Clean menu UI with keyboard navigation The game runs on a javax.swing.Timer firing at 60 FPS on the Event Dispatch Thread, so updates and repaints stay smooth without ever blocking the EDT with Thread.sleep. Ball physics are vector-based: each return angle is computed from the hit position relative to the paddle centre (rel × 60°), so edge hits produce steep angles and centre hits produce flat returns, with the velocity decomposed via cos/sin. Speed builds 5% per volley up to a hard cap (MAXSPEED), making long rallies progressively harder to control. The AI opponent projects where the ball will land by running a frame-by-frame physics simulation (predictBallY) that mirrors the wall-bounce logic. To stay beatable, it recomputes its target only every ~15 frames, applies a ±25px position error, moves slightly slower than the player, and drifts back to centre when the ball is travelling away — so it can be consistently beaten by pushing the ball into the corners at high speed. Object-oriented design — game state, rendering, and input separated across classes; Event-driven programming — Java Swing event dispatch and key handling; Game loop architecture — javax.swing.Timer at 60 FPS, no blocking on the EDT; Game physics — vector velocity, trigonometric bounce angles, per-volley speed ramping; Collision detection — ball-versus-paddle and ball-versus-wall response; Game AI — predictive opponent via frame-by-frame trajectory simulation; Vector math & trigonometry — cos/sin angle decomposition from paddle hit position; 2D rendering — custom Graphics drawing of paddles, ball, scores, and menu; Input handling — multi-key state tracking and keyboard menu navigation; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17+; Java Swing / AWT (JPanel, JFrame, Graphics, javax.swing.Timer); Java Platform Module System (module-info.java, requires java.desktop); Packaged as a runnable modular JAR (PONG.jar)

JavaGame PhysicsGame AI
No. 16

Cockroach

A real-time 2D Java desktop game where cockroaches swarm in from the edges of the screen. Squash them before they eat your crumbs. The cockroaches run a lightweight greedy-steering AI to seek food and flee from fast cursor movement, all rendered with procedural Graphics2D animation. Cockroaches spawn continuously from all four edges and wander across the screen. Drop bread crumbs to lure them — cockroaches use greedy steering to seek the nearest crumb and will eat it down to nothing. Move your cursor too quickly near a cockroach and it will scatter. Left-click to squash; a splat mark fades on the floor where it died. Swing game loop — javax.swing.Timer drives all updates on the EDT, giving thread-safe state mutation without locks while keeping repaint latency low.; Greedy steering AI — cockroaches find the nearest crumb and pick the 8-directional heading with the highest dot product against the target bearing, replacing an earlier pixel-level BFS that allocated a fresh 600 × 600 visited array per entity per tick.; Flee behaviour — peak cursor speed is sampled between direction-update cycles; any cockroach within 100 px when the speed threshold is exceeded steers directly away for ~0.8 s.; Custom 2D renderer — entities are drawn with Graphics2D transforms (translate → rotate → scale): body oval, head, eyes, antennae, and three leg pairs, all rotated to face the direction of travel. Death plays a squish-and-fade animation by scaling the transform over 100 frames.; Persistent splat marks — squash events stamp a dark oval into a separate list that fades over ~5 seconds independently of the entity lifecycle.; Crumb consumption — each crumb has 10 health points; stopped cockroaches bite stochastically (~3 % chance per frame), and the crumb shrinks visually in proportion to remaining health. Object-oriented design — Cockroach, Entity, Mouse, and Layout classes; Event-driven programming — Java Swing mouse handling and timer-driven updates; Game loop architecture — javax.swing.Timer on the EDT for lock-free, thread-safe state; Game AI & steering behaviours — greedy seek toward nearest crumb, flee on fast cursor; Vector math — 8-directional heading chosen by maximum dot product against the target bearing; Performance optimisation — replaced a per-tick 600×600 BFS scan with O(1) greedy steering; Collision & hit detection — click-to-squash hit testing and crumb proximity; Custom 2D rendering — Graphics2D affine transforms (translate/rotate/scale), procedural sprites; Animation — squish-and-fade death and time-decaying splat marks; Object lifecycle management — independent entity, crumb, and splat lists; Stochastic behaviour — probabilistic crumb biting and randomised spawning; Input handling — left-click squash, drag-and-throw, right-click crumb placement; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17+; Java Swing / AWT (JPanel, Graphics2D, javax.swing.Timer, MouseListener); Java Platform Module System (module-info.java); Packaged as a runnable JAR (cockroach.jar); Eclipse IDE

JavaGame AITesting
No. 17

Exorcist

A 2D infinite climbing platformer built in Java (Swing). Jump between procedurally generated platforms, fight four enemy types with a responsive combat system, and climb as high as you can. Built on an object-oriented entity hierarchy with state-machine AI, custom collision physics, and a sprite-sheet animation system. Procedural generation — platforms, hazards, and enemy placements are generated on the fly with increasing difficulty as you ascend; Four enemy types with distinct AI behaviors: melee aggression, ranged cursing, aerial pursuit, and heavy tanking; Fluid combat — attack, double jump, and a stamina-based shield that rewards timing; Persistent high score saved between sessions; Polished animations — per-entity sprite sheets with state-driven animation (idle, walk, attack, death); Responsive game feel — fall damage, knockback, curse DoT with visual feedback, half-heart regeneration The game is organised around an object-oriented entity model: a shared Entity base provides movement, health, and animation state, and each enemy (Wolf, Golem, Witch, Bat) and the Player extends it with its own state-machine AI. GamePanel drives the update/render loop, CollisionChecker resolves platform and combat collisions, and TileManager builds the world from map files while scrolling infinitely upward and generating fresh content as you climb. Each entity animates from sprite sheets driven by its current state (idle, walk, attack, death). Physics covers gravity, jumping and double-jumping, knockback, and fall damage for long drops. Input is split between KeyHandler and MouseHandler, audio plays through javax.sound.sampled via a dedicated Sound class, and the high score persists to disk between sessions. Move, double jump, attack, and shield; 5 hearts HP with 2 bonus overflow hearts (earned from kills); Shield with stamina bar — blocks frontal attacks, depletes on sustained use; Half-heart regen every 20 seconds; Fall damage for drops over 10 tiles Object-oriented design — Entity base with Wolf / Golem / Witch / Bat / Player subclasses; Inheritance & polymorphism — shared entity behaviour specialised per enemy; State-machine AI — per-entity behaviour and animation states; Game AI — four distinct enemy behaviours (melee lunge, ranged kiting, aerial pursuit, tank); Procedural generation — infinite upward platform, hazard, and enemy generation with scaling difficulty; Collision detection & physics — CollisionChecker, gravity, double jump, knockback, fall damage; Sprite animation system — state-driven sprite-sheet animation (idle/walk/attack/death); Game loop architecture — GamePanel update/render cycle; Custom 2D rendering — Java Swing Graphics2D with AlphaComposite effects; Input handling — separate keyboard and mouse handlers; Audio playback — sound effects via javax.sound.sampled; Tile-map system — TileManager loading map files with infinite scrolling; File I/O — persistent high score and map loading; Combat systems design — stamina shield, curse DoT, half-heart regen, overflow hearts; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 17; Java Swing / AWT (Graphics2D, AlphaComposite, 2D rendering); javax.sound.sampled (audio); Java Platform Module System (module-info.java); Packaged as a runnable modular JAR (Exorcist.jar); Eclipse IDE

JavaGame AISwing
No. 18

Go Board Game

A fully playable 19×19 Go board game built in Java using the Processing library. It enforces the Chinese ruleset, handles all the tricky game logic (ko, suicide, group capture via BFS liberty checking), and renders smooth 3D-style stones with real-time hover feedback. This project implements the ancient strategy game of Go as a standalone desktop application. It enforces Chinese ruleset scoring, handles all edge-case game logic (ko, suicide, group capture), and renders smooth 3D-style stones with real-time hover feedback — built on top of Processing's Java2D rendering pipeline. Chinese rules — area scoring (stones + territory) with 7.5 komi for White; Capture detection — BFS flood-fill liberty checking for individual stones and connected groups; Ko rule — rejects moves that recreate the previous board position; Suicide prevention — illegal self-capture moves are blocked before placement; Pass & Reset — pass your turn or restart the game at any time; Game end — two consecutive passes trigger automatic scoring and declare a winner; Territory visualisation — empty intersections are marked at game end to show each player's scored regions; 3D stone rendering — each stone is drawn with shadow, radial gradient, and specular highlight layers; Hover preview — semi-transparent ghost stone follows the cursor for precise placement; App icon — custom logo displayed on the window, taskbar, and macOS Dock The board state and rules live in a Go logic class, kept separate from the Sketch class that handles all Processing rendering and input. Captures are resolved with a BFS flood-fill: when a stone is placed, each adjacent enemy group is flooded to count its liberties, and any group with zero liberties is removed. The same liberty check, applied to the just-placed stone, enforces suicide prevention. The ko rule is implemented by snapshotting the previous board position and rejecting any move that would recreate it. At game end (two consecutive passes), the engine performs Chinese area scoring — counting each player's stones plus the empty territory they fully enclose, adding a 7.5 komi for White, and declaring the winner. Stones are rendered as layered 2D primitives (drop shadow, radial gradient body, specular highlight) for a 3D look, and a translucent ghost stone tracks the cursor for precise placement. Object-oriented design — game logic (Go) separated from rendering/input (Sketch); Game-rule engine — complete Go ruleset with Chinese area scoring and komi; BFS flood-fill — stone and connected-group liberty/capture detection; Graph connectivity — flooding adjacent groups to evaluate captures; Ko-rule detection — rejects moves that repeat the previous board position; Suicide-move prevention — illegal self-capture blocked before placement; Territory scoring — enclosed-region detection for end-game area scoring; Custom 2D rendering — layered 3D-style stones (shadow, radial gradient, specular highlight); Interactive UI — real-time hover ghost-stone preview; Game state management — turn order, pass, reset, and automatic end detection; Processing framework — PApplet with the Java2D renderer; Application packaging — window/taskbar/Dock icon and a runnable JAR Java 17; Processing (PApplet, Java2D renderer; core.jar); JOGL / GlueGen (bundled native libraries shipped with Processing for cross-platform support); Packaged as a runnable JAR (Go.jar)

JavaGoProcessing
No. 19

Snake

A fully playable, built-from-scratch Snake game written in Java Swing — my first independent software project. It implements a complete fixed-timestep game loop, custom 2D rendering, collision detection, and persistent high-score storage using only the Java standard library, with no game engine or third-party dependencies. Grid-based snake movement on a 60×30 board with wrap-around borders; Apple spawning that never lands on the snake's current body; Real-time score plus a persistent high score saved across sessions; Start and game-over overlays, with instant restart (R) without relaunching; WASD and arrow-key controls, with 180° reversal protection; Custom-drawn HUD, snake, food, and translucent message overlays The game is driven by an event-driven loop built on a javax.swing.Timer that fires about 12 times per second (FPS = 12). On each tick the game applies buffered input, advances the snake one cell, runs collision checks, and triggers a repaint. Input is deliberately decoupled from movement: a keypress only sets a pending direction (nextXv / nextYv), which is committed at the start of the next tick. A guard rejects any direct 180° reversal — this eliminates the classic bug where two quick keypresses between frames fold the snake back onto itself. The playfield wraps at every edge, so leaving one side re-enters from the opposite one. The snake's body is stored as a trail of grid coordinates; each tick appends the new head and trims the tail to the current length. Self-collision is detected by scanning the trail for the head's position, and food is re-rolled until it lands on an empty cell. The high score is persisted to a dotfile (~/.snakehighscore) in the user's home directory — loaded on startup, written on every new record, and flushed again on exit (window close or Esc). All visuals are produced in a single custom paintComponent override using AWT Graphics primitives. This was my first programming project, written to learn the fundamentals of Java, event-driven GUI design, and game-loop architecture from the ground up. It has since been refactored to fix several original bugs — timer misuse on the event dispatch thread, game logic embedded in the paint method, and incorrect high-score tracking — while preserving its original structure and scope. Object-oriented design — game model, rendering, and input separated across classes; Event-driven programming — built on Java Swing's event dispatch model; Game loop architecture — fixed-timestep loop via javax.swing.Timer (~12 FPS); 2D rendering — custom paintComponent / Graphics drawing of every element; Collision detection — self-collision and boundary wrap-around; Input handling — buffered direction changes with 180° reversal prevention; Separation of concerns — KeyListener decoupled from game and render logic; File I/O — persistent high-score storage across sessions; Application lifecycle handling — save-on-exit via a WindowListener; Java Platform Module System — modular build with module-info.java; JAR packaging — runnable modular Java application Java 11+; Java Swing (JPanel, JFrame, javax.swing.Timer); AWT (Graphics, Color, Font, FontMetrics, KeyListener / KeyEvent); Java Platform Module System (module-info.java); java.io file I/O; Packaged as a runnable modular JAR (Snake.jar)

JavaSwingObject-oriented design
No. 20

Competitive Programming

Solutions to competitive programming problems from the Canadian Computing Competition (CCC) and DMOJ, written in C, C++, and Java. The collection spans 150+ solved problems across algorithms, data structures, dynamic programming, graph theory, string processing, and computational geometry. The CCC is Canada's premier annual high school programming competition, organized by the University of Waterloo. This repository contains Senior division solutions spanning 15 years (2000–2014), as well as class materials and practice problems from two competition seasons (2022–2024). Sorting & Searching — binary search, merge sort, quicksort, dual-pivot quicksort, BST; Graph Algorithms — BFS, DFS, shortest path, cycle detection, Eulerian paths; Dynamic Programming — coin change, knapsack, frog DP, sequence DP; Data Structures — binary search trees, hash tables, disjoint sets, segment trees; String Processing — pattern matching, compression, encoding (Huffman, Morse, CRC); Math & Combinatorics — modular inverse, fast exponentiation, RSA numbers, Fibonacci; Geometry — Voronoi diagrams, triangle problems, spiral patterns Solutions to problems from DMOJ: Modern Online Judge, an online judge for Canadian high school competitive programming. Competitive programming — CCC and DMOJ contest problem solving; Algorithms & data structures — broad coverage across 150+ solved problems; Graph algorithms — BFS, DFS, shortest path, cycle detection, Eulerian paths, max flow; Dynamic programming — coin change, knapsack, and sequence DP formulations; Sorting & searching — binary search and merge / quick / dual-pivot quicksort; Tree & set structures — binary search trees, disjoint sets, segment trees, hash tables; String processing — pattern matching, compression, and Huffman / Morse / CRC encoding; Math & combinatorics — modular inverse, fast exponentiation, RSA, Fibonacci; Computational geometry — Voronoi diagrams, triangle and spiral problems; Multi-language fluency — solving the same class of problems in C, C++, and Java; Complexity & optimization — meeting contest time and memory limits C; C++; Java; Eclipse IDE (CCC / DMOJ workspaces)

JavaC++C
No. 21

Learning

A collection of programming projects spanning my learning journey — from writing my first lines of Java and C++ through implementing classic graph algorithms and teaching others. It ranges across language fundamentals, data-structure and graph-algorithm implementations, small utilities, and material I prepared as a high-school programming instructor. Foundational Java projects built through a structured course, including GUI programs, sound playback, and user input handling. Entry point into object-oriented programming. Java practice workspace from 2022, used for experimenting with new concepts alongside formal coursework. Selected projects from a guided Java curriculum — includes a Length Converter, Word Counter, and an image display program. Focused on practical application of core Java APIs. Implementations of classic graph and tree algorithms in Java: Material prepared and taught as an instructor in a high school programming club. Includes introductory exercises and guided problems written to help beginners get started with Java. Small utilities written for personal use — prime number tools and helper scripts for everyday tasks. Stars and Bars — combinatorics calculator; Galois 2022 4 — solution to a Galois Contest problem; Change Finder — coin change problem variant 26 single-topic programs covering the full introductory C++ curriculum: Variables · Data Types · Numbers · Strings · Arrays · 2D Arrays · User Input · If Statements · Switch Statements · For Loops · While Loops · Functions · Return Values · Pointers · Classes & Objects · Constructor Functions · Getters & Setters · Object Functions · Inheritance · Calculator · Guessing Game · MadLibs · Exponent Function · Comments · HelloWorld Each program isolates one concept, making this a clean reference for C++ fundamentals. Object-oriented programming — Java and C++ fundamentals through to small projects; Data structures — binary search trees and disjoint-set union; Graph algorithms — Dijkstra's shortest path, Prim's & Kruskal's MST, Tarjan's & Kosaraju's SCC; Graph traversal & validation — Eulerian paths and directed/undirected cycle detection; Algorithm implementation — classic graph and tree algorithms written from scratch; Combinatorics & math — stars and bars, coin change, and contest math problems; GUI programming — Java Swing projects with sound playback and user input; C++ fundamentals — 26 single-topic programs (pointers, classes, inheritance, and more); Practical utilities — converters, a word counter, image display, and prime-number tools; Teaching & mentoring — prepared and taught high-school programming-club material; Self-directed learning — a multi-year progression across two languages Java; C++; Java Swing (GUI projects); Eclipse IDE

JavaCSSC++

Curriculum Vitae

Experience

May 2026 – Present

Ford Motor Company

Software Developer Intern

Working on Android Automotive OS (AAOS) development at Ford, contributing to the in-vehicle Car Dialer app for Ford's infotainment system. Work spans call management via the Android Telecom framework, Bluetooth Hands-Free Profile (HFP) integration, UI development across multi-module architecture, and unit testing with Robolectric.

JavaKotlinXMLAndroid SDKAndroid Automotive OSBash/ShellGroovyGit

Jun 2025 – Aug 2025

University of British Columbia

Undergraduate Research Assistant

Worked under Dr. Martin McKeown and Prof. Z. Jane Wang at the Djavad Mowafaghian Centre for Brain Health, contributing to PIKA — an AI-driven Parkinson's care platform deployed at Vancouver Coastal Health. I owned development of two full-stack hand rehabilitation apps within the platform. HandEase gamifies rehab as a farming-style game where hand gestures control gameplay (finger tapping summons rain to water plants), making exercises feel engaging rather than clinical. Palm & Plant is the medical counterpart, designed for structured clinical sessions with detailed progress tracking. Both share the same core: a computer vision pipeline (OpenCV + MediaPipe) that detects 7 hand gestures at ~90% accuracy in real time (<100ms latency), running entirely on-device to meet PIPEDA and GDPR privacy requirements. I also built activity heatmap dashboards that cut practitioner monitoring overhead by 30%, giving clinicians a clearer picture of patient progress between appointments. Presented at the 11th Singapore International Parkinson Disease & Movement Disorders Symposium, with projected deployment across hospitals in 10+ countries.

PythonOpenCVMediaPipeNumPyPandasMatplotlib

Aug 2021 – May 2024

Kumon Inc.

Math & Reading Instructor

Recruited directly by the Kumon supervisor after standing out as a top-performing student in both Math and Literature — a distinction that made me more effective as an instructor from day one. Over three years, worked with 100+ students across a wide range of skill levels, adapting explanations on the fly to match each student's pace rather than following a rigid script. The core challenge was balancing class-wide flow with meaningful one-on-one attention — reading where each student was at, adjusting in the moment, and delivering feedback precise enough to move them forward without overwhelming them. Consistently saw improvement in both test results and student confidence over time.

The Toolkit

Skills

  • Languages: TypeScript, JavaScript, TeX, Python, Jupyter Notebook, Java, C++, Processing, C, Kotlin, CSS, XML, Bash/Shell, Groovy
  • AI & ML: Anthropic API, Transformers, Reinforcement Learning from Human Feedback (RLHF), Policy-gradient methods, Reward modeling, Generalized Advantage Estimation (GAE), Adaptive KL control, Supervised fine-tuning (SFT), Deep learning with PyTorch, Parameter-efficient fine-tuning, LLM-as-Judge Evaluation, Reward-hacking mitigation, Machine Learning, Generative AI / LLMs, Probabilistic reasoning, Computer Vision, OpenAI API, LLM application development, Structured outputs, Semantic Search & Embeddings, Hierarchical classification, Retrieval-Augmented Generation (RAG), Cross-encoder reranking, Listwise LLM reranking, Personalized PageRank, Approximate nearest neighbor (ANN), Grounded generation, Prompt engineering, ReAct agent loop, Reflection / self-correction, Accessibility-tree observation, Set-of-Marks visual grounding, Provider-agnostic LLM abstraction, Typed action space with validation, Agent Workflow Memory (AWM), Anti-hallucination engineering, Gesture Recognition, Pose Estimation, ML Inference, Real-time Systems
  • Algorithms & DS: A* Pathfinding, Proximal Policy Optimization (PPO), Direct Preference Optimization (DPO), Group Relative Policy Optimization (GRPO), Constraint-propagation solver, Algorithms & Data Structures, Graph Connectivity Analysis, BFS flow-field pathfinding, Algorithmic navigation, Breadth-first search, State-space reduction, Competitive programming, Graph algorithms, Dynamic programming, Sorting & searching, Tree & set structures, String processing, Combinatorics & Math, Computational geometry, Complexity & optimization, Performance optimization, Custom data structure design, Intrusive data structures, Cache optimization, Data Structures, Graph traversal & validation, Hybrid search, Code graph construction, Computational Complexity
  • Statistics & Evaluation: Reproducibility and static analysis, Evaluation methodology, Statistical rigor, Deterministic benchmark scoring, Significance testing, Cross-evaluator agreement, Reproducible experiment logging, Probability, Statistics
  • Concurrency & Networking: Multiplayer presence, Real-time animation, Networking, Distributed / multi-GPU training, Concurrency, Real-time state propagation, Real-time control loop, Producer–consumer queue, Background processing, Thread-safe state, Wait-free synchronization, Distributed Systems, Parallel evaluation
  • 3D Graphics: OpenGL, 3D graphics programming, Ray-cast picking
  • Systems & Embedded: Robotics & Embedded, Sensor integration & fusion, Motor control, Serial communication, Hardware calibration, Computer Architecture
  • Systems & Performance: Numerical stability, RAII & smart pointers, Modern C++20, Bitmasking & state encoding, Low-latency systems programming, Bit manipulation, Custom memory allocation, Open-addressing hash map, Lock-free programming, C++ memory model, Template metaprogramming, Fuzzing, Sanitizers, C++, C++ fundamentals
  • Security & Crypto: Security & secret hygiene
  • Compilers & Languages: AST parsing, Tokenization, Assembly & Compilers
  • Finance & Trading: Matching-engine domain, Financial-exchange order types, Event sourcing and deterministic replay, Pre-trade risk management, Binary protocol design
  • Game AI: Procedural generation, Game AI & steering behaviours, State-machine AI
  • Game Dev: Collision detection & physics, Particle systems, Game Development, Game Physics, Collision detection, Game logic, Vector math & trigonometry, Vector math, Collision & hit detection, BFS flood-fill, Procedural graphics, Game-rule engine, Ko-rule detection, Territory scoring, Entity–component modelling, Spatial partitioning, Game systems design, Tile-map system, Combat systems design, Maze mapping
  • UI & 2D: HTML5 Canvas rendering, 2D rendering, Custom 2D rendering, Animation, Dynamic UI scaling, Interactive UI, Sprite animation system, Interaction design, UX engineering, GUI development, Swing GUI from scratch, Off-screen rendering, Pan & zoom UX, Declarative UI, Reactive state management, Material Design 3
  • Web & Backend: GraphQL, REST, REST API and route handlers, Redis with Upstash REST API, External API integration, Web Development, Backend / APIs, Automation / Scraping, Browser automation, Anti-bot stealth, Dynamic web scraping, Rate-limit handling, Content extraction, Provider-agnostic API design, HTTP server, MCP (Model Context Protocol) server, LiteLLM, Rate-limit resilience
  • Architecture & Design: Game engine architecture, Software design, Object-Oriented Design, Event-driven programming, Game loop architecture, Separation of concerns, Application lifecycle handling, Java Platform Module System, Polymorphism & abstract base classes, Inheritance, Strategy-style effect system, Model–view separation (MVC), Object lifecycle management, Game state management, Inheritance & polymorphism, Autonomous navigation, Data modelling, Persistence, Cross-browser abstraction, MVVM architecture, Local persistence, Repository design pattern, Navigation, Component reuse, Lifecycle awareness, Provider abstraction (strategy pattern), Factory pattern
  • Testing & Delivery: CI/CD & DevOps, Testing, JAR Packaging, Cross-Platform Builds, Packaging, Property-Based Testing, Debugging with invariants, Gradle build system, Shipping to production, Benchmarking methodology, Build and CI engineering, Benchmarking, Testing & Debugging
  • Reliability & Ops: Accessibility and performance, Checkpointing and resumability, Performance optimisation, Robust error handling, Error handling, Fault tolerance, Crash-safe file operations, Secrets management, Cost engineering, Privacy engineering, Automatic dependency management, Incremental computation, Resilience engineering, Failure taxonomy
  • Frameworks: Next.js, React, Swing, SDL2, Jetpack Compose, Dagger Hilt, AndroidX/Jetpack, LiveData, ViewModel, Android Telecom, Robolectric, JaCoCo, Android SDK, Android Automotive OS
  • ML / Data: NumPy, PyTorch, scikit-learn, Pandas, Matplotlib, SciPy, OpenCV, MediaPipe
  • Data & Visualization: PDF parsing, Data Analysis, Image processing, Grayscale conversion, Image scaling, Pillow, Interactive data visualization, Data visualization
  • Platform & I/O: Input handling, File I/O, Layout management, Audio playback, Automatic driver management, Clipboard integration, Keyboard shortcut system, Local notifications, Preferences storage, Mobile Development
  • Tools: TypeScript, GitHub Actions, Vitest, ESLint, Tailwind, pip, CMake, Selenium, Gradle, JUnit, Make, Playwright, Docker, Android Studio, Jira, Ford SDK, scrcpy, Git, Version Control (Git), Linux / Shell
  • Concepts & Practices: Framer Motion, R, React and Next.js (App Router), Conditional compilation, Command parsing, Stochastic behaviour, Go, Processing, Suicide-move prevention, Processing framework, Iterative engineering, Java, Multi-language fluency, Set operations, Requests, Prompt caching, CLI design, Practical utilities, Teaching & mentoring, Self-directed learning, Assembly, JavaScript, HTML, Docker sandbox integration, Cost/token accounting, Unit Testing, Code Review, Multi-module Architecture, Bluetooth/HFP, Agile/Scrum, OOP, Object-Oriented Design, Functional Programming, Logic & Computation
  • Soft Skills: Collaboration, Technical Writing, Agile, Weekly Standups, Clinician Collaboration, Communication, Patience, Adaptability, Leadership
  • Build & CI: Gradle, AOSP/Soong, SonarQube, ADB, Docker
  • Research: Custom Libraries, Data Analysis, Research
  • Teaching: 1-on-1 Mentoring, Curriculum Adaptation, Lesson Planning, Progress Tracking, Classroom Management, Feedback Delivery, Student Assessment
  • Mathematics: Linear Algebra, Calculus, Combinatorics & Graph Theory, Optimization, Discrete Math & Proofs

Tap a circle to open it. A skill's colour is its category — skills in the same group share one colour, and each keeps that colour everywhere it appears (Work, Projects, Archive). Skills outside these groups show in grey.

The Grind

Competitive Programming

Problem-solving, pulled live from LeetCode and DMOJ.

The Curator

About

The summer after grade 8, my parents signed me up for a Java course over Zoom — AP Computer Science, mostly to get me to stop playing video games. It backfired beautifully: I got hooked on building things instead, and now I build an unreasonable number of games anyway. I'm a CS student at the University of Waterloo, and what really gets me is figuring out how something works and then making something people can actually use — lately that's been Android Automotive at Ford and computer-vision rehab tools at a UBC research lab. Longer term I'm aiming for the deep end — the large-scale systems, AI, and quant work that the biggest tech, research, and trading firms are built on — and I'm at my best with a genuinely hard problem in front of me. Off the clock I'm usually on a snowboard, partway up a climbing wall, or somewhere new. Off the clock — Snowboarding and skiing in winter, climbing and hiking the rest of the year, and travelling somewhere new whenever I can — usually chasing good coffee and food along the way. Otherwise: board games and chess, a rotating lineup of film and anime, books, music, and building games and little open-source side projects for the fun of it.

Stay in touch

Let's talk