Hide N Seek
A Hide and Seek game built in Python on top of the Python Graphics library — playable as either hider or seeker, and written under a course restriction banning lists and dictionaries entirely. Built for ICS2O, 2024.
Abstract
I created a hide and seek game in python for my high school's ICS2O class. This normally wouldn't be anything out of the ordinary... only there were restrictions. No lists, no dictionaries. The unit hadn't covered them, so we couldn't use them.
That sounds like a small restriction until you try to build the damn thing.
There is no array of colour swatches. There is no map from a clicked region to an action. There is no sprite list to iterate.
Every collection you'd normally reach for has to be written out by hand as individually named variables, and every lookup becomes a chain of comparisons.
The Price

The colour picker offers 8 preset swatches. Normally that's a loop over a list of eight (name, colour, rect) tuples. Here it's eight separately declared Rectangle objects with eight separate names.
The expensive part isn't drawing them... it's the selection state. When you click red, red gets a white 2px outline and the other seven have to go back to a black 0.5px outline. With no list to iterate, each of the eight branches manually resets the other seven, by name. That's roughly sixty lines to just "highlight the thing that was clicked."
Hit detection has the same shape. With no dictionary from region to handler, every clickable thing is a raw bounds check against hardcoded pixel coordinates:
if 50 < cust_mouseclick.getX() < 90 and 120 < cust_mouseclick.getY() < 160:The same pattern gates the play button, the tutorial button, the two gamemode panels, the map, and the exit button. Everything is coordinates, because coordinates are what's left.
Under the swatches there's an X11 colour name field that overrides the picker entirely, so anyone who wanted a colour I hadn't hardcoded could still have one without the game size further ballooning.
Sprites (or lack thereof)
Zelle's graphics library has no sprite or group concept, and I had no list to build one with. The player character is four separate objects: a body rectangle, two eye rectangles, and a nametag. Moving one step means calling .move() on all four with the same offset, in every one of the four direction branches, in both game modes.
The entire map operates the same way: the house, the car, the individual pool floaties...
Gameplay
Two (2) roles: you pick hider or seeker.

As seeker, you move with the arrow keys on a 1000-step budget. Distance to the hider is real Euclidean maths, and a ±45px box drives the hot/cold readout — "you are close to the hider!" versus "you are far." Getting within ±20px on both axes catches them.
As hider, you choose your spot on a half-scale map image and click; the click coordinates get doubled back into game space and marked with a pointer. Then the seeker is a bot: it picks a random direction, commits to a random run of 1–20 steps, and repeats. You watch its live coordinates and a step-distance readout tick down as it wanders toward or away from you, with no way to move - pretty tense when you see the bot getting closer and closer to you.
Either way, the round ends three ways: found, out of moves, or hidden to the end. The winner screen reports who won, how many moves it took, and where the hider actually was.

Design
For a project like this, simplicity is key. By starting from sticks and stones, I was able to create a unified design language throughout the app, where solid colored backgrounds, text/font hierarchy, and borderless dogma rule free.
Postmortem
Working inside a restriction you disagree with is a real skill. The no-lists rule made the code long and repetitive in ways I could see were wrong while I was typing them, and being able to see exactly why a list would have fixed it is the whole point of the exercise.
