rubywarrior-i18n 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +38 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +20 -0
- data/README.md +199 -0
- data/Rakefile +17 -0
- data/bin/rubywarrior +5 -0
- data/features/command_options.feature +46 -0
- data/features/levels.feature +71 -0
- data/features/profiles.feature +56 -0
- data/features/step_definitions/common_steps.rb +19 -0
- data/features/step_definitions/interaction_steps.rb +65 -0
- data/features/support/env.rb +12 -0
- data/features/support/mockio.rb +57 -0
- data/features/towers.feature +14 -0
- data/i18n/en.yml +232 -0
- data/i18n/es.yml +233 -0
- data/lib/ruby_warrior.rb +53 -0
- data/lib/ruby_warrior/abilities/attack.rb +25 -0
- data/lib/ruby_warrior/abilities/base.rb +44 -0
- data/lib/ruby_warrior/abilities/bind.rb +20 -0
- data/lib/ruby_warrior/abilities/detonate.rb +34 -0
- data/lib/ruby_warrior/abilities/direction_of.rb +13 -0
- data/lib/ruby_warrior/abilities/direction_of_stairs.rb +13 -0
- data/lib/ruby_warrior/abilities/distance_of.rb +13 -0
- data/lib/ruby_warrior/abilities/explode.rb +28 -0
- data/lib/ruby_warrior/abilities/feel.rb +14 -0
- data/lib/ruby_warrior/abilities/form.rb +25 -0
- data/lib/ruby_warrior/abilities/health.rb +13 -0
- data/lib/ruby_warrior/abilities/listen.rb +15 -0
- data/lib/ruby_warrior/abilities/look.rb +16 -0
- data/lib/ruby_warrior/abilities/pivot.rb +17 -0
- data/lib/ruby_warrior/abilities/rescue.rb +24 -0
- data/lib/ruby_warrior/abilities/rest.rb +20 -0
- data/lib/ruby_warrior/abilities/shoot.rb +24 -0
- data/lib/ruby_warrior/abilities/walk.rb +21 -0
- data/lib/ruby_warrior/config.rb +22 -0
- data/lib/ruby_warrior/core_additions.rb +29 -0
- data/lib/ruby_warrior/floor.rb +71 -0
- data/lib/ruby_warrior/game.rb +209 -0
- data/lib/ruby_warrior/level.rb +123 -0
- data/lib/ruby_warrior/level_loader.rb +56 -0
- data/lib/ruby_warrior/player_generator.rb +41 -0
- data/lib/ruby_warrior/position.rb +82 -0
- data/lib/ruby_warrior/profile.rb +120 -0
- data/lib/ruby_warrior/runner.rb +34 -0
- data/lib/ruby_warrior/space.rb +71 -0
- data/lib/ruby_warrior/tower.rb +14 -0
- data/lib/ruby_warrior/turn.rb +38 -0
- data/lib/ruby_warrior/ui.rb +54 -0
- data/lib/ruby_warrior/units/archer.rb +34 -0
- data/lib/ruby_warrior/units/base.rb +100 -0
- data/lib/ruby_warrior/units/captive.rb +17 -0
- data/lib/ruby_warrior/units/golem.rb +20 -0
- data/lib/ruby_warrior/units/sludge.rb +30 -0
- data/lib/ruby_warrior/units/thick_sludge.rb +13 -0
- data/lib/ruby_warrior/units/warrior.rb +73 -0
- data/lib/ruby_warrior/units/wizard.rb +34 -0
- data/lib/ruby_warrior/version.rb +3 -0
- data/spec/fixtures/short-tower/level_001.rb +15 -0
- data/spec/fixtures/short-tower/level_002.rb +15 -0
- data/spec/fixtures/walking_player.rb +5 -0
- data/spec/ruby_warrior/abilities/attack_spec.rb +51 -0
- data/spec/ruby_warrior/abilities/base_spec.rb +38 -0
- data/spec/ruby_warrior/abilities/bind_spec.rb +19 -0
- data/spec/ruby_warrior/abilities/direction_of_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/direction_of_stairs_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/distance_of_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/explode_spec.rb +32 -0
- data/spec/ruby_warrior/abilities/feel_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/form_spec.rb +48 -0
- data/spec/ruby_warrior/abilities/health_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/listen_spec.rb +17 -0
- data/spec/ruby_warrior/abilities/look_spec.rb +15 -0
- data/spec/ruby_warrior/abilities/pivot_spec.rb +18 -0
- data/spec/ruby_warrior/abilities/rescue_spec.rb +40 -0
- data/spec/ruby_warrior/abilities/rest_spec.rb +29 -0
- data/spec/ruby_warrior/abilities/shoot_spec.rb +22 -0
- data/spec/ruby_warrior/abilities/throw_spec.rb +46 -0
- data/spec/ruby_warrior/abilities/walk_spec.rb +25 -0
- data/spec/ruby_warrior/core_additions_spec.rb +7 -0
- data/spec/ruby_warrior/floor_spec.rb +81 -0
- data/spec/ruby_warrior/game_spec.rb +119 -0
- data/spec/ruby_warrior/level_loader_spec.rb +54 -0
- data/spec/ruby_warrior/level_spec.rb +203 -0
- data/spec/ruby_warrior/player_generator_spec.rb +12 -0
- data/spec/ruby_warrior/position_spec.rb +108 -0
- data/spec/ruby_warrior/profile_spec.rb +171 -0
- data/spec/ruby_warrior/space_spec.rb +190 -0
- data/spec/ruby_warrior/tower_spec.rb +15 -0
- data/spec/ruby_warrior/turn_spec.rb +42 -0
- data/spec/ruby_warrior/ui_spec.rb +93 -0
- data/spec/ruby_warrior/units/archer_spec.rb +23 -0
- data/spec/ruby_warrior/units/base_spec.rb +133 -0
- data/spec/ruby_warrior/units/captive_spec.rb +23 -0
- data/spec/ruby_warrior/units/golem_spec.rb +28 -0
- data/spec/ruby_warrior/units/sludge_spec.rb +27 -0
- data/spec/ruby_warrior/units/thick_sludge_spec.rb +19 -0
- data/spec/ruby_warrior/units/warrior_spec.rb +65 -0
- data/spec/ruby_warrior/units/wizard_spec.rb +23 -0
- data/spec/spec_helper.rb +10 -0
- data/templates/README.erb +33 -0
- data/templates/player.rb +5 -0
- data/towers/beginner/level_001.rb +18 -0
- data/towers/beginner/level_002.rb +19 -0
- data/towers/beginner/level_003.rb +23 -0
- data/towers/beginner/level_004.rb +20 -0
- data/towers/beginner/level_005.rb +24 -0
- data/towers/beginner/level_006.rb +21 -0
- data/towers/beginner/level_007.rb +20 -0
- data/towers/beginner/level_008.rb +23 -0
- data/towers/beginner/level_009.rb +22 -0
- data/towers/intermediate/level_001.rb +20 -0
- data/towers/intermediate/level_002.rb +22 -0
- data/towers/intermediate/level_003.rb +25 -0
- data/towers/intermediate/level_004.rb +26 -0
- data/towers/intermediate/level_005.rb +21 -0
- data/towers/intermediate/level_006.rb +25 -0
- data/towers/intermediate/level_007.rb +27 -0
- data/towers/intermediate/level_008.rb +25 -0
- data/towers/intermediate/level_009.rb +33 -0
- metadata +226 -0
@@ -0,0 +1,123 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
class Level
|
3
|
+
attr_reader :profile, :number
|
4
|
+
attr_accessor :description, :tip, :clue, :warrior, :floor, :time_bonus, :ace_score
|
5
|
+
|
6
|
+
def self.grade_letter(percent)
|
7
|
+
if percent >= 1.0 then "S"
|
8
|
+
elsif percent >= 0.9 then "A"
|
9
|
+
elsif percent >= 0.8 then "B"
|
10
|
+
elsif percent >= 0.7 then "C"
|
11
|
+
elsif percent >= 0.6 then "D"
|
12
|
+
else "F"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(profile, number)
|
17
|
+
@profile = profile
|
18
|
+
@number = number
|
19
|
+
@time_bonus = 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def player_path
|
23
|
+
@profile.player_path
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_path
|
27
|
+
File.join(
|
28
|
+
File.expand_path('../../../towers/', __FILE__),
|
29
|
+
File.basename(@profile.tower_path) + "/level_" +
|
30
|
+
@number.to_s.rjust(3, '0') + ".rb"
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def load_level
|
35
|
+
LevelLoader.new(self).instance_eval(File.read(load_path))
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_player
|
39
|
+
$: << player_path
|
40
|
+
load 'player.rb'
|
41
|
+
end
|
42
|
+
|
43
|
+
def generate_player_files
|
44
|
+
load_level
|
45
|
+
PlayerGenerator.new(self).generate
|
46
|
+
end
|
47
|
+
|
48
|
+
def play(turns = 1000)
|
49
|
+
load_level
|
50
|
+
turns.times do |n|
|
51
|
+
return if passed? || failed?
|
52
|
+
UI.puts "- #{R18n.t.turn} #{n+1} -"
|
53
|
+
UI.print @floor.character
|
54
|
+
@floor.units.each { |unit| unit.prepare_turn }
|
55
|
+
@floor.units.each { |unit| unit.perform_turn }
|
56
|
+
yield if block_given?
|
57
|
+
@time_bonus -= 1 if @time_bonus > 0
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def tally_points
|
62
|
+
score = 0
|
63
|
+
|
64
|
+
UI.puts "#{R18n.t.level.score}: #{warrior.score}"
|
65
|
+
score += warrior.score
|
66
|
+
|
67
|
+
UI.puts "#{R18n.t.bonus.time}: #{time_bonus}"
|
68
|
+
score += @time_bonus
|
69
|
+
|
70
|
+
if floor.other_units.empty?
|
71
|
+
UI.puts "#{R18n.t.bonus.clear}: #{clear_bonus}"
|
72
|
+
score += clear_bonus
|
73
|
+
end
|
74
|
+
|
75
|
+
if @profile.epic?
|
76
|
+
UI.puts "#{R18n.t.level.grade}: #{grade_for(score)}" if grade_for(score)
|
77
|
+
UI.puts "#{R18n.t.score.total}: " + score_calculation(@profile.current_epic_score, score)
|
78
|
+
@profile.current_epic_grades[@number] = (score / ace_score.to_f) if ace_score
|
79
|
+
@profile.current_epic_score += score
|
80
|
+
else
|
81
|
+
UI.puts "#{R18n.t.score.total}: " + score_calculation(@profile.score, score)
|
82
|
+
@profile.score += score
|
83
|
+
@profile.abilities = warrior.abilities.keys
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def grade_for(score)
|
88
|
+
if ace_score
|
89
|
+
self.class.grade_letter(score / ace_score.to_f)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def clear_bonus
|
94
|
+
((warrior.score + time_bonus)*0.2).round
|
95
|
+
end
|
96
|
+
|
97
|
+
def score_calculation(current_score, addition)
|
98
|
+
if current_score.zero?
|
99
|
+
addition.to_s
|
100
|
+
else
|
101
|
+
"#{current_score} + #{addition} = #{current_score + addition}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def passed?
|
106
|
+
@floor.stairs_space.warrior?
|
107
|
+
end
|
108
|
+
|
109
|
+
def failed?
|
110
|
+
!@floor.units.include?(warrior)
|
111
|
+
end
|
112
|
+
|
113
|
+
def exists?
|
114
|
+
File.exist? load_path
|
115
|
+
end
|
116
|
+
|
117
|
+
def setup_warrior(warrior)
|
118
|
+
@warrior = warrior
|
119
|
+
@warrior.add_abilities(*profile.abilities)
|
120
|
+
@warrior.name = profile.warrior_name
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
class LevelLoader
|
3
|
+
def initialize(level)
|
4
|
+
@floor = RubyWarrior::Floor.new
|
5
|
+
@level = level
|
6
|
+
@level.floor = @floor
|
7
|
+
end
|
8
|
+
|
9
|
+
def description(desc)
|
10
|
+
@level.description = desc
|
11
|
+
end
|
12
|
+
|
13
|
+
def tip(tip)
|
14
|
+
@level.tip = tip
|
15
|
+
end
|
16
|
+
|
17
|
+
def clue(clue)
|
18
|
+
@level.clue = clue
|
19
|
+
end
|
20
|
+
|
21
|
+
def time_bonus(bonus)
|
22
|
+
@level.time_bonus = bonus
|
23
|
+
end
|
24
|
+
|
25
|
+
def ace_score(score)
|
26
|
+
@level.ace_score = score
|
27
|
+
end
|
28
|
+
|
29
|
+
def size(width, height)
|
30
|
+
@floor.width = width
|
31
|
+
@floor.height = height
|
32
|
+
end
|
33
|
+
|
34
|
+
def stairs(x, y)
|
35
|
+
@floor.place_stairs(x, y)
|
36
|
+
end
|
37
|
+
|
38
|
+
def unit(unit, x, y, facing = :north)
|
39
|
+
unit = unit_to_constant(unit).new unless unit.kind_of? Units::Base
|
40
|
+
@floor.add(unit, x, y, facing)
|
41
|
+
yield unit if block_given?
|
42
|
+
unit
|
43
|
+
end
|
44
|
+
|
45
|
+
def warrior(*args, &block)
|
46
|
+
@level.setup_warrior unit(Units::Warrior.new, *args, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def unit_to_constant(name)
|
52
|
+
camel = name.to_s.split('_').map { |s| s.capitalize }.join
|
53
|
+
eval("Units::#{camel}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module RubyWarrior
|
6
|
+
class PlayerGenerator
|
7
|
+
def initialize(level)
|
8
|
+
@level = level
|
9
|
+
end
|
10
|
+
|
11
|
+
def level
|
12
|
+
@level
|
13
|
+
end
|
14
|
+
|
15
|
+
def previous_level
|
16
|
+
@previous_level ||= Level.new(level.profile, level.number-1)
|
17
|
+
end
|
18
|
+
|
19
|
+
# TODO refactor and test this method
|
20
|
+
def generate
|
21
|
+
if level.number == 1
|
22
|
+
FileUtils.mkdir_p(level.player_path) unless File.exists? level.player_path
|
23
|
+
FileUtils.cp(templates_path + '/player.rb', level.player_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
File.open(level.player_path + '/README', 'w') do |f|
|
27
|
+
f.write read_template(templates_path + '/README.erb')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def templates_path
|
32
|
+
File.expand_path("../../../templates", __FILE__)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def read_template(path)
|
38
|
+
ERB.new(File.read(path), nil, '-').result(binding)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
class Position
|
3
|
+
attr_reader :floor
|
4
|
+
DIRECTIONS = [:north, :east, :south, :west]
|
5
|
+
RELATIVE_DIRECTIONS = [:forward, :right, :backward, :left]
|
6
|
+
|
7
|
+
def initialize(floor, x, y, direction = nil)
|
8
|
+
@floor = floor
|
9
|
+
@x = x
|
10
|
+
@y = y
|
11
|
+
@direction_index = DIRECTIONS.index(direction || :north)
|
12
|
+
end
|
13
|
+
|
14
|
+
def at?(x, y)
|
15
|
+
@x == x && @y == y
|
16
|
+
end
|
17
|
+
|
18
|
+
def direction
|
19
|
+
DIRECTIONS[@direction_index]
|
20
|
+
end
|
21
|
+
|
22
|
+
def rotate(amount)
|
23
|
+
@direction_index += amount
|
24
|
+
@direction_index -= 4 while @direction_index > 3
|
25
|
+
@direction_index += 4 while @direction_index < 0
|
26
|
+
end
|
27
|
+
|
28
|
+
def relative_space(forward, right = 0)
|
29
|
+
@floor.space(*translate_offset(forward, right))
|
30
|
+
end
|
31
|
+
|
32
|
+
def space
|
33
|
+
@floor.space(@x, @y)
|
34
|
+
end
|
35
|
+
|
36
|
+
def move(forward, right = 0)
|
37
|
+
@x, @y = *translate_offset(forward, right)
|
38
|
+
end
|
39
|
+
|
40
|
+
def distance_from_stairs
|
41
|
+
distance_of(@floor.stairs_space)
|
42
|
+
end
|
43
|
+
|
44
|
+
def distance_of(space)
|
45
|
+
x, y = *space.location
|
46
|
+
(@x - x).abs + (@y - y).abs
|
47
|
+
end
|
48
|
+
|
49
|
+
def relative_direction_of_stairs
|
50
|
+
relative_direction_of(@floor.stairs_space)
|
51
|
+
end
|
52
|
+
|
53
|
+
def relative_direction_of(space)
|
54
|
+
relative_direction(direction_of(space))
|
55
|
+
end
|
56
|
+
|
57
|
+
def direction_of(space)
|
58
|
+
space_x, space_y = *space.location
|
59
|
+
if (@x - space_x).abs > (@y - space_y).abs
|
60
|
+
space_x > @x ? :east : :west
|
61
|
+
else
|
62
|
+
space_y > @y ? :south : :north
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def relative_direction(direction)
|
67
|
+
offset = DIRECTIONS.index(direction) - @direction_index
|
68
|
+
offset -= 4 while offset > 3
|
69
|
+
offset += 4 while offset < 0
|
70
|
+
RELATIVE_DIRECTIONS[offset]
|
71
|
+
end
|
72
|
+
|
73
|
+
def translate_offset(forward, right)
|
74
|
+
case direction
|
75
|
+
when :north then [@x + right, @y - forward]
|
76
|
+
when :east then [@x + forward, @y + right]
|
77
|
+
when :south then [@x - right, @y + forward]
|
78
|
+
when :west then [@x - forward, @y - right]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module RubyWarrior
|
4
|
+
class Profile
|
5
|
+
attr_accessor :score, :epic_score, :current_epic_score, :average_grade, :current_epic_grades, :abilities, :level_number, :last_level_number, :tower_path, :warrior_name, :player_path
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@tower_path = nil
|
9
|
+
@warrior_name = nil
|
10
|
+
@score = 0
|
11
|
+
@current_epic_score = 0
|
12
|
+
@current_epic_grades = {}
|
13
|
+
@epic_score = 0
|
14
|
+
@average_grade = nil
|
15
|
+
@abilities = []
|
16
|
+
@level_number = 0
|
17
|
+
@last_level_number = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def encode
|
21
|
+
Base64.encode64(Marshal.dump(self))
|
22
|
+
end
|
23
|
+
|
24
|
+
def save
|
25
|
+
update_epic_score
|
26
|
+
@level_number = 0 if epic?
|
27
|
+
File.open(player_path + '/.profile', 'w') { |f| f.write(encode) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.decode(str)
|
31
|
+
Marshal.load(Base64.decode64(str))
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.load(path)
|
35
|
+
player = decode(File.read(path))
|
36
|
+
player.player_path = File.dirname(path)
|
37
|
+
player
|
38
|
+
end
|
39
|
+
|
40
|
+
def player_path
|
41
|
+
@player_path || Config.path_prefix + "/rubywarrior/#{directory_name}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def directory_name
|
45
|
+
[warrior_name.downcase.gsub(/[^a-z0-9]+/, '-'), tower.name].join('-')
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
if epic?
|
50
|
+
[warrior_name, tower.name, "#{R18n.t.score.first} #{score}", "#{R18n.t.score.epic} #{epic_score_with_grade}"].join(' - ')
|
51
|
+
else
|
52
|
+
[warrior_name, tower.name, "#{R18n.t.level.level} #{level_number}", "#{R18n.t.score.score} #{score}"].join(' - ')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def epic_score_with_grade
|
57
|
+
if average_grade
|
58
|
+
"#{epic_score} (#{Level.grade_letter(average_grade)})"
|
59
|
+
else
|
60
|
+
epic_score
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def tower
|
65
|
+
Tower.new(File.basename @tower_path)
|
66
|
+
end
|
67
|
+
|
68
|
+
def current_level
|
69
|
+
Level.new(self, level_number)
|
70
|
+
end
|
71
|
+
|
72
|
+
def next_level
|
73
|
+
Level.new(self, level_number+1)
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_abilities(*abilities)
|
77
|
+
@abilities += abilities
|
78
|
+
@abilities.uniq!
|
79
|
+
end
|
80
|
+
|
81
|
+
def enable_epic_mode
|
82
|
+
@epic = true
|
83
|
+
@epic_score ||= 0
|
84
|
+
@current_epic_score ||= 0
|
85
|
+
@last_level_number ||= @level_number
|
86
|
+
end
|
87
|
+
|
88
|
+
def enable_normal_mode
|
89
|
+
@epic = false
|
90
|
+
@epic_score = 0
|
91
|
+
@current_epic_score = 0
|
92
|
+
@current_epic_grades = {}
|
93
|
+
@average_grade = nil
|
94
|
+
@level_number = @last_level_number
|
95
|
+
@last_level_number = nil
|
96
|
+
end
|
97
|
+
|
98
|
+
def epic?
|
99
|
+
@epic
|
100
|
+
end
|
101
|
+
|
102
|
+
def level_after_epic?
|
103
|
+
Level.new(self, last_level_number+1).exists? if last_level_number
|
104
|
+
end
|
105
|
+
|
106
|
+
def update_epic_score
|
107
|
+
if @current_epic_score > @epic_score
|
108
|
+
@epic_score = @current_epic_score
|
109
|
+
@average_grade = calculate_average_grade
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def calculate_average_grade
|
114
|
+
if @current_epic_grades.size > 0
|
115
|
+
sum = @current_epic_grades.values.inject(0) { |sum, value| sum + value }
|
116
|
+
sum / @current_epic_grades.size
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module RubyWarrior
|
4
|
+
class Runner
|
5
|
+
def initialize(arguments, stdin, stdout)
|
6
|
+
@arguments = arguments
|
7
|
+
@stdin = stdin
|
8
|
+
@stdout = stdout
|
9
|
+
@game = RubyWarrior::Game.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
Config.in_stream = @stdin
|
14
|
+
Config.out_stream = @stdout
|
15
|
+
Config.delay = 0.6
|
16
|
+
parse_options
|
17
|
+
@game.start
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def parse_options
|
23
|
+
t = R18n.t.runner.options
|
24
|
+
options = OptionParser.new
|
25
|
+
options.banner = t.banner
|
26
|
+
options.on('-d', '--directory DIR', t.directory) { |dir| Config.path_prefix = dir }
|
27
|
+
options.on('-l', '--level LEVEL', t.level) { |level| Config.practice_level = level.to_i }
|
28
|
+
options.on('-s', '--skip', t.skip) { Config.skip_input = true }
|
29
|
+
options.on('-t', '--time SECONDS', t.time) { |seconds| Config.delay = seconds.to_f }
|
30
|
+
options.on('-h', '--help', t.help) { puts(options); exit }
|
31
|
+
options.parse!(@arguments)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|