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,96 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe RubyWarrior::UI do
4
+ before(:each) do
5
+ @ui = RubyWarrior::UI
6
+ @out = StringIO.new
7
+ @in = StringIO.new
8
+ @ui.out_stream = @out
9
+ @ui.in_stream = @in
10
+ end
11
+
12
+ after(:each) do
13
+ @ui.delay = nil
14
+ end
15
+
16
+ it "should add puts to out stream" do
17
+ @ui.puts "hello"
18
+ @out.string.should == "hello\n"
19
+ end
20
+
21
+ it "should add print to out stream without newline" do
22
+ @ui.print "hello"
23
+ @out.string.should == "hello"
24
+ end
25
+
26
+ it "should fetch gets from in stream" do
27
+ @in.puts "bar"
28
+ @in.rewind
29
+ @ui.gets.should == "bar\n"
30
+ end
31
+
32
+ it "should gets should return empty string if no input" do
33
+ @ui.in_stream = nil
34
+ @ui.gets.should == ""
35
+ end
36
+
37
+ it "should request text input" do
38
+ @in.puts "bar"
39
+ @in.rewind
40
+ @ui.request("foo").should == "bar"
41
+ @out.string.should == "foo"
42
+ end
43
+
44
+ it "should ask for yes/no and return true when yes" do
45
+ @ui.expects(:request).with('foo? [yn] ').returns('y')
46
+ @ui.ask("foo?").should be_true
47
+ end
48
+
49
+ it "should ask for yes/no and return false when no" do
50
+ @ui.stubs(:request).returns('n')
51
+ @ui.ask("foo?").should be_false
52
+ end
53
+
54
+ it "should ask for yes/no and return false for any input" do
55
+ @ui.stubs(:request).returns('aklhasdf')
56
+ @ui.ask("foo?").should be_false
57
+ end
58
+
59
+ it "should present multiple options and return selected one" do
60
+ @ui.expects(:request).with(includes('item')).returns('2')
61
+ @ui.choose('item', [:foo, :bar, :test]).should == :bar
62
+ @out.string.should include('[1] foo')
63
+ @out.string.should include('[2] bar')
64
+ @out.string.should include('[3] test')
65
+ end
66
+
67
+ it "choose should accept array as option" do
68
+ @ui.stubs(:request).returns('3')
69
+ @ui.choose('item', [:foo, :bar, [:tower, 'easy']]).should == :tower
70
+ @out.string.should include('[3] easy')
71
+ end
72
+
73
+ it "choose should return option without prompt if only one item" do
74
+ @ui.expects(:puts).never
75
+ @ui.expects(:gets).never
76
+ @ui.stubs(:request).returns('3')
77
+ @ui.choose('item', [:foo]).should == :foo
78
+ end
79
+
80
+ it "choose should return first value in array of option if only on item" do
81
+ @ui.choose('item', [[:foo, :bar]]).should == :foo
82
+ end
83
+
84
+ it "should delay after puts when specified" do
85
+ @ui.delay = 1.3
86
+ @ui.expects(:puts).with("foo")
87
+ @ui.expects(:sleep).with(1.3)
88
+ @ui.puts_with_delay("foo")
89
+ end
90
+
91
+ it "should not delay puts when delay isn't specified" do
92
+ @ui.expects(:puts).with("foo")
93
+ @ui.expects(:sleep).never
94
+ @ui.puts_with_delay("foo")
95
+ end
96
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Units::Archer do
4
+ before(:each) do
5
+ @archer = RubyWarrior::Units::Archer.new
6
+ end
7
+
8
+ it "should have look and shoot abilities" do
9
+ @archer.abilities.keys.to_set.should == [:shoot!, :look].to_set
10
+ end
11
+
12
+ it "should have shoot power of 3" do
13
+ @archer.shoot_power.should == 3
14
+ end
15
+
16
+ it "should have 7 max health" do
17
+ @archer.max_health.should == 7
18
+ end
19
+
20
+ it "should appear as a on map" do
21
+ @archer.to_map.should == "a"
22
+ end
23
+ end
@@ -0,0 +1,133 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Units::Base do
4
+ before(:each) do
5
+ @unit = RubyWarrior::Units::Base.new
6
+ end
7
+
8
+ it "should have an attack power which defaults to zero" do
9
+ @unit.attack_power.should be_zero
10
+ end
11
+
12
+ it "should consider itself dead when no position" do
13
+ @unit.position.should be_nil
14
+ @unit.should_not be_alive
15
+ end
16
+
17
+ it "should consider itself alive with position" do
18
+ @unit.position = stub
19
+ @unit.should be_alive
20
+ end
21
+
22
+ it "should default max health to 10" do
23
+ @unit.max_health.should be_zero
24
+ end
25
+
26
+ it "should do nothing when earning points" do
27
+ lambda { @unit.earn_points(10) }.should_not raise_error
28
+ end
29
+
30
+ it "should default health to max health" do
31
+ @unit.stubs(:max_health).returns(10)
32
+ @unit.health.should == 10
33
+ end
34
+
35
+ it "should subtract health when taking damage" do
36
+ @unit.stubs(:max_health).returns(10)
37
+ @unit.take_damage(3)
38
+ @unit.health.should == 7
39
+ end
40
+
41
+ it "should do nothing when taking damage if health isn't set" do
42
+ lambda { @unit.take_damage(3) }.should_not raise_error
43
+ end
44
+
45
+ it "should set position to nil when running out of health" do
46
+ @unit.position = stub
47
+ @unit.stubs(:max_health).returns(10)
48
+ @unit.take_damage(10)
49
+ @unit.position.should be_nil
50
+ end
51
+
52
+ it "should print out line with name when speaking" do
53
+ RubyWarrior::UI.expects(:puts_with_delay).with("Base foo")
54
+ @unit.say "foo"
55
+ end
56
+
57
+ it "should return name in to_s" do
58
+ @unit.name.should == 'Base'
59
+ @unit.to_s.should == 'Base'
60
+ end
61
+
62
+ it "should prepare turn by calling play_turn with next turn object" do
63
+ @unit.stubs(:next_turn).returns('next_turn')
64
+ @unit.expects(:play_turn).with('next_turn')
65
+ @unit.prepare_turn
66
+ end
67
+
68
+ it "should perform action when calling perform on turn" do
69
+ @unit.position = stub
70
+ RubyWarrior::Abilities::Walk.any_instance.expects(:perform).with(:backward)
71
+ @unit.add_abilities(:walk!)
72
+ turn = stub(:action => [:walk!, :backward])
73
+ @unit.stubs(:next_turn).returns(turn)
74
+ @unit.prepare_turn
75
+ @unit.perform_turn
76
+ end
77
+
78
+ it "should not perform action when dead (no position)" do
79
+ @unit.position = nil
80
+ RubyWarrior::Abilities::Walk.any_instance.stubs(:perform).raises("action should not be called")
81
+ @unit.add_abilities(:walk!)
82
+ turn = stub(:action => [:walk!, :backward])
83
+ @unit.stubs(:next_turn).returns(turn)
84
+ @unit.prepare_turn
85
+ @unit.perform_turn
86
+ end
87
+
88
+ it "should not raise an exception when calling perform_turn when there's no action" do
89
+ @unit.prepare_turn
90
+ lambda { @unit.perform_turn }.should_not raise_error
91
+ end
92
+
93
+ it "should pass abilities to new turn when calling next_turn" do
94
+ RubyWarrior::Turn.expects(:new).with(:walk! => nil, :attack! => nil, :feel => nil).returns('turn')
95
+ @unit.stubs(:abilities).returns(:walk! => nil, :attack! => nil, :feel => nil)
96
+ @unit.next_turn.should == 'turn'
97
+ end
98
+
99
+ it "should add ability" do
100
+ RubyWarrior::Abilities::Walk.expects(:new).with(@unit).returns('walk')
101
+ @unit.add_abilities(:walk!)
102
+ @unit.abilities.should == { :walk! => 'walk' }
103
+ end
104
+
105
+ it "should appear as question mark on map" do
106
+ @unit.to_map.should == "?"
107
+ end
108
+
109
+ it "should be released from bonds when taking damage" do
110
+ @unit.stubs(:max_health).returns(10)
111
+ @unit.bind
112
+ @unit.should be_bound
113
+ @unit.take_damage(2)
114
+ @unit.should_not be_bound
115
+ end
116
+
117
+ it "should be released from bonds when calling release" do
118
+ @unit.bind
119
+ @unit.unbind
120
+ @unit.should_not be_bound
121
+ end
122
+
123
+ it "should not perform action when bound" do
124
+ @unit.position = stub
125
+ @unit.bind
126
+ RubyWarrior::Abilities::Walk.any_instance.stubs(:perform).raises("action should not be called")
127
+ @unit.add_abilities(:walk!)
128
+ turn = stub(:action => [:walk!, :backward])
129
+ @unit.stubs(:next_turn).returns(turn)
130
+ @unit.prepare_turn
131
+ @unit.perform_turn
132
+ end
133
+ end
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Units::ThickSludge do
4
+ before(:each) do
5
+ @captive = RubyWarrior::Units::Captive.new
6
+ end
7
+
8
+ it "should have 1 max health" do
9
+ @captive.max_health.should == 1
10
+ end
11
+
12
+ it "should appear as C on map" do
13
+ @captive.to_map.should == "C"
14
+ end
15
+
16
+ it "should be bound by default" do
17
+ @captive.should be_bound
18
+ end
19
+
20
+ it "should explode when bomb time reaches 0 and unbind itself" do
21
+ @captive.bomb_time = 3
22
+ @captive.play_turn(stub)
23
+ @captive.play_turn(stub)
24
+ @captive.should be_bound
25
+ turn = stub
26
+ turn.expects(:explode!)
27
+ @captive.play_turn(turn)
28
+ @captive.should_not be_bound
29
+ end
30
+
31
+ it "should have explode ability" do
32
+ @captive.abilities.keys.should include(:explode!)
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Units::Sludge do
4
+ before(:each) do
5
+ @sludge = RubyWarrior::Units::Sludge.new
6
+ end
7
+
8
+ it "should have attack action" do
9
+ @sludge.abilities.keys.should include(:attack!)
10
+ end
11
+
12
+ it "should have feel sense" do
13
+ @sludge.abilities.keys.should include(:feel)
14
+ end
15
+
16
+ it "should have attack power of 3" do
17
+ @sludge.attack_power.should == 3
18
+ end
19
+
20
+ it "should have 12 max health" do
21
+ @sludge.max_health.should == 12
22
+ end
23
+
24
+ it "should appear as s on map" do
25
+ @sludge.to_map.should == "s"
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Units::ThickSludge do
4
+ before(:each) do
5
+ @sludge = RubyWarrior::Units::ThickSludge.new
6
+ end
7
+
8
+ it "should have 24 max health" do
9
+ @sludge.max_health.should == 24
10
+ end
11
+
12
+ it "should appear as S on map" do
13
+ @sludge.to_map.should == "S"
14
+ end
15
+
16
+ it "should have the name of 'Thick Sludge'" do
17
+ @sludge.name.should == "Thick Sludge"
18
+ end
19
+ end
@@ -0,0 +1,60 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ class Player
4
+ def turn(warrior)
5
+ end
6
+ end
7
+
8
+ describe RubyWarrior::Units::Warrior do
9
+ before(:each) do
10
+ @warrior = RubyWarrior::Units::Warrior.new
11
+ end
12
+
13
+ it "should default name to warrior" do
14
+ @warrior.name.should == "Warrior"
15
+ @warrior.name = ''
16
+ @warrior.name.should == "Warrior"
17
+ end
18
+
19
+ it "should be able to set name" do
20
+ @warrior.name = "Joe"
21
+ @warrior.name.should == "Joe"
22
+ @warrior.to_s.should == "Joe"
23
+ end
24
+
25
+ it "should have 20 max health" do
26
+ @warrior.max_health.should == 20
27
+ end
28
+
29
+ it "should have 0 score at beginning and be able to earn points" do
30
+ @warrior.score.should be_zero
31
+ @warrior.earn_points(5)
32
+ @warrior.score.should == 5
33
+ end
34
+
35
+ it "should call player.play_turn and pass turn to player" do
36
+ player = stub
37
+ player.expects(:play_turn).with('turn')
38
+ @warrior.stubs(:player).returns(player)
39
+ @warrior.play_turn('turn')
40
+ end
41
+
42
+ it "should call Player.new the first time loading player, and return same object next time" do
43
+ Player.expects(:new).returns('player').times(1)
44
+ 2.times do
45
+ @warrior.player.should == 'player'
46
+ end
47
+ end
48
+
49
+ it "should have an attack power of 5" do
50
+ @warrior.attack_power.should == 5
51
+ end
52
+
53
+ it "should have an shoot power of 3" do
54
+ @warrior.shoot_power.should == 3
55
+ end
56
+
57
+ it "should appear as @ on map" do
58
+ @warrior.to_map.should == "@"
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RubyWarrior::Units::Wizard do
4
+ before(:each) do
5
+ @wizard = RubyWarrior::Units::Wizard.new
6
+ end
7
+
8
+ it "should have look and shoot abilities" do
9
+ @wizard.abilities.keys.to_set.should == [:shoot!, :look].to_set
10
+ end
11
+
12
+ it "should have shoot power of 11" do
13
+ @wizard.shoot_power.should == 11
14
+ end
15
+
16
+ it "should have 3 max health" do
17
+ @wizard.max_health.should == 3
18
+ end
19
+
20
+ it "should appear as w on map" do
21
+ @wizard.to_map.should == "w"
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require File.dirname(__FILE__) + '/../lib/ruby_warrior'
4
+
5
+ Spec::Runner.configure do |config|
6
+ config.mock_with :mocha
7
+ end
@@ -0,0 +1,20 @@
1
+ Level <%= level.number %>
2
+
3
+ <%= level.description %>
4
+
5
+ Tip: <%= level.tip %>
6
+
7
+ <%= level.floor.to_map -%>
8
+
9
+ > = Stairs
10
+ <%- for unit in level.floor.unique_units -%>
11
+ <%= unit.to_map %> = <%= unit.name %> (<%= unit.max_health %> HP)
12
+ <%- end -%>
13
+
14
+
15
+ Available Abilities:
16
+ <%- level.warrior.abilities.each do |name, ability| -%>
17
+
18
+ warrior.<%= name %>
19
+ <%= ability.description %>
20
+ <%- end -%>