@startuml skinparam linetype ortho skinparam monochrome reverse skinparam backgroundColor #FFFFFF class Main{ static void main(String[]) } package viewer { class Viewer { final Game Viewer(List) void eventLoop(ApplicationContext) } } package context { interface Updateable { List update(Context) static List updateAll(List, Context) } class Context { Context(Game, List, GraphicsContext) Game getGame() List getEvents() GraphicsContext getGraphicsContext() Duration getTimeDelta() } class GraphicsContext { Graphics2D, ScreenInfo paintCircle(Color, Vec2, float) paintSquare(Color, Vec2, float, float) paintString(Color, Vec2,String) } class InputHandler { ApplicationContext InputHandler(ApplicationContext) List getEvents() } class ScreenManager { ApplicationContext, Graphics2D ScreenManager(ApplicationContext,Graphics2D) GraphicsContext clearScreen() } class Game implements Updateable { Stage final List int indexBoard final List bool over Game(List) Stage getStage() bool isOver() void setOver() void nextStage() void retryStage() List update(Context context) } class Stage implements Updateable { Stage(Board) Board getBoard() List getBlocks() List update(Context) bool isCleared() } } package event { interface Event interface GameEvent implements Event interface InputEvent implements Event class ConfirmOrder implements InputEvent class BombSetupOrder implements InputEvent class MoveRobotOrder implements InputEvent { MoveRobotEvent(TileVec2) TileVec2 getTarget() } class BombSetupEvent implements GameEvent { final TileVec2 AddBombEvent(TileVec2) TileVec2 getTile() } class GameOverEvent implements GameEvent class ExplosionEvent implements GameEvent { Block source Body source } } package board { class Board { Board(width, height) BlockType getBlockTypeAt(TileVec2) BlockType setBlockTypeAt(TileVec2, BlockType) Stream> stream() } class BoardParser { static Board parse(File) } class BoardValidator { static class Constraint BoardValidator(Board) BoardValidator validate(Predicate, String error) Board get() } class BoardConverter { static Board worldToBoard(List) static List boardToWorld(Board) } class TileVec2 { static final int TILE_DIM static TileVec2 fromVec2(Vec2) TileVec2(col, row) Vec2 toPixelPos() List neighbors() } class Matrix { static int getWidth(...) static int getHeight(...) static boolean isShapeValid(...) } class PathFinder { PathFinder(Board) List findPath(TileVec2 origin, TileVec2 target) } } package block { enum BlockType { FREE, WALL, TRASH, GARBAGE, ROBOT, BOMB boolean isBounding() boolean mustBeReachable() boolean isTraversable() boolean isMovableByExplosion() } class BlockFactory { Block build(BlockType, TileVec2) } abstract class Block implements Updateable { Block(BlockType) BlockType getType() TileVec2 getTile() abstract Vec2 getPos() abstract void link(World) } abstract class JBoxBlock extends Block { JBoxBlock(BlockType, BodyType, Shape, Vec2) Vec2 getPos() void link(World) } class RobotBlock extends Block { Vec2 getPos() void link(World world) List update(Context context) } class WallBlock extends JBoxBlock { List update(Context context) } class TrashBlock extends JBoxBlock { List update(Context context) } class BombBlock extends JBoxBlock { List update(Context context) } class GarbageBlock extends JBoxBlock { List update(Context context) } } package controller { interface Controller extends Updateable class GameStateController implements Controller } Zen5 ()-- Viewer Zen5 ()-- Main Main --> viewer viewer --> context viewer --> block context --> event block --> controller board --> block @enduml