A Battleships Game I Built in One Day (in 2014)
I found a fully functional Battleships game I built in one day during a 2014 work trial. Looking at it now, it accidentally shows how I’ve always approached engineering.
In early 2014, I interviewed for Silktide. They were a local tech company that had the kind of energy and ambition that was rare in the Midlands tech scene at the time. They seemed to care. It felt different.
As part of the interview process, they invited me to a paid one-day work trial. It was surprisingly forward-thinking — almost a precursor to the modern approach taken by companies with a high product bar (like Linear), where the work trial is the interview.
My task for the day: build a playable game of Battleships.
Not your usual interview exercise. But perfect for me.
Silktide, by the way, was mostly a PHP shop. Back then, most companies leaned heavily on the backend, with a bit of JS sprinkled on top. I’d drifted hard towards JavaScript instead. I liked its liveness. Working directly with the user felt like sculpting something alive, not waiting for the backend to respond.
So I went all in with JS, and by the looks of it I picked Backbone. Actually, a pretty solid choice for the time. A stepping stone to React and the patterns we take for granted today.
By the end of the day I not only had a working Battleship game, but also a surprisingly competent enemy AI.
UI: the instinct for “feel”
The ship placement system still cracks me up.
Drag and drop to place a ship. Press R to rotate it.
It feels more like a native app than a website. It’s low friction and makes the whole thing feel right. A very “me” decision, even back then.
There’s no modal.
No coordinate input.
No clunky forms.
Just drag, drop and rotate.
It teaches itself.
Even today, 11 years later, I opened it up and knew how to play without thinking.
Take a shot? Click the enemy grid.
Hit? Tile turns green.
Miss? Grey.
Sunk? Red.
Simple, obvious, satisfyingly direct.
And after taking a turn, the enemy also takes theirs. No clicking “next turn” or any friction.
The AI: simple but alive
The AI is basic, but not stupid.
It keeps a list of “known ship positions” — hits the enemy has landed but not yet converted into a sunk ship. When it has one of these, it tries hitting neighbouring squares. When it doesn’t, it fires randomly.
It blends both strategies. You could even tune enemy difficulty by adjusting that ratio.
Even with this simplicity, it feels alive and reactive. A bit unpredictable. Much more engaging than pure random shots.
And honestly, this is exactly how I build things today. The pattern:
- simple models
- small heuristics
- minimal rules
- arranged so that interesting behaviours emerge
The ships are just coloured blocks.
The AI is just a few heuristics.
The UI is barely skinned.
Significant events are literally shown with window.alert()
But together, they form something that works — something you can play.
The pattern
This is the pattern I’ve always gravitated towards:
- build something small
- make it tactile
- make it work
- let the system come alive before worrying about polish
Where many engineers front-load complexity, I’ve always preferred getting a working prototype into people’s hands and then iterating. Half the time the prototype turns out to be good enough. Keeping things simple forces you not to add what you don’t need. Exploring the problem is often how you solve the problem.
This little Battleships game is rough and unpretentious, and a perfect snapshot of that philosophy.
Conclusion
I didn’t think of myself as a “product engineer” or “systems thinker” back then. I just thought I was decent at writing code, and that I knew what felt right.
I was building in the only way I knew how.
Looking at it now, I realize they’re the same instincts I still rely on today.