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.
Files changed (122) hide show
  1. data/CHANGELOG.rdoc +38 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +44 -0
  4. data/LICENSE +20 -0
  5. data/README.md +199 -0
  6. data/Rakefile +17 -0
  7. data/bin/rubywarrior +5 -0
  8. data/features/command_options.feature +46 -0
  9. data/features/levels.feature +71 -0
  10. data/features/profiles.feature +56 -0
  11. data/features/step_definitions/common_steps.rb +19 -0
  12. data/features/step_definitions/interaction_steps.rb +65 -0
  13. data/features/support/env.rb +12 -0
  14. data/features/support/mockio.rb +57 -0
  15. data/features/towers.feature +14 -0
  16. data/i18n/en.yml +232 -0
  17. data/i18n/es.yml +233 -0
  18. data/lib/ruby_warrior.rb +53 -0
  19. data/lib/ruby_warrior/abilities/attack.rb +25 -0
  20. data/lib/ruby_warrior/abilities/base.rb +44 -0
  21. data/lib/ruby_warrior/abilities/bind.rb +20 -0
  22. data/lib/ruby_warrior/abilities/detonate.rb +34 -0
  23. data/lib/ruby_warrior/abilities/direction_of.rb +13 -0
  24. data/lib/ruby_warrior/abilities/direction_of_stairs.rb +13 -0
  25. data/lib/ruby_warrior/abilities/distance_of.rb +13 -0
  26. data/lib/ruby_warrior/abilities/explode.rb +28 -0
  27. data/lib/ruby_warrior/abilities/feel.rb +14 -0
  28. data/lib/ruby_warrior/abilities/form.rb +25 -0
  29. data/lib/ruby_warrior/abilities/health.rb +13 -0
  30. data/lib/ruby_warrior/abilities/listen.rb +15 -0
  31. data/lib/ruby_warrior/abilities/look.rb +16 -0
  32. data/lib/ruby_warrior/abilities/pivot.rb +17 -0
  33. data/lib/ruby_warrior/abilities/rescue.rb +24 -0
  34. data/lib/ruby_warrior/abilities/rest.rb +20 -0
  35. data/lib/ruby_warrior/abilities/shoot.rb +24 -0
  36. data/lib/ruby_warrior/abilities/walk.rb +21 -0
  37. data/lib/ruby_warrior/config.rb +22 -0
  38. data/lib/ruby_warrior/core_additions.rb +29 -0
  39. data/lib/ruby_warrior/floor.rb +71 -0
  40. data/lib/ruby_warrior/game.rb +209 -0
  41. data/lib/ruby_warrior/level.rb +123 -0
  42. data/lib/ruby_warrior/level_loader.rb +56 -0
  43. data/lib/ruby_warrior/player_generator.rb +41 -0
  44. data/lib/ruby_warrior/position.rb +82 -0
  45. data/lib/ruby_warrior/profile.rb +120 -0
  46. data/lib/ruby_warrior/runner.rb +34 -0
  47. data/lib/ruby_warrior/space.rb +71 -0
  48. data/lib/ruby_warrior/tower.rb +14 -0
  49. data/lib/ruby_warrior/turn.rb +38 -0
  50. data/lib/ruby_warrior/ui.rb +54 -0
  51. data/lib/ruby_warrior/units/archer.rb +34 -0
  52. data/lib/ruby_warrior/units/base.rb +100 -0
  53. data/lib/ruby_warrior/units/captive.rb +17 -0
  54. data/lib/ruby_warrior/units/golem.rb +20 -0
  55. data/lib/ruby_warrior/units/sludge.rb +30 -0
  56. data/lib/ruby_warrior/units/thick_sludge.rb +13 -0
  57. data/lib/ruby_warrior/units/warrior.rb +73 -0
  58. data/lib/ruby_warrior/units/wizard.rb +34 -0
  59. data/lib/ruby_warrior/version.rb +3 -0
  60. data/spec/fixtures/short-tower/level_001.rb +15 -0
  61. data/spec/fixtures/short-tower/level_002.rb +15 -0
  62. data/spec/fixtures/walking_player.rb +5 -0
  63. data/spec/ruby_warrior/abilities/attack_spec.rb +51 -0
  64. data/spec/ruby_warrior/abilities/base_spec.rb +38 -0
  65. data/spec/ruby_warrior/abilities/bind_spec.rb +19 -0
  66. data/spec/ruby_warrior/abilities/direction_of_spec.rb +13 -0
  67. data/spec/ruby_warrior/abilities/direction_of_stairs_spec.rb +13 -0
  68. data/spec/ruby_warrior/abilities/distance_of_spec.rb +13 -0
  69. data/spec/ruby_warrior/abilities/explode_spec.rb +32 -0
  70. data/spec/ruby_warrior/abilities/feel_spec.rb +13 -0
  71. data/spec/ruby_warrior/abilities/form_spec.rb +48 -0
  72. data/spec/ruby_warrior/abilities/health_spec.rb +13 -0
  73. data/spec/ruby_warrior/abilities/listen_spec.rb +17 -0
  74. data/spec/ruby_warrior/abilities/look_spec.rb +15 -0
  75. data/spec/ruby_warrior/abilities/pivot_spec.rb +18 -0
  76. data/spec/ruby_warrior/abilities/rescue_spec.rb +40 -0
  77. data/spec/ruby_warrior/abilities/rest_spec.rb +29 -0
  78. data/spec/ruby_warrior/abilities/shoot_spec.rb +22 -0
  79. data/spec/ruby_warrior/abilities/throw_spec.rb +46 -0
  80. data/spec/ruby_warrior/abilities/walk_spec.rb +25 -0
  81. data/spec/ruby_warrior/core_additions_spec.rb +7 -0
  82. data/spec/ruby_warrior/floor_spec.rb +81 -0
  83. data/spec/ruby_warrior/game_spec.rb +119 -0
  84. data/spec/ruby_warrior/level_loader_spec.rb +54 -0
  85. data/spec/ruby_warrior/level_spec.rb +203 -0
  86. data/spec/ruby_warrior/player_generator_spec.rb +12 -0
  87. data/spec/ruby_warrior/position_spec.rb +108 -0
  88. data/spec/ruby_warrior/profile_spec.rb +171 -0
  89. data/spec/ruby_warrior/space_spec.rb +190 -0
  90. data/spec/ruby_warrior/tower_spec.rb +15 -0
  91. data/spec/ruby_warrior/turn_spec.rb +42 -0
  92. data/spec/ruby_warrior/ui_spec.rb +93 -0
  93. data/spec/ruby_warrior/units/archer_spec.rb +23 -0
  94. data/spec/ruby_warrior/units/base_spec.rb +133 -0
  95. data/spec/ruby_warrior/units/captive_spec.rb +23 -0
  96. data/spec/ruby_warrior/units/golem_spec.rb +28 -0
  97. data/spec/ruby_warrior/units/sludge_spec.rb +27 -0
  98. data/spec/ruby_warrior/units/thick_sludge_spec.rb +19 -0
  99. data/spec/ruby_warrior/units/warrior_spec.rb +65 -0
  100. data/spec/ruby_warrior/units/wizard_spec.rb +23 -0
  101. data/spec/spec_helper.rb +10 -0
  102. data/templates/README.erb +33 -0
  103. data/templates/player.rb +5 -0
  104. data/towers/beginner/level_001.rb +18 -0
  105. data/towers/beginner/level_002.rb +19 -0
  106. data/towers/beginner/level_003.rb +23 -0
  107. data/towers/beginner/level_004.rb +20 -0
  108. data/towers/beginner/level_005.rb +24 -0
  109. data/towers/beginner/level_006.rb +21 -0
  110. data/towers/beginner/level_007.rb +20 -0
  111. data/towers/beginner/level_008.rb +23 -0
  112. data/towers/beginner/level_009.rb +22 -0
  113. data/towers/intermediate/level_001.rb +20 -0
  114. data/towers/intermediate/level_002.rb +22 -0
  115. data/towers/intermediate/level_003.rb +25 -0
  116. data/towers/intermediate/level_004.rb +26 -0
  117. data/towers/intermediate/level_005.rb +21 -0
  118. data/towers/intermediate/level_006.rb +25 -0
  119. data/towers/intermediate/level_007.rb +27 -0
  120. data/towers/intermediate/level_008.rb +25 -0
  121. data/towers/intermediate/level_009.rb +33 -0
  122. metadata +226 -0
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Rest do
4
+ before(:each) do
5
+ @warrior = RubyWarrior::Units::Warrior.new
6
+ @rest = RubyWarrior::Abilities::Rest.new(@warrior)
7
+ end
8
+
9
+ it "should give 10% health back" do
10
+ @warrior.stubs(:max_health).returns(20)
11
+ @warrior.health = 10
12
+ @rest.perform
13
+ @warrior.health.should == 12
14
+ end
15
+
16
+ it "should add health when at max" do
17
+ @warrior.stubs(:max_health).returns(20)
18
+ @warrior.health = 20
19
+ @rest.perform
20
+ @warrior.health.should == 20
21
+ end
22
+
23
+ it "should not go over max health" do
24
+ @warrior.stubs(:max_health).returns(20)
25
+ @warrior.health = 19
26
+ @rest.perform
27
+ @warrior.health.should == 20
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Shoot do
4
+ before(:each) do
5
+ @shooter = stub(:position => stub, :shoot_power => 2, :say => nil)
6
+ @shoot = RubyWarrior::Abilities::Shoot.new(@shooter)
7
+ end
8
+
9
+ it "should shoot only first unit" do
10
+ receiver = stub(:alive? => true)
11
+ receiver.expects(:take_damage).with(2)
12
+ other = stub(:alive? => true)
13
+ other.expects(:take_damage).never
14
+ @shoot.expects(:multi_unit).with(:forward, anything).returns([nil, receiver, other, nil])
15
+ @shoot.perform
16
+ end
17
+
18
+ it "should shoot and do nothing if no units in the way" do
19
+ @shoot.expects(:multi_unit).with(:forward, anything).returns([nil, nil])
20
+ lambda { @shoot.perform }.should_not raise_error
21
+ end
22
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Detonate do
4
+ before(:each) do
5
+ @floor = RubyWarrior::Floor.new
6
+ @floor.width = 3
7
+ @floor.height = 3
8
+ @warrior = RubyWarrior::Units::Warrior.new
9
+ @floor.add(@warrior, 0, 0, :south)
10
+ @detonate = RubyWarrior::Abilities::Detonate.new(@warrior)
11
+ end
12
+
13
+ it "should subtract 8 from forward unit and 4 from surrounding units" do
14
+ target_unit = RubyWarrior::Units::Base.new
15
+ target_unit.health = 15
16
+ second_unit = RubyWarrior::Units::Base.new
17
+ second_unit.health = 15
18
+ @floor.add(target_unit, 0, 1)
19
+ @floor.add(second_unit, 1, 1)
20
+ @detonate.perform
21
+ target_unit.health.should == 7
22
+ second_unit.health.should == 11
23
+ end
24
+
25
+ it "should subtract 8 from left unit and 4 from surrounding units" do
26
+ target_unit = RubyWarrior::Units::Base.new
27
+ target_unit.health = 15
28
+ second_unit = RubyWarrior::Units::Base.new
29
+ second_unit.health = 15
30
+ @floor.add(target_unit, 1, 0)
31
+ @floor.add(second_unit, 1, 1)
32
+ @detonate.perform(:left)
33
+ target_unit.health.should == 7
34
+ second_unit.health.should == 11
35
+ end
36
+
37
+ it "should detonate an explosive if any unit has one" do
38
+ captive = RubyWarrior::Units::Captive.new
39
+ captive.health = 1
40
+ captive.add_abilities :explode!
41
+ @floor.add(captive, 1, 1)
42
+ @detonate.perform
43
+ captive.health.should == -99
44
+ @warrior.health.should == -80
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Walk do
4
+ before(:each) do
5
+ @space = stub(:empty? => true, :unit => nil)
6
+ @position = stub(:relative_space => @space, :move => nil)
7
+ @walk = RubyWarrior::Abilities::Walk.new(stub(:position => @position, :say => nil))
8
+ end
9
+
10
+ it "should move position forward when calling perform" do
11
+ @position.expects(:move).with(1, 0)
12
+ @walk.perform
13
+ end
14
+
15
+ it "should move position right if that is direction" do
16
+ @position.expects(:move).with(0, 1)
17
+ @walk.perform(:right)
18
+ end
19
+
20
+ it "should keep position if something is in the way" do
21
+ @position.stubs(:move).raises("shouldn't be called")
22
+ @space.stubs(:empty?).returns(false)
23
+ lambda { @walk.perform(:right) }.should_not raise_error
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+ it "should wrap text at white space when over a specific character length" do
5
+ "foo bar blah".hard_wrap(10).should == "foo bar\nblah"
6
+ end
7
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyWarrior::Floor do
4
+ describe "2x3" do
5
+ before(:each) do
6
+ @floor = RubyWarrior::Floor.new
7
+ @floor.width = 2
8
+ @floor.height = 3
9
+ end
10
+
11
+ it "should be able to add a unit and fetch it at that position" do
12
+ unit = RubyWarrior::Units::Base.new
13
+ @floor.add(unit, 0, 1, :north)
14
+ @floor.get(0, 1).should == unit
15
+ end
16
+
17
+ it "should not consider unit on floor if no position" do
18
+ unit = RubyWarrior::Units::Base.new
19
+ @floor.add(unit, 0, 1, :north)
20
+ unit.position = nil
21
+ @floor.units.should_not include(unit)
22
+ end
23
+
24
+ it "should fetch other units not warrior" do
25
+ unit = RubyWarrior::Units::Base.new
26
+ warrior = RubyWarrior::Units::Warrior.new
27
+ @floor.add(unit, 0, 0, :north)
28
+ @floor.add(warrior, 1, 0, :north)
29
+ @floor.other_units.should_not include(warrior)
30
+ @floor.other_units.should include(unit)
31
+ end
32
+
33
+ it "should not consider corners out of bounds" do
34
+ @floor.should_not be_out_of_bounds(0, 0)
35
+ @floor.should_not be_out_of_bounds(1, 0)
36
+ @floor.should_not be_out_of_bounds(1, 2)
37
+ @floor.should_not be_out_of_bounds(0, 2)
38
+ end
39
+
40
+ it "should consider out of bounds when going beyond sides" do
41
+ @floor.should be_out_of_bounds(-1, 0)
42
+ @floor.should be_out_of_bounds(0, -1)
43
+ @floor.should be_out_of_bounds(0, 3)
44
+ @floor.should be_out_of_bounds(2, 0)
45
+ end
46
+
47
+ it "should return space at the specified location" do
48
+ @floor.space(0, 0).should be_kind_of(RubyWarrior::Space)
49
+ end
50
+
51
+ it "should place stairs and be able to fetch the location" do
52
+ @floor.place_stairs(1, 2)
53
+ @floor.stairs_location.should == [1, 2]
54
+ end
55
+ end
56
+
57
+ describe "3x1" do
58
+ before(:each) do
59
+ @floor = RubyWarrior::Floor.new
60
+ @floor.width = 3
61
+ @floor.height = 1
62
+ end
63
+
64
+ it "should print map with stairs and unit" do
65
+ @floor.add(RubyWarrior::Units::Warrior.new, 0, 0)
66
+ @floor.place_stairs(2, 0)
67
+ @floor.character.should == <<-MAP
68
+ ---
69
+ |@ >|
70
+ ---
71
+ MAP
72
+ end
73
+
74
+ it "should return unique units" do
75
+ u1 = RubyWarrior::Units::Base.new
76
+ @floor.add(u1, 0, 0)
77
+ @floor.add(RubyWarrior::Units::Base.new, 1, 0)
78
+ @floor.unique_units.should == [u1]
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyWarrior::Game do
4
+ before(:each) do
5
+ @game = RubyWarrior::Game.new
6
+ end
7
+
8
+ # GAME DIR
9
+
10
+ it "should make game directory if player says so" do
11
+ RubyWarrior::UI.stubs(:ask).returns(true)
12
+ Dir.expects(:mkdir).with('./rubywarrior')
13
+ @game.make_game_directory
14
+ end
15
+
16
+ it "should not make game and exit if player says no" do
17
+ RubyWarrior::UI.stubs(:ask).returns(false)
18
+ Dir.stubs(:mkdir).raises('should not be called')
19
+ lambda { @game.make_game_directory }.should raise_error(SystemExit)
20
+ end
21
+
22
+
23
+ # PROFILES
24
+
25
+ it "should load profiles for each profile path" do
26
+ RubyWarrior::Profile.expects(:load).with('foo/.profile').returns(1)
27
+ RubyWarrior::Profile.expects(:load).with('bar/.profile').returns(2)
28
+ @game.stubs(:profile_paths).returns(['foo/.profile', 'bar/.profile'])
29
+ @game.profiles.should == [1, 2]
30
+ end
31
+
32
+ it "should find profile paths using Dir[] search" do
33
+ Dir.expects(:[]).with("./rubywarrior/**/.profile")
34
+ @game.profile_paths
35
+ end
36
+
37
+ it "should try to create profile when no profile paths are specified" do
38
+ @game.stubs(:profiles).returns([])
39
+ @game.expects(:new_profile).returns('profile')
40
+ @game.profile.should == 'profile'
41
+ end
42
+
43
+ it "should ask a player to choose a profile if multiple profiles are available, but only once" do
44
+ RubyWarrior::UI.expects(:choose).with('profile', [:profile1, [:new, 'New Profile']]).returns(:profile1)
45
+ @game.stubs(:profiles).returns([:profile1])
46
+ 2.times { @game.profile.should == :profile1 }
47
+ end
48
+
49
+ it "should ask user to choose a tower when creating a new profile" do
50
+ RubyWarrior::UI.stubs(:gets).returns('')
51
+ @game.stubs(:towers).returns([:tower1, :tower2])
52
+ RubyWarrior::UI.expects(:choose).with('tower', [:tower1, :tower2]).returns(stub(:path => '/foo/bar'))
53
+ @game.new_profile
54
+ end
55
+
56
+ it "should pass name and selected tower to profile" do
57
+ profile = stub
58
+ RubyWarrior::UI.stubs(:choose).returns(stub(:path => 'tower_path'))
59
+ RubyWarrior::UI.stubs(:request).returns('name')
60
+ RubyWarrior::Profile.expects(:new).returns(profile)
61
+ profile.expects(:tower_path=).with('tower_path')
62
+ profile.expects(:warrior_name=).with('name')
63
+ @game.new_profile.should == profile
64
+ end
65
+
66
+
67
+ # TOWERS
68
+
69
+ it "load towers for each tower path" do
70
+ RubyWarrior::Tower.expects(:new).with('towers/foo').returns(1)
71
+ RubyWarrior::Tower.expects(:new).with('towers/bar').returns(2)
72
+ @game.stubs(:tower_paths).returns(['towers/foo', 'towers/bar'])
73
+ @game.towers.should == [1, 2]
74
+ end
75
+
76
+ it "should find tower paths using Dir[] search" do
77
+ Dir.expects(:[]).with(File.expand_path('../../../towers/*', __FILE__))
78
+ @game.tower_paths
79
+ end
80
+
81
+
82
+ # LEVEL
83
+
84
+ it "should fetch current level from profile and cache it" do
85
+ @game.stubs(:profile).returns(stub)
86
+ @game.profile.expects(:current_level).returns('foo')
87
+ 2.times { @game.current_level.should == 'foo' }
88
+ end
89
+
90
+ it "should fetch next level from profile and cache it" do
91
+ @game.stubs(:profile).returns(stub)
92
+ @game.profile.expects(:next_level).returns('bar')
93
+ 2.times { @game.next_level.should == 'bar' }
94
+ end
95
+
96
+ it "should report final grade" do
97
+ profile = RubyWarrior::Profile.new
98
+ profile.current_epic_grades = { 1 => 0.7, 2 => 0.9 }
99
+ @game.stubs(:profile).returns(profile)
100
+ report = @game.final_report
101
+ report.should include("Your average grade for this tower is: B")
102
+ report.should include("Level 1: C\n Level 2: A")
103
+ end
104
+
105
+ it "should have an empty final report if no epic grades are available" do
106
+ profile = RubyWarrior::Profile.new
107
+ profile.current_epic_grades = {}
108
+ @game.stubs(:profile).returns(profile)
109
+ @game.final_report.should be_nil
110
+ end
111
+
112
+ it "should have an empty final report if practice level" do
113
+ RubyWarrior::Config.practice_level = 2
114
+ profile = RubyWarrior::Profile.new
115
+ profile.current_epic_grades = { 1 => 0.7, 2 => 0.9 }
116
+ @game.stubs(:profile).returns(profile)
117
+ @game.final_report.should be_nil
118
+ end
119
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyWarrior::LevelLoader do
4
+ describe "with profile" do
5
+ before(:each) do
6
+ @profile = RubyWarrior::Profile.new
7
+ @level = RubyWarrior::Level.new(@profile, 1)
8
+ @loader = RubyWarrior::LevelLoader.new(@level)
9
+ end
10
+
11
+ it "should be able to add description, tip and clue" do
12
+ @loader.description "foo"
13
+ @loader.tip "bar"
14
+ @loader.clue "clue"
15
+ @level.description.should == "foo"
16
+ @level.tip.should == "bar"
17
+ @level.clue.should == "clue"
18
+ end
19
+
20
+ it "should be able to set size" do
21
+ @loader.size 5, 3
22
+ @level.floor.width.should == 5
23
+ @level.floor.height.should == 3
24
+ end
25
+
26
+ it "should be able to add stairs" do
27
+ @level.floor.expects(:place_stairs).with(1, 2)
28
+ @loader.stairs 1, 2
29
+ end
30
+
31
+ it "should yield new unit when building" do
32
+ @loader.unit :base, 1, 2 do |unit|
33
+ unit.should be_kind_of(RubyWarrior::Units::Base)
34
+ unit.position.should be_at(1, 2)
35
+ end
36
+ end
37
+
38
+ it "should be able to add multi-word units" do
39
+ lambda { @loader.unit :thick_sludge, 1, 2 }.should_not raise_error
40
+ end
41
+
42
+ it "should build warrior from profile" do
43
+ @loader.warrior 1, 2 do |unit|
44
+ unit.should be_kind_of(RubyWarrior::Units::Warrior)
45
+ unit.position.should be_at(1, 2)
46
+ end
47
+ end
48
+
49
+ it "should be able to set time bonus" do
50
+ @loader.time_bonus 100
51
+ @level.time_bonus.should == 100
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,203 @@
1
+ require 'spec_helper'
2
+ require 'set'
3
+
4
+ describe RubyWarrior::Level do
5
+ before(:each) do
6
+ @profile = RubyWarrior::Profile.new
7
+ @floor = RubyWarrior::Floor.new
8
+ @level = RubyWarrior::Level.new(@profile, 1)
9
+ @level.floor = @floor
10
+ @level.stubs(:failed?).returns(false)
11
+ end
12
+
13
+ it "should consider passed when warrior is on stairs" do
14
+ @level.warrior = RubyWarrior::Units::Warrior.new
15
+ @floor.add(@level.warrior, 0, 0, :north)
16
+ @floor.place_stairs(0, 0)
17
+ @level.should be_passed
18
+ end
19
+
20
+ it "should default time bonus to zero" do
21
+ @level.time_bonus.should be_zero
22
+ end
23
+
24
+ it "should have a grade relative to ace score" do
25
+ @level.ace_score = 100
26
+ @level.grade_for(110).should == "S"
27
+ @level.grade_for(100).should == "S"
28
+ @level.grade_for(99).should == "A"
29
+ @level.grade_for(89).should == "B"
30
+ @level.grade_for(79).should == "C"
31
+ @level.grade_for(69).should == "D"
32
+ @level.grade_for(59).should == "F"
33
+ end
34
+
35
+ it "should have no grade if there is no ace score" do
36
+ @level.ace_score.should be_nil
37
+ @level.grade_for(100).should be_nil
38
+ end
39
+
40
+ it "should load file contents into level" do
41
+ @level.stubs(:load_path).returns('path/to/level.rb')
42
+ File.expects(:read).with('path/to/level.rb').returns("description 'foo'")
43
+ @level.load_level
44
+ @level.description.should == 'foo'
45
+ end
46
+
47
+ it "should have a player path from profile" do
48
+ @profile.stubs(:player_path).returns('path/to/player')
49
+ @level.player_path.should == 'path/to/player'
50
+ end
51
+
52
+ it "should have a load path from profile tower with level number in it" do
53
+ @profile.stubs(:tower_path).returns('path/to/tower')
54
+ @level.load_path.should == File.expand_path('towers/tower/level_001.rb')
55
+ end
56
+
57
+ it "should exist if file exists" do
58
+ @level.stubs(:load_path).returns('/foo/bar')
59
+ File.expects(:exist?).with('/foo/bar').returns(true)
60
+ @level.exists?.should be_true
61
+ end
62
+
63
+ it "should load player and player path" do
64
+ @level.stubs(:player_path).returns('player/path')
65
+ $:.expects(:<<).with('player/path')
66
+ @level.expects(:load).with('player.rb')
67
+ @level.load_player
68
+ end
69
+
70
+ it "should generate player files" do
71
+ @level.expects(:load_level)
72
+ generator = stub
73
+ generator.expects(:generate)
74
+ RubyWarrior::PlayerGenerator.expects(:new).with(@level).returns(generator)
75
+ @level.generate_player_files
76
+ end
77
+
78
+ it "should setup warrior with profile abilities" do
79
+ @profile.abilities = [:foo, :bar]
80
+ warrior = stub_everything
81
+ warrior.expects(:add_abilities).with(:foo, :bar)
82
+ @level.setup_warrior(warrior)
83
+ end
84
+
85
+ it "should setup warrior with profile name" do
86
+ @profile.warrior_name = "Joe"
87
+ warrior = stub_everything
88
+ warrior.expects(:name=).with("Joe")
89
+ @level.setup_warrior(warrior)
90
+ end
91
+
92
+ describe "playing" do
93
+ before(:each) do
94
+ @level.stubs(:load_level)
95
+ end
96
+
97
+ it "should load level once when playing multiple turns" do
98
+ @level.expects(:load_level)
99
+ @level.play(2)
100
+ end
101
+
102
+ it "should call prepare_turn and play_turn on each object specified number of times" do
103
+ object = RubyWarrior::Units::Base.new
104
+ object.expects(:prepare_turn).times(2)
105
+ object.expects(:perform_turn).times(2)
106
+ @floor.add(object, 0, 0, :north)
107
+ @level.play(2)
108
+ end
109
+
110
+ it "should return immediately when passed" do
111
+ object = RubyWarrior::Units::Base.new
112
+ object.expects(:turn).times(0)
113
+ @floor.add(object, 0, 0, :north)
114
+ @level.stubs(:passed?).returns(true)
115
+ @level.play(2)
116
+ end
117
+
118
+ it "should yield to block in play method for each turn" do
119
+ int = 0
120
+ @level.play(2) do
121
+ int += 1
122
+ end
123
+ int.should == 2
124
+ end
125
+
126
+ it "should count down time_bonus once each turn" do
127
+ @level.time_bonus = 10
128
+ @level.play(3)
129
+ @level.time_bonus.should == 7
130
+ end
131
+
132
+ it "should count down time_bonus below 0" do
133
+ @level.time_bonus = 2
134
+ @level.play(5)
135
+ @level.time_bonus.should be_zero
136
+ end
137
+
138
+ it "should have a pretty score calculation" do
139
+ @level.score_calculation(123, 45).should == "123 + 45 = 168"
140
+ end
141
+
142
+ it "should not have a score calculation when starting score is zero" do
143
+ @level.score_calculation(0, 45).should == "45"
144
+ end
145
+ end
146
+
147
+ describe "tallying points" do
148
+ before(:each) do
149
+ @warrior = stub(:score => 0, :abilities => {})
150
+ @level.stubs(:warrior).returns(@warrior)
151
+ @level.floor.stubs(:other_units).returns([stub])
152
+ end
153
+
154
+ it "should add warrior score to profile" do
155
+ @warrior.stubs(:score).returns(30)
156
+ @level.tally_points
157
+ @profile.score.should == 30
158
+ end
159
+
160
+ it "should add warrior score to profile for epic mode" do
161
+ @profile.enable_epic_mode
162
+ @warrior.stubs(:score).returns(30)
163
+ @level.tally_points
164
+ @profile.current_epic_score.should == 30
165
+ end
166
+
167
+ it "should add level grade percent to profile for epic mode" do
168
+ @level.ace_score = 100
169
+ @profile.enable_epic_mode
170
+ @warrior.stubs(:score).returns(30)
171
+ @level.tally_points
172
+ @profile.current_epic_grades.should == { 1 => 0.3 }
173
+ end
174
+
175
+ it "should not add level grade if ace score is not set" do
176
+ @level.ace_score = nil
177
+ @profile.enable_epic_mode
178
+ @warrior.stubs(:score).returns(30)
179
+ @level.tally_points
180
+ @profile.current_epic_grades.should == {}
181
+ end
182
+
183
+ it "should apply warrior abilities to profile" do
184
+ @warrior.stubs(:abilities).returns({:foo => nil, :bar => nil})
185
+ @level.tally_points
186
+ @profile.abilities.to_set.should == [:foo, :bar].to_set
187
+ end
188
+
189
+ it "should apply time bonus to profile score" do
190
+ @level.time_bonus = 20
191
+ @level.tally_points
192
+ @profile.score.should == 20
193
+ end
194
+
195
+ it "should give 20% bonus when no other units left" do
196
+ @level.floor.stubs(:other_units).returns([])
197
+ @warrior.stubs(:score).returns(10)
198
+ @level.time_bonus = 10
199
+ @level.tally_points
200
+ @profile.score.should == 24
201
+ end
202
+ end
203
+ end