Fight Game
- 2 Devlogs
- 4 Total hours
A Java turn-based fighting game where monsters, creatures, and chaos agents from opposing teams clash on a 10×10 arena.
A Java turn-based fighting game where monsters, creatures, and chaos agents from opposing teams clash on a 10×10 arena.
The quit option:
Added a Q — Quit option to the action menu so it appears on every turn. Typing it exits the game cleanly with a goodbye message. It’s also documented on the instructions screen now.
Trimming dead code:
Character.java carried a full set of getters and setters that nothing in the game actually called — every field is accessed directly. I removed all of them, so Character.java is now just its fields, the ANSI color constants, and a constructor, which is exactly what a data-model class should be.
Board.java documentation:
Added thorough inline comments throughout Board.java, explaining the grid primitives, the ANSI cursor-positioning trick used in printBoard() (the CELL/START column math that keeps emoji aligned), and every map-object method.
The big one — an automated test harness:
The headline addition is TestHarness.java, a standalone tool that stress-tests the whole combat system. It runs every character against every character — all 100 matchups, 20 times each, in two passes (once with map objects, once without) for roughly 4,000 battles. Both fighters are driven by the existing opponent AI, so no input is needed. Each battle is wrapped to catch any exception or assertion failure, and a turn cap catches any battle that never ends. At the end it prints a win-rate matrix plus a count of any crashes or timeouts.
Making this fast required one small change to Fight.java: an animationsEnabled flag, because the attack animation uses Thread.sleep and 4,000 battles of real-time animation would take hours. The flag defaults to on, so normal play is unaffected; the harness flips it off. I wrote the full design into CLAUDE.md before building it.
The first run came back completely clean — 0 exceptions, 0 timeouts, all in about 300ms — and the results matrix matched expectations (Dragon dominates, Goblin and Zombie struggle), which is a good sign the combat, ability, shield, and map-object systems all hold up under every pairing.
Smaller touches:
Added a credits line under the title screen, updated the README with the quit option, the new file, and a testing section.
The biggest change this session was a major refactor of how the code is organized across files. Fight.java was getting bloated as the game controller, so logic was redistributed to the classes that actually own it.
Board.java gained five new methods: printBoard() (the bordered grid renderer), spawnObjects(), checkObjectInteraction(), restoreHouseIfVacating(), and ejectFromHouseIfExpired(). All of the map object logic now lives alongside the board data it operates on, rather than sitting in the game controller as static helpers.
Opponent.java absorbed moveOpponentToward() and opponentAI() as instance methods. An opponent now knows how to move and take its turn — Fight.java just calls opponent.opponentAI(…) instead of running all that logic externally.
Fight.java is now significantly leaner, focused only on game setup, the turn loop, player input, and UI rendering.
On the bug fix side, the shield raise failure messages (“Something is in the way”) were moved out of raiseShield() and into the player-only call site. Previously these messages would print whenever the opponent AI tried and failed to raise its shield, which confused players who weren’t doing anything with their shield.
The board display was also reworked to use ANSI cursor column positioning (\033[nG) to force each cell to a fixed terminal column, solving a long-standing alignment issue where emoji with different display widths would push cells out of place.
The instructions screen was rewritten — cleaner language, shorter sentences, and a new map objects section explaining how the house, hospital, and heart work. The “(I) How to play” hint was moved to sit next to the “Choose your character” header so it’s visible before scrolling through the roster.
The README was also reviewed and is current.