Skip to content

Commit acea680

Browse files
committed
The 3 Greek Fates gang up and enter into the Ruby MMO
1 parent 372fdd2 commit acea680

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed

players/gang_of_three.rb

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
class GangOfThree
2+
attr_accessor :current_victim
3+
attr_reader :last_victim
4+
5+
def initialize
6+
@members = []
7+
@names = %w(Clotho Lachesis Atropos)
8+
reset
9+
end
10+
11+
def form_up
12+
3.times {create_member @names.shift} unless @members.any?
13+
end
14+
15+
def kill?(player)
16+
defense = player.stats[:defense] / 2
17+
total_damage = members.inject(0) do |sum, member|
18+
sum + member.strength - defense
19+
end
20+
total_damage > player.stats[:health]
21+
end
22+
23+
def max_health(player)
24+
Player::HEALTH_INDEX[player.stats[:level]]
25+
end
26+
27+
def members
28+
@members.select {|m| m.alive?}
29+
end
30+
31+
def monsters
32+
@monsters ||= begin
33+
all_players.select {|p| p.to_s == 'rat'}
34+
end
35+
end
36+
37+
def move_taken(member)
38+
@moves << member
39+
reset if @moves.size == members.size
40+
end
41+
42+
def proxies
43+
@proxies ||= members.map {|m| m.proxy}
44+
end
45+
46+
def victims
47+
@victims ||= begin
48+
players = all_players.reject {|p| p.to_s == 'rat'}
49+
players.sort_by {|p| [1/max_health(p), p.stats[:health]]}
50+
end
51+
end
52+
53+
protected
54+
def all_players
55+
Game.world[:players].reject {|p| proxies.include? p}
56+
end
57+
58+
def create_member(name)
59+
@members << Member.new(name, self).tap do |m|
60+
m.prepare
61+
end
62+
end
63+
64+
def reset
65+
@moves = []
66+
@last_victim = @current_victim
67+
@last_victim = nil if @last_victim && !@last_victim.alive?
68+
@current_victim = nil
69+
@victims = nil
70+
@monsters = nil
71+
end
72+
73+
class Member
74+
attr_reader :name, :gang, :module
75+
attr_accessor :proxy
76+
77+
def initialize(name, gang)
78+
@name = name
79+
@gang = gang
80+
end
81+
82+
%w(health strength experience).each do |m|
83+
define_method m do
84+
proxy.stats[m.to_sym]
85+
end
86+
end
87+
88+
%w(alive? stats).each do |m|
89+
define_method m do
90+
proxy.send m
91+
end
92+
end
93+
94+
def move
95+
return rest if winning? || vulnerable?
96+
97+
victim = next_victim
98+
if victim
99+
attack victim
100+
else
101+
health == max_health ? attack(random_victim) : [:rest]
102+
end
103+
ensure
104+
gang.move_taken self
105+
end
106+
107+
def prepare
108+
create_module
109+
end
110+
111+
protected
112+
def attack(victim)
113+
[:attack, victim]
114+
end
115+
116+
def vulnerable?
117+
!gang.victims.detect {|v| kill? self, v}.nil?
118+
end
119+
120+
def kill?(victim, attacker = self)
121+
total_damage = attacker.stats[:strength] - victim.stats[:defense] / 2
122+
total_damage > victim.stats[:health]
123+
end
124+
125+
def max_health(p = proxy)
126+
gang.max_health p
127+
end
128+
129+
def next_victim
130+
current = gang.current_victim
131+
return current if current
132+
133+
last_victim = gang.last_victim
134+
return gang.current_victim = last_victim if last_victim && last_victim.alive?
135+
136+
easy_victim = gang.victims.detect {|v| gang.kill? v}
137+
return gang.current_victim = easy_victim if easy_victim
138+
139+
easy_victim = gang.victims.detect {|v| kill? v}
140+
return easy_victim if easy_victim
141+
142+
monster = random_monster
143+
return monster if monster
144+
145+
gang.current_victim = random_victim
146+
end
147+
148+
def random_monster
149+
gang.monsters.sample
150+
end
151+
152+
def random_victim
153+
gang.victims.sample
154+
end
155+
156+
def rest
157+
[:rest]
158+
end
159+
160+
def winning?
161+
return false if experience < 50
162+
return false if gang.victims.size < 10
163+
top_three = (gang.victims + [self]).sort_by {|v| v.stats[:experience]}[-3..-1]
164+
top_three && top_three.include?(self)
165+
end
166+
167+
private
168+
def create_module
169+
@module = Module.new do
170+
def move
171+
member.move
172+
end
173+
174+
def to_s
175+
member.name
176+
end
177+
end
178+
179+
Object.const_set name, @module
180+
class << @module
181+
attr_accessor :member, :name
182+
183+
def extended(player_proxy)
184+
class << player_proxy
185+
attr_accessor :member
186+
end
187+
player_proxy.member = member
188+
member.proxy = player_proxy
189+
end
190+
end
191+
@module.member = self
192+
@module.name = name
193+
end
194+
end
195+
end
196+
197+
GangOfThree.new.form_up

0 commit comments

Comments
 (0)