goektan.dev
University ProjectB.Sc. coursework · Solo — university project

Labyrinth.

2D maze game in Java with MVC architecture — OOP course project.

JavaMVCOOP DesignUniversity Project
Labyrinth — primary screenshot
01Overview

A 2D Labyrinth game in Java. The player has to find the exit of a maze while avoiding stalkers that chase them; an invisibility potion freezes the stalkers for three rounds. Built for the 2nd-semester Object-Oriented Programming course where the actual grading criterion was the architecture — MVC discipline, observer pattern, clean inheritance — not the gameplay.

02The problem

What it solves.

Game projects are a classic OOP teaching tool because they force you to model real interactions between entities (player ↔ stalker ↔ environment) with shared behaviors. The trap is to start ad-hoc, end up with one God-class, and fail the design review. The challenge was twofold: (a) get the architecture right under the course's grading criteria, and (b) come back after submission to fix the things I'd missed.

03The build

How it's solved.

  1. 01

    Model — Level holds dynamic state (player, stalkers, powerups, effects). Map loads the static grid from an ASCII text file. Tile is abstract; Wall and Corridor inherit. Entity is abstract for anything that moves; Player and Stalker inherit. Powerups/effects abstracted through Powerup and Effect interfaces.

  2. 02

    View — View is an interface; concrete views (ConsoleView, GraphicView) register on the level and get notified when state changes (observer pattern). GraphicView renders the board with Swing sprites + toolbar + status bar; ConsoleView exists for debugging.

  3. 03

    Controller — Listens for key events and toolbar actions, calls matching methods on Level. Knows nothing about drawing — that flows model → views via observer updates. Entry point wires everything on Swing's Event Dispatch Thread.

  4. 04

    Levels as plain text files in resources/map/ — each character is one tile (+ wall, . corridor, s start, f finish, e stalker, i potion). Loading validates structure and throws IOException with row/column on the first invalid character.

  5. 05

    Stalker AI: simple greedy rule — try the axis with larger distance first, fall back to the other axis if blocked. Not optimal (they get stuck in dead ends sometimes), but for hand-designed level sizes it works.

04Highlights

What makes it interesting.

MVC discipline as the actual deliverable

The interesting deliverable wasn't the game — it was the MVC separation. Controller doesn't draw; View doesn't mutate state; Model fires observer updates. Each piece is testable in isolation.

Came back after submission to refactor

Post-submission cleanup pass: fixed an equals()-without-hashCode() bug that broke HashSet usage, switched resource loading from filesystem paths to classpath (so the JAR actually works when launched from anywhere), and tightened the map parser to fail loudly on unknown characters — which surfaced two typos in shipped level files that the old silent fallback had hidden.

Validating input loudly is worth the noise

Old parser silently treated unknown characters as corridors. New version throws IOException with exact row and column. Caught a stray comma in level1.txt and stray space in level2.txt that had been invisibly buggy since submission.

05— Gallery
Labyrinth screenshot 2
06Stack

Tech.

Language
Java 11+
GUI / rendering
Java SwingAWT
Pattern
MVCObserver (view updates)
Build
Maven
Resources
ASCII map files32×32 PNG sprites
Tooling
IntelliJ IDEAGit
Questions about this project?Get in touch