-
Notifications
You must be signed in to change notification settings - Fork 0
/
dwelling.rb
82 lines (71 loc) · 2.94 KB
/
dwelling.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
require_relative "./build_dwelling/rule_only_not_built"
require_relative "./build_dwelling/event_dwelling_built"
require_relative "./change_available_creatures/event_available_creatures_changed"
require_relative "./change_available_creatures/rule_only_built"
require_relative "./recruit_creature/event_creature_recruited"
module Heroes
module CreatureRecruitment
module Dwelling
NotBuilt = Data.define
Built = Data.define(:dwelling_id, :creature_id, :cost_per_troop, :available_creatures)
class << self
def decide(command, state)
case command
when BuildDwelling
build(command, state)
when IncreaseAvailableCreatures
increase_available_creatures(command, state)
when RecruitCreature
recruit(command, state)
else
raise "Unknown command"
end
end
def evolve(state, event)
case event
when DwellingBuilt
Built.new(dwelling_id: event.dwelling_id,
creature_id: event.creature_id,
cost_per_troop: event.cost_per_troop,
available_creatures: 0)
when AvailableCreaturesChanged
state.with(available_creatures: event.changed_to)
when CreatureRecruited
state.with(available_creatures: state.available_creatures - event.recruited)
else
raise "Unknown event"
end
end
def initial_state
NotBuilt.new
end
private
def build(command, state)
raise ::Heroes::CreatureRecruitment::OnlyNotBuiltBuildingCanBeBuild unless state.is_a?(NotBuilt)
[
DwellingBuilt.new(dwelling_id: command.dwelling_id,
creature_id: command.creature_id,
cost_per_troop: command.cost_per_troop)
]
end
def increase_available_creatures(command, state)
raise ::Heroes::CreatureRecruitment::OnlyBuiltDwellingCanHaveAvailableCreatures if state.is_a?(NotBuilt)
[
AvailableCreaturesChanged.new(dwelling_id: command.dwelling_id,
creature_id: command.creature_id,
changed_to: state.available_creatures + command.increase_by)
]
end
def recruit(command, state)
raise ::Heroes::CreatureRecruitment::RecruitCreaturesNotExceedAvailableCreatures if state.is_a?(NotBuilt) || command.creature_id != state.creature_id || (command.recruit > state.available_creatures)
[
CreatureRecruited.new(dwelling_id: command.dwelling_id,
creature_id: command.creature_id,
recruited: command.recruit,
total_cost: state.cost_per_troop * command.recruit)
]
end
end
end
end
end