rubywarrior-i18n 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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