karnowski-ruby-warrior 0.0.1

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