TL:DR design pattern for objects that temporarily modify each other in a game scenario. Functionality is added and then removed dynamically.
As a database developer delving into front-end development, I am exploring new techniques to stay informed about various layers of the technology stack. While I am not well-versed in object-oriented programming, I possess a basic understanding of problem-solving with objects. However, I lack knowledge about different design patterns and their applicable scenarios. In my journey to learn AngularJS, I have chosen to replicate the board game Small World to outline my project requirements swiftly. Here is the foundation I aim to establish:
The game revolves around Powers and Races, each having unique ways of altering game rules. These Power/Race combinations are used to conquer Regions for points, with modifications activating at different phases:
- First Turn (Wealthy: gain 7 points, occurs only once)
- Start Turn (Amazons: receive 4 extra tokens)
- Enter Decline (Ghouls: Ghouls function like an active race in decline; Stout: immediately select your next race upon entering decline)
- Conquest (Commando: require 1 fewer token to conquer a region)
- Redeploy (Amazons: lose 4 tokens; Fortress: Place a fortress in an occupied region for +1 defense and +1 point)
- End Turn (Hill: gain 1 extra point on a hill region; Orcs: +1 point for each region conquered this turn)
- Multi Player/Totally Unique(Diplomat: select a player not attacked this turn, rendering them unable to attack until your next turn)
Furthermore, some regions can possess special attributes:
- Mine: dwarves receive +1 point from this region even in decline
- Magic Source: wizards gain +1 point from this region
- Underworld: races with the underworld power consider all underworld regions adjacent
- Mountain: requires 1 extra token to conquer, with +1 defense
During gameplay, race/power combos will appear and disappear, replaced by new combinations. Managing numerous attributes while races exist is essential (e.g. tracking attacked players for diplomat). While it's feasible to define attributes for known scenarios, my aim is to allow addition of new race/powers in the config file, enabling the game to comprehend and implement rule modifications. I propose a general object called a Modifier to structure my objects:
{
event:'endTurn',
modify:{
points: 1,
strength: -4,
strength: -1,
actions:[function(gameState, region, gameRace){
//conditional logic or advanced modifiers
}]
}
}
SWGame
+--+Player[]
| |
| +--+GameRace[]
| |
| +--+Race
| |
| | +---Modifier[]
| |
| +--+Power
| |
| +---Modifier[]
+--+GameMap
|
+--+Region[]
|
+---Modifier[]
The challenge I face is managing Races that modify regions (e.g. Giants: if you occupy a mountain, adjacent regions to the mountain cost 1 fewer tokens to conquer). Applying a "strength: -1" modifier to adjacent regions, and later removing the Giants' modifiers at the end of a turn before applying new player modifiers, is becoming cumbersome. The tracking of modifiers is becoming convoluted. Any suggestions for a better-suited design pattern for this scenario would be highly appreciated.