TLDR
Adding logic for identifying where cities can be placed. Adding logic for collecting extra resources if a Settlement is a city. Updating the Settlement model to have an isCity() getter. Updating resource collecting logic to ignore collection if a Hexagon is blocked by the Robber. Updating ResourceBundle with utility functions to facilitate this all.
See “Learnings” note below about Collector interface.
// TODO can some kind of Collector be implemented to form the final ResourceBundle?
// collect resources from all adjacent hexagons
ResourceBundle resourceBundle = new ResourceBundle();
this.graph
.get(settlementNode.get())
.stream()
.filter(graphNode -> graphNode.graphNodeIndex().graphNodeType() == GraphIndexType.HEXAGON)
.filter(hexagonGraphNode -> hexagonGraphNode.graphNodeIndex().index() != knightIndex)
.map(hexagonGraphNode -> (Hexagon) hexagonGraphNode.graphNodePiece())
.map(Hexagon::getResourceColor)
.filter(resourceColor -> resourceColor != ResourceColor.DESERT)
.forEach(resourceColor -> {
if(isCity) {
resourceBundle.addToSpecificResource(resourceColor, 2);
} else {
resourceBundle.increment(resourceColor);
}
});
return resourceBundle;
Red player’s settlements correctly being identified as places a city could be built.

Main work
- Implementing the
getAvailableCityIndices(int userId)method in theCatanGraphService. - Adding
isCityboolean field to theSettlementmodel. - Updating resource collection logic to collect extra resources for cities.
- Updating the
ResourceBundlemodel with utility methods to support resource collection.- In particular, the
addToSpecificResource(...)utility method.
- In particular, the
- Cleaning up misc things near places in the code that were broken by data model updates / new function signatures.
Challenges
- There’s now a good amount of changes to make in multiple places if I revise a data model or how a method should work (method signature).
- This isn’t too bad, since I chose a statically typed language and am mostly told by the compiler where I’m breaking things.
- I noticed that I have some redundant logic for collecting resources in both
collectSettlementResourcesandcollectResourcesFromRoll.- This could be abstracted / consolidate into a service in the future. At the moment though, repeating myself once isn’t too bad.
Learnings
- During eventual cleanup, could explore implementing a
Collectorto help keep things functional.- The code snippet above shows a case where I create a mutable container then assign values to the container from a functional
forEach. - The code could be updated to use
mapinstead offorEach, then the code could accumulate the results into the finalResourceBundlecontainer. - Java’s
Collectorinterface only has four or five methods to implement. - Would still likely be overkill for just this single use case.
- Benefit is that the method is no longer maintaining any state (the mutable container) itself.
- Not relevant to this project, but making things functional would typically facilitates massive scaling, e.g., the map-reduce pattern for distributed systems.
- The code snippet above shows a case where I create a mutable container then assign values to the container from a functional