karnowski-ruby-warrior 0.0.1

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 (108) hide show
  1. data/.gitignore +3 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +156 -0
  4. data/Rakefile +36 -0
  5. data/VERSION +1 -0
  6. data/bin/rubywarrior +8 -0
  7. data/features/levels.feature +50 -0
  8. data/features/profiles.feature +46 -0
  9. data/features/step_definitions/common_steps.rb +7 -0
  10. data/features/step_definitions/interaction_steps.rb +53 -0
  11. data/features/support/env.rb +8 -0
  12. data/features/support/mockio.rb +57 -0
  13. data/features/towers.feature +14 -0
  14. data/lib/ruby_warrior.rb +41 -0
  15. data/lib/ruby_warrior/abilities/attack.rb +24 -0
  16. data/lib/ruby_warrior/abilities/base.rb +36 -0
  17. data/lib/ruby_warrior/abilities/bind.rb +19 -0
  18. data/lib/ruby_warrior/abilities/direction_of.rb +13 -0
  19. data/lib/ruby_warrior/abilities/direction_of_stairs.rb +13 -0
  20. data/lib/ruby_warrior/abilities/distance.rb +13 -0
  21. data/lib/ruby_warrior/abilities/explode.rb +16 -0
  22. data/lib/ruby_warrior/abilities/feel.rb +13 -0
  23. data/lib/ruby_warrior/abilities/health.rb +13 -0
  24. data/lib/ruby_warrior/abilities/listen.rb +15 -0
  25. data/lib/ruby_warrior/abilities/look.rb +15 -0
  26. data/lib/ruby_warrior/abilities/pivot.rb +16 -0
  27. data/lib/ruby_warrior/abilities/rescue.rb +23 -0
  28. data/lib/ruby_warrior/abilities/rest.rb +20 -0
  29. data/lib/ruby_warrior/abilities/shoot.rb +23 -0
  30. data/lib/ruby_warrior/abilities/walk.rb +20 -0
  31. data/lib/ruby_warrior/config.rb +11 -0
  32. data/lib/ruby_warrior/core_additions.rb +25 -0
  33. data/lib/ruby_warrior/floor.rb +71 -0
  34. data/lib/ruby_warrior/game.rb +160 -0
  35. data/lib/ruby_warrior/level.rb +93 -0
  36. data/lib/ruby_warrior/level_loader.rb +52 -0
  37. data/lib/ruby_warrior/player_generator.rb +41 -0
  38. data/lib/ruby_warrior/position.rb +80 -0
  39. data/lib/ruby_warrior/profile.rb +86 -0
  40. data/lib/ruby_warrior/space.rb +63 -0
  41. data/lib/ruby_warrior/tower.rb +14 -0
  42. data/lib/ruby_warrior/turn.rb +38 -0
  43. data/lib/ruby_warrior/ui.rb +64 -0
  44. data/lib/ruby_warrior/units/archer.rb +34 -0
  45. data/lib/ruby_warrior/units/base.rb +95 -0
  46. data/lib/ruby_warrior/units/captive.rb +30 -0
  47. data/lib/ruby_warrior/units/sludge.rb +30 -0
  48. data/lib/ruby_warrior/units/thick_sludge.rb +13 -0
  49. data/lib/ruby_warrior/units/warrior.rb +58 -0
  50. data/lib/ruby_warrior/units/wizard.rb +34 -0
  51. data/ruby-warrior.gemspec +191 -0
  52. data/script/console +8 -0
  53. data/spec/fixtures/short-tower/level_001.rb +14 -0
  54. data/spec/fixtures/short-tower/level_002.rb +14 -0
  55. data/spec/fixtures/walking_player.rb +5 -0
  56. data/spec/ruby_warrior/abilities/attack_spec.rb +51 -0
  57. data/spec/ruby_warrior/abilities/base_spec.rb +24 -0
  58. data/spec/ruby_warrior/abilities/bind_spec.rb +19 -0
  59. data/spec/ruby_warrior/abilities/direction_of_spec.rb +13 -0
  60. data/spec/ruby_warrior/abilities/direction_of_stairs_spec.rb +13 -0
  61. data/spec/ruby_warrior/abilities/distance_spec.rb +13 -0
  62. data/spec/ruby_warrior/abilities/explode_spec.rb +21 -0
  63. data/spec/ruby_warrior/abilities/feel_spec.rb +13 -0
  64. data/spec/ruby_warrior/abilities/health_spec.rb +13 -0
  65. data/spec/ruby_warrior/abilities/listen_spec.rb +17 -0
  66. data/spec/ruby_warrior/abilities/look_spec.rb +15 -0
  67. data/spec/ruby_warrior/abilities/pivot_spec.rb +18 -0
  68. data/spec/ruby_warrior/abilities/rescue_spec.rb +40 -0
  69. data/spec/ruby_warrior/abilities/rest_spec.rb +29 -0
  70. data/spec/ruby_warrior/abilities/shoot_spec.rb +22 -0
  71. data/spec/ruby_warrior/abilities/walk_spec.rb +25 -0
  72. data/spec/ruby_warrior/floor_spec.rb +81 -0
  73. data/spec/ruby_warrior/game_spec.rb +96 -0
  74. data/spec/ruby_warrior/level_loader_spec.rb +54 -0
  75. data/spec/ruby_warrior/level_spec.rb +163 -0
  76. data/spec/ruby_warrior/player_generator_spec.rb +12 -0
  77. data/spec/ruby_warrior/position_spec.rb +103 -0
  78. data/spec/ruby_warrior/profile_spec.rb +125 -0
  79. data/spec/ruby_warrior/space_spec.rb +165 -0
  80. data/spec/ruby_warrior/tower_spec.rb +15 -0
  81. data/spec/ruby_warrior/turn_spec.rb +42 -0
  82. data/spec/ruby_warrior/ui_spec.rb +96 -0
  83. data/spec/ruby_warrior/units/archer_spec.rb +23 -0
  84. data/spec/ruby_warrior/units/base_spec.rb +133 -0
  85. data/spec/ruby_warrior/units/captive_spec.rb +34 -0
  86. data/spec/ruby_warrior/units/sludge_spec.rb +27 -0
  87. data/spec/ruby_warrior/units/thick_sludge_spec.rb +19 -0
  88. data/spec/ruby_warrior/units/warrior_spec.rb +60 -0
  89. data/spec/ruby_warrior/units/wizard_spec.rb +23 -0
  90. data/spec/spec_helper.rb +7 -0
  91. data/templates/README.erb +20 -0
  92. data/templates/player.rb +5 -0
  93. data/towers/beginner/level_001.rb +15 -0
  94. data/towers/beginner/level_002.rb +17 -0
  95. data/towers/beginner/level_003.rb +20 -0
  96. data/towers/beginner/level_004.rb +17 -0
  97. data/towers/beginner/level_005.rb +21 -0
  98. data/towers/beginner/level_006.rb +18 -0
  99. data/towers/beginner/level_007.rb +17 -0
  100. data/towers/beginner/level_008.rb +20 -0
  101. data/towers/beginner/level_009.rb +19 -0
  102. data/towers/intermediate/level_001.rb +17 -0
  103. data/towers/intermediate/level_002.rb +19 -0
  104. data/towers/intermediate/level_003.rb +22 -0
  105. data/towers/intermediate/level_004.rb +23 -0
  106. data/towers/intermediate/level_005.rb +18 -0
  107. data/towers/intermediate/level_006.rb +23 -0
  108. metadata +218 -0
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Health do
4
+ before(:each) do
5
+ @warrior = RubyWarrior::Units::Warrior.new
6
+ @health = RubyWarrior::Abilities::Health.new(@warrior)
7
+ end
8
+
9
+ it "should return the amount of health" do
10
+ @warrior.health = 10
11
+ @health.perform.should == 10
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Listen do
4
+ before(:each) do
5
+ @floor = RubyWarrior::Floor.new
6
+ @floor.width = 2
7
+ @floor.height = 3
8
+ @warrior = RubyWarrior::Units::Warrior.new
9
+ @floor.add(@warrior, 0, 0)
10
+ @listen = RubyWarrior::Abilities::Listen.new(@warrior)
11
+ end
12
+
13
+ it "should return an array of spaces which have units on them besides main unit" do
14
+ @floor.add(RubyWarrior::Units::Base.new, 0, 1)
15
+ @listen.perform.should have(1).record
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Look do
4
+ before(:each) do
5
+ @unit = stub(:position => stub, :say => nil)
6
+ @feel = RubyWarrior::Abilities::Look.new(@unit)
7
+ end
8
+
9
+ it "should get 3 objects at position from offset" do
10
+ @unit.position.expects(:relative_space).with(1, 0).returns(1)
11
+ @unit.position.expects(:relative_space).with(2, 0).returns(2)
12
+ @unit.position.expects(:relative_space).with(3, 0).returns(3)
13
+ @feel.perform(:forward).should == [1, 2, 3]
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Pivot do
4
+ before(:each) do
5
+ @position = stub
6
+ @pivot = RubyWarrior::Abilities::Pivot.new(stub(:position => @position, :say => nil))
7
+ end
8
+
9
+ it "should flip around when not passing arguments" do
10
+ @position.expects(:rotate).with(2)
11
+ @pivot.perform
12
+ end
13
+
14
+ it "should rotate 1 when pivoting right" do
15
+ @position.expects(:rotate).with(1)
16
+ @pivot.perform(:right)
17
+ end
18
+ end
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Abilities::Rescue do
4
+ before(:each) do
5
+ @warrior = RubyWarrior::Units::Warrior.new
6
+ @rescue = RubyWarrior::Abilities::Rescue.new(@warrior)
7
+ end
8
+
9
+ it "should rescue captive" do
10
+ captive = RubyWarrior::Units::Captive.new
11
+ captive.position = stub
12
+ @rescue.expects(:space).with(:forward).returns(stub(:captive? => true))
13
+ @rescue.expects(:unit).with(:forward).returns(captive)
14
+ @warrior.expects(:earn_points).with(20)
15
+ @rescue.perform
16
+ captive.position.should be_nil
17
+ end
18
+
19
+ it "should do nothing to other unit if not bound" do
20
+ unit = RubyWarrior::Units::Base.new
21
+ unit.position = stub
22
+ @rescue.expects(:space).with(:forward).returns(stub(:captive? => false))
23
+ @rescue.expects(:unit).with(:forward).never
24
+ @warrior.expects(:earn_points).never
25
+ @rescue.perform
26
+ unit.position.should_not be_nil
27
+ end
28
+
29
+ it "should release other unit when bound" do
30
+ unit = RubyWarrior::Units::Base.new
31
+ unit.bind
32
+ unit.position = stub
33
+ @rescue.expects(:space).with(:forward).returns(stub(:captive? => true))
34
+ @rescue.expects(:unit).with(:forward).returns(unit)
35
+ @warrior.expects(:earn_points).never
36
+ @rescue.perform
37
+ unit.should_not be_bound
38
+ unit.position.should_not be_nil
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../../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 File.dirname(__FILE__) + '/../../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,25 @@
1
+ require File.dirname(__FILE__) + '/../../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,81 @@
1
+ require File.dirname(__FILE__) + '/../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.to_map.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,96 @@
1
+ require File.dirname(__FILE__) + '/../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('./ruby-warrior')
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("./ruby-warrior/**/.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(File.dirname(__FILE__) + '/../../towers/*'))
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
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/../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,163 @@
1
+ require File.dirname(__FILE__) + '/../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 load file contents into level" do
25
+ @level.stubs(:load_path).returns('path/to/level.rb')
26
+ File.expects(:read).with('path/to/level.rb').returns("description 'foo'")
27
+ @level.load_level
28
+ @level.description.should == 'foo'
29
+ end
30
+
31
+ it "should have a player path from profile" do
32
+ @profile.stubs(:player_path).returns('path/to/player')
33
+ @level.player_path.should == 'path/to/player'
34
+ end
35
+
36
+ it "should have a load path from profile tower with level number in it" do
37
+ @profile.stubs(:tower_path).returns('path/to/tower')
38
+ @level.load_path.should == 'path/to/tower/level_001.rb'
39
+ end
40
+
41
+ it "should exist if file exists" do
42
+ @level.stubs(:load_path).returns('/foo/bar')
43
+ File.expects(:exist?).with('/foo/bar').returns(true)
44
+ @level.exists?.should be_true
45
+ end
46
+
47
+ it "should load player and player path" do
48
+ @level.stubs(:player_path).returns('player/path')
49
+ $:.expects(:<<).with('player/path')
50
+ @level.expects(:load).with('player.rb')
51
+ @level.load_player
52
+ end
53
+
54
+ it "should generate player files" do
55
+ @level.expects(:load_level)
56
+ generator = stub
57
+ generator.expects(:generate)
58
+ RubyWarrior::PlayerGenerator.expects(:new).with(@level).returns(generator)
59
+ @level.generate_player_files
60
+ end
61
+
62
+ it "should setup warrior with profile abilities" do
63
+ @profile.abilities = [:foo, :bar]
64
+ warrior = stub_everything
65
+ warrior.expects(:add_abilities).with(:foo, :bar)
66
+ @level.setup_warrior(warrior)
67
+ end
68
+
69
+ it "should setup warrior with profile name" do
70
+ @profile.warrior_name = "Joe"
71
+ warrior = stub_everything
72
+ warrior.expects(:name=).with("Joe")
73
+ @level.setup_warrior(warrior)
74
+ end
75
+
76
+ describe "playing" do
77
+ before(:each) do
78
+ @level.stubs(:load_level)
79
+ end
80
+
81
+ it "should load level once when playing multiple turns" do
82
+ @level.expects(:load_level)
83
+ @level.play(2)
84
+ end
85
+
86
+ it "should call prepare_turn and play_turn on each object specified number of times" do
87
+ object = RubyWarrior::Units::Base.new
88
+ object.expects(:prepare_turn).times(2)
89
+ object.expects(:perform_turn).times(2)
90
+ @floor.add(object, 0, 0, :north)
91
+ @level.play(2)
92
+ end
93
+
94
+ it "should return immediately when passed" do
95
+ object = RubyWarrior::Units::Base.new
96
+ object.expects(:turn).times(0)
97
+ @floor.add(object, 0, 0, :north)
98
+ @level.stubs(:passed?).returns(true)
99
+ @level.play(2)
100
+ end
101
+
102
+ it "should yield to block in play method for each turn" do
103
+ int = 0
104
+ @level.play(2) do
105
+ int += 1
106
+ end
107
+ int.should == 2
108
+ end
109
+
110
+ it "should count down time_bonus once each turn" do
111
+ @level.time_bonus = 10
112
+ @level.play(3)
113
+ @level.time_bonus.should == 7
114
+ end
115
+
116
+ it "should count down time_bonus below 0" do
117
+ @level.time_bonus = 2
118
+ @level.play(5)
119
+ @level.time_bonus.should be_zero
120
+ end
121
+ end
122
+
123
+ describe "tallying points" do
124
+ before(:each) do
125
+ @warrior = stub(:score => 0, :abilities => {})
126
+ @level.stubs(:warrior).returns(@warrior)
127
+ @level.floor.stubs(:other_units).returns([stub])
128
+ end
129
+
130
+ it "should add warrior score to profile" do
131
+ @warrior.stubs(:score).returns(30)
132
+ @level.tally_points
133
+ @profile.score.should == 30
134
+ end
135
+
136
+ it "should add warrior score to profile for epic mode" do
137
+ @profile.enable_epic_mode
138
+ @warrior.stubs(:score).returns(30)
139
+ @level.tally_points
140
+ @profile.current_epic_score.should == 30
141
+ end
142
+
143
+ it "should apply warrior abilities to profile" do
144
+ @warrior.stubs(:abilities).returns({:foo => nil, :bar => nil})
145
+ @level.tally_points
146
+ @profile.abilities.to_set.should == [:foo, :bar].to_set
147
+ end
148
+
149
+ it "should apply time bonus to profile score" do
150
+ @level.time_bonus = 20
151
+ @level.tally_points
152
+ @profile.score.should == 20
153
+ end
154
+
155
+ it "should give 20% bonus when no other units left" do
156
+ @level.floor.stubs(:other_units).returns([])
157
+ @warrior.stubs(:score).returns(10)
158
+ @level.time_bonus = 10
159
+ @level.tally_points
160
+ @profile.score.should == 24
161
+ end
162
+ end
163
+ end