AlgoMaster Logo
AlgoMasterDesign Terrain Mapeasy

Design Terrain Map

easy

A tile-based game map can hold thousands of cells, while the terrains they show number only a handful. A terrain's name, movement cost and map symbol repeat on every cell of that kind, so they are shared. Only the coordinates belong to each cell.

Cell and GameMap are provided in the starter code. Implement only the flyweight side: the Terrain contract, ConcreteTerrain, and TerrainFactory (ITerrain in C#).

  • Terrain exposes render(x, y), which returns "[grass, cost 1] '.' at (x,y)", and cost().
  • ConcreteTerrain(name, cost, symbol) stores those three values and nothing else.
  • TerrainFactory exposes get(name, cost, symbol), which returns the one shared terrain for those values and creates it on first request, idOf(terrain), which numbers terrains from 1 in creation order, and count().

The provided Cell(terrain, x, y) calls terrain.render(x, y) and terrain.cost(). The provided GameMap exposes this API:

  • GameMap() creates a map with no terrains and no cells.
  • String paint(String name, int cost, String symbol, int x, int y) obtains the terrain from the factory, adds a cell and returns its rendering.
  • int terrainId(String name, int cost, String symbol) returns the number of the shared terrain for those values, creating it when absent.
  • int terrainCount() returns how many distinct terrains exist and int cellCount() how many cells were painted.
  • String rendered(int index) re-renders the cell at that zero-based paint index, or returns "NONE" when the index is invalid.
  • int totalCost() adds up the terrain cost of every cell.

The tests call the provided GameMap; your work should be confined to the contract, the concrete terrain, and the factory.

Example 1:

Input:

Output:

Explanation: Three cells use two terrains. The two grass cells share one object, and the total cost adds each cell's terrain cost.

Example 2:

Input:

Output:

Explanation: Asking for grass again returns the object numbered 1. Painting water reuses the object created by the earlier id lookup, so the count stays at two.

Constraints

  • 1 <= name.length <= 10 and symbol is one character.
  • 1 <= cost <= 10 and 0 <= x, y <= 99
  • At most 100 calls in total are made across all methods.

Starter Code

Implement Terrain, ConcreteTerrain and TerrainFactory. Cell and GameMap are complete and must not be modified.

How the design is graded

needs 7/10 to pass
  • Intrinsic state lives on the flyweight

    Full marks when `ConcreteTerrain` stores only the name, cost and symbol and its `render` takes the coordinates as arguments. Lose points heavily when a terrain stores a position or the cell stores a copy of the terrain's fields.

  • The factory shares by value

    Full marks when `TerrainFactory.get` returns the identical object for equal name, cost and symbol, so `terrainId` is stable and `terrainCount` counts distinct combinations. Lose points when equal requests create separate objects or the key ignores one of the three values.

  • Numbering follows creation

    Full marks when `idOf` reports the creation order from `1` and `count` matches. Lose points for printing to stdout.

Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.

Hints

Loading...
CallReturns
new GameMap()null
paint("grass", 1, ".", 0, 0)"[grass, cost 1] '.' at (0,0)"
paint("grass", 1, ".", 1, 0)"[grass, cost 1] '.' at (1,0)"
paint("water", 3, "~", 2, 0)"[water, cost 3] '~' at (2,0)"
terrainCount()2
cellCount()3
totalCost()5

Three cells use two terrains. The two grass cells share one object, and the total cost adds each cell's terrain cost.

Run checks these cases. Submit also runs a larger hidden set.