Projects
AlphaZero Connect 4 bot 2026
A Connect 4 bot that learns by playing against itself, based on the AlphaZero paper. I built it
in four steps: the game itself, minimax with alpha-beta pruning, Monte Carlo tree search, and
then a neural network trained on its own games with PUCT search on top. Each new network has to
beat the previous one in a match before it gets kept.
-
After about 16 hours of training on my laptop's GPU, the network plus search beats my
alpha-beta engine at every depth I tried (0.78 score against depth 6 over 30 games with random
openings).
-
I measure how good it is by comparing its moves to a perfect Connect 4 solver on 6,000 test
positions. The self-play network got stuck at around 26.5% wrong moves.
-
I wasn't sure if that was because the network was too small or because it didn't have enough
training data, so I trained the same network on 300k positions labeled by the solver instead.
That got it down to 7.4%, so the problem was the data, not the network.
-
Early on my results were inflated because two deterministic bots play the exact same game every
time, so a 12 game match was really 2 games. All matches use random openings now.
-
291 pytest tests. The JavaScript version is tested against the Python version on 120 positions
to make sure they play the same moves, and the ONNX exports are checked against PyTorch.
Python, PyTorch, NumPy, pytest. Browser version in JavaScript with onnxruntime-web.
Code and writeup on GitHub
Tic-Tac-Toe with minimax, alpha-beta and MCTS 2026
I did this before Connect 4 to learn the search algorithms on a game small enough to check by
hand. Minimax, then alpha-beta pruning, then basic Monte Carlo tree search. A lot of the bugs I
would have hit in Connect 4 I hit here first.
Python, pytest.
Code
ModelBandit 2026
A service that reads an LLM prompt, works out what kind of task it is, and sends it to the
cheapest model that should be able to handle it. It keeps running averages of how every model
does on every kind of task and uses those to make the next decision, so it gets better with use.
Built after I kept paying GPT-4o prices for questions a 7B model could answer.
This is the server's real classifier and scoring code running in your browser against a
snapshot of the performance table. Type anything and it explains the decision.
Open it full size, or
use the full app, which actually calls the
models and learns from every request. It needs an account, and it's slow: the cheap models
take a few seconds.
Try the demo
Use the full app
-
Classification is two stages: weighted regexes decide clear prompts in under a millisecond, and
ambiguous ones fall through to nearest-neighbour search over 120 embedded example prompts.
Confidence is the margin between the top two candidates, not the raw match score.
-
Every model is scored per task type from its own history: confidence, cost, latency and how
often it needed escalating, normalised and weighted differently for code, math, chat and so on.
10% of requests pick a random model instead so it keeps finding cheaper options.
-
Low-confidence requests are retried one tier up, and both calls are recorded. Learning that
those retries were the classifier's fault, not the cheap model's, and lowering that penalty was
the change that made cheap models win where they should.
-
Every model, open-weight or not, is called through OpenRouter with one key. When a call fails
outright the request moves to another model at the same tier and the failure counts against
the one that broke. Accounts with per-user keys, per-IP rate limiting, and 154 Jest tests,
most of them prompts I once misclassified.
Node.js, Express, TypeScript, React, Postgres on Neon with Drizzle, Better Auth, OpenRouter, Jest, Docker.
Code and writeup on GitHub
Work
Zaytune Core contributor, full-stack · Feb 2026 to present
Zaytune is an AI chat app that routes each message to whichever model fits it best. There are two
of us working on the routing and reliability code, and I also do most of the frontend.
-
Co-designed the router: a 9-stage pipeline in Node.js that classifies each message by
complexity and intent and sends it to either a fast model or a reasoning model through
OpenRouter. It has an offline evaluation harness with unit tests so we can check routing changes
before shipping them.
-
Built the retry and reliability layer for the model providers: exponential backoff with jitter,
retries before the stream starts, per-provider failure tracking, and a retry button in the
client, so users still get a response when a provider returns 429s or 5xx errors.
-
Made an admin dashboard that saves routing traces, so we can look at why a request went to a
specific model and replay eval cases against real traffic.
-
Led the React/TypeScript frontend redesign: a design system with four themes, a rewrite of how
chat responses render, and mobile-first layouts.
-
Shipped compliance and growth features end to end: server-side geo-restriction for EEA, UK and
Switzerland, terms and privacy pages with age gating, and a sitemap and metadata for SEO.
-
Added Jest tests across the routing, reliability and API code.
Node.js, Express, React, TypeScript, MongoDB, Redis, Docker, Railway, GitHub Actions, Jest, Playwright.
Education
- Eastern Michigan University Expected December 2027
-
B.S. in Computer Science, GPA 3.8. Relevant coursework: data structures and algorithms, database
systems, discrete structures, computer organization and architecture.
- Washtenaw Community College 2023 to 2025
- Associate of Science in Computer Science, GPA 3.8. Transferred to EMU.
Skills
- Languages
- Python, TypeScript, JavaScript, Java, C++, SQL, Bash
- Frontend
- React, Vite, Tailwind CSS, Radix UI, TanStack Query, React Router
- Backend
- Node.js, Express, FastAPI, REST, server-sent events, Passport (JWT, OAuth2), Mongoose, Zod
- Data and infrastructure
- MongoDB, Redis, Meilisearch, Docker, Railway, GitHub Actions
- Machine learning
- PyTorch, reinforcement learning, Monte Carlo tree search, LLM APIs, model routing and evaluation
- Testing
- Jest, Playwright, pytest, offline evaluation harnesses
- Languages spoken
- English, Urdu, Hindi, Punjabi