alpha 1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ #
2
+ # DO NOT tamper with this file. It will lead to disqualification.
3
+
4
+ require 'rake'
5
+ require 'spec/rake/spectask'
6
+
7
+ desc "Run all examples with RCov"
8
+ Spec::Rake::SpecTask.new('spec_with_rcov') do |t|
9
+ t.spec_files = FileList['spec/**/*.rb']
10
+ t.rcov = true
11
+ t.rcov_opts = ['-t', '--exclude', 'spec', '--no-html']
12
+ end
@@ -0,0 +1,47 @@
1
+ require 'rake'
2
+ require 'rake/gempackagetask'
3
+ require 'spec/rake/spectask'
4
+ require 'battleship_tournament/submit'
5
+
6
+ desc "Run all specs"
7
+ Spec::Rake::SpecTask.new('spec') do |t|
8
+ t.spec_files = FileList['spec/**/*.rb']
9
+ t.rcov = false
10
+ end
11
+
12
+ PKG_NAME = "alpha"
13
+ PKG_VERSION = "1.7"
14
+
15
+ spec = Gem::Specification.new do |s|
16
+ s.name = PKG_NAME
17
+ s.version = PKG_VERSION
18
+ s.files = FileList['**/*'].to_a
19
+ s.require_path = 'lib'
20
+ s.test_files = Dir.glob('spec/*_spec.rb')
21
+ s.bindir = 'bin'
22
+ s.executables = []
23
+ s.summary = "Battleship Player:alpha"
24
+ s.rubyforge_project = "sparring"
25
+ s.homepage = "http://sparring.rubyforge.org/"
26
+
27
+ ###########################################
28
+ ##
29
+ ## You are encouraged to modify the following
30
+ ## spec attributes.
31
+ ##
32
+ ###########################################
33
+ s.description = "The Alpha bot"
34
+ s.author = "Paul W Pagel"
35
+ s.email = "paul@8thlight.com"
36
+ end
37
+
38
+ Rake::GemPackageTask.new(spec) do |pkg|
39
+ pkg.need_zip = false
40
+ pkg.need_tar = false
41
+ end
42
+
43
+ desc "Submit your player"
44
+ task :submit do
45
+ submitter = BattleshipTournament::Submit.new(PKG_NAME)
46
+ submitter.submit
47
+ end
@@ -0,0 +1,217 @@
1
+ require 'alpha/grid'
2
+ require "alpha/randomizer"
3
+ require "alpha/mover"
4
+
5
+ module Alpha
6
+
7
+ # Battleship Player
8
+ #
9
+ # Battleship is board game between two players. See http://en.wikipedia.org/wiki/Battleship for more information and
10
+ # game rules.
11
+ #
12
+ # A player represents the conputer AI to play a game of Battleship. It should know how to place ships and target
13
+ # the opponents ships.
14
+ #
15
+ # This version of Battleship is played on a 10 x 10 grid where rows are labled by the letters A - J and
16
+ # columns are labled by the numbers 1 - 10. At the start of the game, each player will be asked for ship placements.
17
+ # Once the ships are placed, play proceeeds by each player targeting one square on their opponents map. A player
18
+ # may only target one square, reguardless of whether it resulted in a hit or not, before changing turns with her opponent.
19
+ #
20
+ class Alpha
21
+
22
+ # This method is called at the beginning of each game. A player may only be instantiated once and used to play many games.
23
+ # So new_game should reset any internal state acquired in previous games so that it is prepared for a new game.
24
+ #
25
+ # The name of the opponent player is passed in. This allows for the possibility to learn opponent strategy and
26
+ # play the game differently based on the opponent.
27
+ #
28
+ def new_game(opponent_name)
29
+ reset
30
+ end
31
+
32
+ # Returns the placement of the carrier. A carrier consumes 5 squares.
33
+ #
34
+ # The return value is a string that describes the placements of the ship.
35
+ # The placement string must be in the following format:
36
+ #
37
+ # "#{ROW}#{COL} #{ORIENTATION}"
38
+ #
39
+ # eg
40
+ #
41
+ # A1 horizontal # the ship will occupy A1, A2, A3, A4, and A5
42
+ # A1 vertical # the ship will occupy A1, B1, C1, D1, and E1
43
+ # F5 horizontal # the ship will occupy F5, F6, F7, F8, and F9
44
+ # F5 vertical # the ship will occupy F5, G5, H5, I5, and J5
45
+ #
46
+ # The ship must not fall off the edge of the map. For example, a carrier placement of 'A8 horizontal' would
47
+ # not leave enough space in the A row to accomidate the carrier since it requires 5 squares.
48
+ #
49
+ # Ships may not overlap with other ships. For example a carrier placement of 'A1 horizontal' and a submarine
50
+ # placement of 'A1 vertical' would be invalid because bothe ships are trying to occupy the square A1.
51
+ #
52
+ # Invalid ship placements will result in disqualification of the player.
53
+ #
54
+
55
+ def get_placement(block_number)
56
+ placement = "#{@randomizer.rand_column}#{@randomizer.rand_row} #{@randomizer.rand_direction}"
57
+ square, direction = parse_placement(placement)
58
+ return get_placement(block_number) unless @my_grid.can_place_block?(square, direction, block_number)
59
+ return placement
60
+ end
61
+
62
+ def parse_placement(placement)
63
+ parts = placement.split(" ")
64
+ return parts[0], parts[1]
65
+ end
66
+
67
+ def place(occupied_squares)
68
+ placement = get_placement(occupied_squares)
69
+ square, direction = parse_placement(placement)
70
+ @my_grid.place_block(square, direction, occupied_squares)
71
+ return placement
72
+ end
73
+
74
+ def carrier_placement
75
+ return place(5)
76
+ end
77
+
78
+ # Returns the placement of the battleship. A battleship consumes 4 squares.
79
+ def battleship_placement
80
+ return place(4)
81
+ end
82
+
83
+ # Returns the placement of the destroyer. A destroyer consumes 3 squares.
84
+ def destroyer_placement
85
+ return place(3)
86
+ end
87
+
88
+ # Returns the placement of the submarine. A submarine consumes 3 squares.
89
+ def submarine_placement
90
+ return place(3)
91
+ end
92
+
93
+ # Returns the placement of the patrolship. A patrolship consumes 2 squares.
94
+ def patrolship_placement
95
+ return place(2)
96
+ end
97
+
98
+ # Returns the coordinates of the players next target. This method will be called once per turn. The player
99
+ # should return target coordinates as a string in the form of:
100
+ #
101
+ # "#{ROW}#{COL}"
102
+ #
103
+ # eg
104
+ #
105
+ # A1 # the square in Row A and Column 1
106
+ # F5 # the square in Row F and Column 5
107
+ #
108
+ # Since the map contains only 10 rows and 10 columns, the ROW should be A, B, C, D, E, F, G H, I, or J. And the
109
+ # COL should be 1, 2, 3, 4, 5, 6, 7, 8, 9, or 10
110
+ #
111
+ # Returning coordinates outside the range or in an invalid format will result in the players disqualification.
112
+ #
113
+ # It is illegal to illegal to target a sector more than once. Doing so will also result in disqualification.
114
+ #
115
+ def next_target
116
+ target = target_for_current_shot
117
+ @shots_taken += 1
118
+ return target
119
+ end
120
+
121
+ # target_result will be called by the system after a call to next_target. The paramters supplied inform the player
122
+ # of the results of the target.
123
+ #
124
+ # coordinates : string. The coordinates targeted. It will be the same value returned by the previous call to next_target
125
+ # was_hit : boolean. true if the target was occupied by a ship. false otherwise.
126
+ # ship_sunk : symbol. nil if the target did not result in the sinking of a ship. If the target did result in
127
+ # in the sinking of a ship, the ship type is supplied (:carrier, :battleship, :destroyer, :submarine, :patrolship).
128
+ #
129
+ # An intelligent player will use the information to better play the game. For example, if the result indicates a
130
+ # hit, a player my choose to target neighboring squares to hit and sink the remainder of the ship.
131
+ #
132
+ def target_result(coordinates, was_hit, ship_sunk)
133
+ result = nil
134
+ if was_hit
135
+ result = :hit
136
+ @red_zone = true unless ship_sunk
137
+ else
138
+ result = :miss
139
+ end
140
+ @red_zone = false if ship_sunk
141
+
142
+ @opponents_grid.place(coordinates, result)
143
+ end
144
+
145
+ # enemy_targeting is called by the system to inform a player of their apponents move. When the opponent targets
146
+ # a square, this method is called with the coordinates.
147
+ #
148
+ # Players may use this information to understand an opponents targeting strategy and place ships differently
149
+ # in subsequent games.
150
+ #
151
+ def enemy_targeting(coordinates)
152
+ end
153
+
154
+ # Called by the system at the end of a game to inform the player of the results.
155
+ #
156
+ # result : 1 of 3 possible values (:victory, :defeate, :disqualified)
157
+ # disqualification_reason : nil unless the game ended as the result of a disqualification. In the event of a
158
+ # disqualification, this paramter will hold a string description of the reason for disqualification. Both
159
+ # players will be informed of the reason.
160
+ #
161
+ # :victory # indicates the player won the game
162
+ # :defeat # indicates the player lost the game
163
+ # :disqualified # indicates the player was disqualified
164
+ #
165
+ def game_over(result, disqualification_reason=nil)
166
+ end
167
+
168
+ # Non API methods #####################################
169
+
170
+ attr_reader :opponent, :targets, :enemy_targeted_sectors, :result, :disqualification_reason #:nodoc:
171
+ attr_reader :battle_queue, :opponents_grid, :red_zone
172
+
173
+ def initialize #:nodoc:
174
+ reset
175
+ end
176
+
177
+ private ###############################################
178
+
179
+ def reset
180
+ @shots_taken = 0
181
+ @randomizer = Randomizer.new
182
+ @my_grid = Grid.new
183
+ @opponents_grid = Grid.new
184
+ @red_zone = false
185
+ end
186
+
187
+ def target_for_current_shot
188
+ if @red_zone
189
+ mover = Mover.new
190
+ last_move = @opponents_grid.moves.last
191
+ row = @opponents_grid.get_row(last_move)
192
+ column = @opponents_grid.get_column(last_move)
193
+
194
+ result = mover.go_right(row, column, @opponents_grid)
195
+ return result if result
196
+
197
+ result = mover.go_left(row, column, @opponents_grid)
198
+ return result if result
199
+
200
+ result = mover.go_down(row, column, @opponents_grid)
201
+ return result if result
202
+
203
+ result = mover.go_up(row, column, @opponents_grid)
204
+ return result if result
205
+ end
206
+ return shot_candidate
207
+
208
+ end
209
+
210
+ def shot_candidate
211
+ candidate = "#{@randomizer.rand_column}#{@randomizer.rand_row}"
212
+ return shot_candidate unless @opponents_grid.query(candidate) == :empty
213
+ return candidate
214
+ end
215
+ end
216
+
217
+ end
@@ -0,0 +1,91 @@
1
+
2
+ module Alpha
3
+ class Grid
4
+ attr_reader :moves
5
+ @@LETTERS = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
6
+ def initialize
7
+ @grid = {}
8
+ @moves = []
9
+
10
+ @@LETTERS.each do |letter|
11
+ 10.times {|times| @grid["#{letter}#{times + 1}"] = :empty }
12
+ end
13
+ end
14
+
15
+ def letters
16
+ return @@LETTERS
17
+ end
18
+
19
+ def place(key, value)
20
+ @moves << key
21
+ return @grid[key] = value
22
+ end
23
+
24
+ def query(criteria)
25
+ return @grid[criteria]
26
+ end
27
+
28
+ def last_a_hit?
29
+ return @grid[@moves.last] == :hit
30
+ end
31
+
32
+ def place_block(placement, direction, occupied_squares)
33
+ if direction == "horizontal"
34
+ row = get_row(placement)
35
+ column = get_column(placement)
36
+
37
+ occupied_squares.times do |col|
38
+ place("#{row}#{col + column}", :placed)
39
+ end
40
+ else
41
+ row = index_of(get_row(placement))
42
+ column = get_column(placement)
43
+ occupied_squares.times do |new_row|
44
+ place("#{@@LETTERS[(row + new_row)] }#{column}", :placed)
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ def can_place_block?(placement, direction, occupied_squares)
51
+ if direction == "horizontal"
52
+ row = get_row(placement)
53
+ column = get_column(placement)
54
+
55
+ occupied_squares.times do |col|
56
+ return false if query("#{row}#{(column + col)}") != :empty
57
+ end
58
+ else
59
+ row = index_of(get_row(placement))
60
+ column = get_column(placement)
61
+ occupied_squares.times do |new_row|
62
+ return false if query("#{@@LETTERS[(row + new_row)] }#{column}") != :empty
63
+ end
64
+ end
65
+ return true
66
+ end
67
+
68
+
69
+ def get_row(placement)
70
+ return placement[0,1]
71
+ end
72
+
73
+ def get_column(placement)
74
+ if placement.size == 2
75
+ return placement[1,2].to_i
76
+ else
77
+ return placement[1,3].to_i
78
+ end
79
+ end
80
+
81
+
82
+ def index_of(item)
83
+ @@LETTERS.each_with_index do |letter, index|
84
+ return index if letter == item
85
+ end
86
+
87
+ raise "ITEM #{item} is not in LETTERS LIST"
88
+ end
89
+ end
90
+ end
91
+
@@ -0,0 +1,51 @@
1
+ module Alpha
2
+
3
+ class Mover
4
+
5
+ def go_right(row, column, grid)
6
+ i = 1
7
+ while true
8
+ square_candidate_value = grid.query("#{row}#{column + i}")
9
+ return "#{row}#{column + i}" if square_candidate_value == :empty
10
+ break unless square_candidate_value == :hit
11
+ i += 1
12
+ end
13
+ end
14
+
15
+ def go_left(row, column, grid)
16
+ i = 1
17
+ while true
18
+ square_candidate_value = grid.query("#{row}#{column - i}")
19
+ return "#{row}#{column - i}" if square_candidate_value == :empty
20
+ break unless square_candidate_value == :hit
21
+ i += 1
22
+ end
23
+ end
24
+
25
+ def go_down(row, column, grid)
26
+ i = 1
27
+ while true
28
+ index = grid.index_of(row)
29
+
30
+ square_candidate_value = grid.query("#{grid.letters[index + i]}#{column}")
31
+ return "#{grid.letters[index + i]}#{column}" if square_candidate_value == :empty
32
+ break unless square_candidate_value == :hit
33
+ i += 1
34
+ end
35
+ end
36
+
37
+ def go_up(row, column, grid)
38
+ i = 1
39
+ while true
40
+ index = grid.index_of(row)
41
+
42
+ square_candidate_value = grid.query("#{grid.letters[index - i]}#{column}")
43
+ return "#{grid.letters[index - i]}#{column}" if square_candidate_value == :empty
44
+ break unless square_candidate_value == :hit
45
+ i += 1
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,39 @@
1
+ module Alpha
2
+ class Randomizer
3
+
4
+ def rand_row
5
+ return random.to_s
6
+ end
7
+
8
+ def rand_column
9
+ return @@LETTERS[random]
10
+ end
11
+
12
+ def rand_direction
13
+ return @@DIRECTIONS[Kernel.rand(2)]
14
+ end
15
+
16
+ def random
17
+ return Kernel.rand(10)
18
+ end
19
+
20
+ @@DIRECTIONS = {
21
+ 0 => "horizontal",
22
+ 1 => "vertical"
23
+ }
24
+
25
+ @@LETTERS = {
26
+ 0 => "A",
27
+ 1 => "B",
28
+ 2 => "C",
29
+ 3 => "D",
30
+ 4 => "E",
31
+ 5 => "F",
32
+ 6 => "G",
33
+ 7 => "H",
34
+ 8 => "I",
35
+ 9 => "J"
36
+ }
37
+ end
38
+
39
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,133 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require 'alpha/alpha'
3
+
4
+
5
+ describe Alpha::Alpha, "placement" do
6
+
7
+ before(:each) do
8
+ @alpha = Alpha::Alpha.new
9
+ end
10
+
11
+ it "should find a random column" do
12
+
13
+ @alpha.carrier_placement.should_not be(nil)
14
+ @alpha.battleship_placement.should_not be(nil)
15
+ @alpha.destroyer_placement.should_not be(nil)
16
+ @alpha.submarine_placement.should_not be(nil)
17
+ @alpha.patrolship_placement.should_not be(nil)
18
+ end
19
+ end
20
+
21
+ describe Alpha::Alpha do
22
+
23
+ before(:each) do
24
+ @alpha = Alpha::Alpha.new
25
+ end
26
+
27
+ it "should remember results of a miss" do
28
+ @alpha.target_result("A1", false, false)
29
+ @alpha.opponents_grid.query("A1").should == :miss
30
+ end
31
+
32
+ it "should remember results of a hit" do
33
+ @alpha.target_result("A1", true, false)
34
+ @alpha.opponents_grid.query("A1").should == :hit
35
+ end
36
+
37
+ it "should remember results of many hits" do
38
+ @alpha.target_result("A1", true, false)
39
+ @alpha.opponents_grid.query("A1").should == :hit
40
+ @alpha.target_result("A2", true, false)
41
+ @alpha.opponents_grid.query("A2").should == :hit
42
+ @alpha.target_result("A3", true, false)
43
+ @alpha.opponents_grid.query("A3").should == :hit
44
+ end
45
+
46
+ it "should flag if it is a hit and not sink" do
47
+ @alpha.target_result("A1", true, false)
48
+ @alpha.red_zone.should == true
49
+ @alpha.target_result("A1", true, true)
50
+ @alpha.red_zone.should == false
51
+ end
52
+
53
+ it "should move right if it has a hit" do
54
+ @alpha.target_result("A1", true, false)
55
+ @alpha.opponents_grid.query("A1").should == :hit
56
+ @alpha.next_target.should == "A2"
57
+ end
58
+
59
+ it "should not move right if it is off the board" do
60
+ @alpha.target_result("A10", true, false)
61
+ @alpha.opponents_grid.query("A10").should == :hit
62
+ @alpha.next_target.should == "A9"
63
+ end
64
+
65
+ it "should not move right if it is off the board" do
66
+ @alpha.target_result("A10", true, false)
67
+ @alpha.opponents_grid.query("A10").should == :hit
68
+ @alpha.next_target.should == "A9"
69
+ end
70
+
71
+ it "should continue to move right if there are hits" do
72
+ @alpha.opponents_grid.place("A6", :hit)
73
+ @alpha.target_result("A5", true, false)
74
+ @alpha.next_target.should == "A7"
75
+ end
76
+
77
+ it "should continue to move right until it hits a miss, then try left" do
78
+ @alpha.opponents_grid.place("A6", :hit)
79
+ @alpha.opponents_grid.place("A7", :miss)
80
+ @alpha.target_result("A5", true, false)
81
+ @alpha.next_target.should == "A4"
82
+ end
83
+
84
+ it "should continue to move right until it hits a miss, then try left" do
85
+ @alpha.opponents_grid.place("A6", :hit)
86
+ @alpha.opponents_grid.place("A7", :hit)
87
+ @alpha.target_result("A5", true, false)
88
+ @alpha.next_target.should == "A8"
89
+ end
90
+
91
+ it "should continue left if right dowesn't work" do
92
+ @alpha.opponents_grid.place("A9", :hit)
93
+ @alpha.opponents_grid.place("A8", :hit)
94
+ @alpha.target_result("A10", true, false)
95
+ @alpha.next_target.should == "A7"
96
+ end
97
+
98
+ it "should go DOWN if left and right don't work" do
99
+ @alpha.opponents_grid.place("C5", :miss)
100
+ @alpha.opponents_grid.place("C3", :miss)
101
+ @alpha.target_result("C4", true, false)
102
+ @alpha.next_target.should == "D4"
103
+ end
104
+
105
+ it "should go UP if left and right and down don't work" do
106
+ @alpha.opponents_grid.place("C5", :miss)
107
+ @alpha.opponents_grid.place("C3", :miss)
108
+ @alpha.opponents_grid.place("D4", :miss)
109
+ @alpha.target_result("C4", true, false)
110
+ @alpha.next_target.should == "B4"
111
+ end
112
+
113
+ # it "should not go more than once in a bad direction" do
114
+ # @alpha.target_result("C4", true, false)
115
+ # @alpha.next_target.should == "C5"
116
+ # @alpha.target_result("C5", false, false)
117
+ # @alpha.next_target.should == "C3"
118
+ # end
119
+
120
+
121
+ end
122
+
123
+ # A B C D E F G H I J
124
+ # 1 | | | | | | | | | | |
125
+ # 2 | | | | | | | | | | |
126
+ # 3 | | | | | | | | | | |
127
+ # 4 | | | | | | | | | | |
128
+ # 5 | | | | | | | | | | |
129
+ # 6 | | | | | | | | | | |
130
+ # 7 | | | | | | | | | | |
131
+ # 8 | | | | | | | | | | |
132
+ # 9 | | | | | | | | | | |
133
+ # 10| | | | | | | | | | |
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require 'alpha/grid'
3
+
4
+ describe Alpha::Grid do
5
+
6
+ before(:each) do
7
+ @grid = Alpha::Grid.new
8
+ end
9
+
10
+ it "should mark the spot" do
11
+ @grid.place("A1", :miss)
12
+
13
+ @grid.query("A1").should == :miss
14
+ end
15
+
16
+ it "should place a horizontal block on a grid" do
17
+ @grid.place_block("A1", "horizontal", 5)
18
+
19
+ @grid.query("A1").should == :placed
20
+ @grid.query("A2").should == :placed
21
+ @grid.query("A3").should == :placed
22
+ @grid.query("A4").should == :placed
23
+ @grid.query("A5").should == :placed
24
+ end
25
+
26
+ it "should place a horizontal block on a grid" do
27
+ @grid.place_block("A2", "horizontal", 5)
28
+
29
+ @grid.query("A2").should == :placed
30
+ @grid.query("A3").should == :placed
31
+ @grid.query("A4").should == :placed
32
+ @grid.query("A5").should == :placed
33
+ @grid.query("A6").should == :placed
34
+ end
35
+
36
+ it "should place a horizontal block on a grid" do
37
+ @grid.place_block("C3", "horizontal", 5)
38
+
39
+ @grid.query("C3").should == :placed
40
+ @grid.query("C4").should == :placed
41
+ @grid.query("C5").should == :placed
42
+ @grid.query("C6").should == :placed
43
+ @grid.query("C7").should == :placed
44
+ end
45
+
46
+ it "should place a vertical block" do
47
+ @grid.place_block("A1", "vertical", 5)
48
+
49
+ @grid.query("A1").should == :placed
50
+ @grid.query("B1").should == :placed
51
+ @grid.query("C1").should == :placed
52
+ @grid.query("D1").should == :placed
53
+ @grid.query("E1").should == :placed
54
+ end
55
+
56
+ it "should place a block on a grid" do
57
+ @grid.can_place_block?("A1", "horizontal", 5).should == true
58
+ @grid.can_place_block?("A1", "vertical", 5).should == true
59
+
60
+ @grid.can_place_block?("A10", "horizontal", 5).should == false
61
+ @grid.can_place_block?("J10", "vertical", 5).should == false
62
+ end
63
+
64
+ it "should keep a queue of moves" do
65
+ @grid.place("A1", :hit)
66
+
67
+ @grid.moves.size.should == 1
68
+ @grid.moves[0].should == "A1"
69
+ end
70
+
71
+ it "should tell me it the last one was a hit" do
72
+ @grid.place("A1", :miss)
73
+ @grid.last_a_hit?.should == false
74
+
75
+ @grid.place("A2", :hit)
76
+ @grid.last_a_hit?.should == true
77
+ end
78
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require "alpha/randomizer"
3
+
4
+ describe Alpha::Randomizer do
5
+
6
+ before(:each) do
7
+ @randomizer = Alpha::Randomizer.new
8
+ end
9
+
10
+ it "should randomize numbers between one and ten" do
11
+ Kernel.should_receive(:rand).with(10)
12
+ @randomizer.rand_row
13
+ end
14
+
15
+ it "should randomize colomn numbers" do
16
+ Kernel.should_receive(:rand).with(10)
17
+ @randomizer.rand_column
18
+ end
19
+
20
+ it "should randomize the direction" do
21
+ Kernel.should_receive(:rand).with(2)
22
+ @randomizer.rand_direction
23
+ end
24
+
25
+ end
@@ -0,0 +1,4 @@
1
+ $: << File.expand_path(File.dirname(__FILE__) + "/../lib")
2
+
3
+ require 'rubygems'
4
+ require 'spec'
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alpha
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.7"
5
+ platform: ruby
6
+ authors:
7
+ - Paul W Pagel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-01 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: The Alpha bot
17
+ email: paul@8thlight.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - Battleship.Rakefile
26
+ - lib
27
+ - lib/alpha
28
+ - lib/alpha/alpha.rb
29
+ - lib/alpha/grid.rb
30
+ - lib/alpha/mover.rb
31
+ - lib/alpha/randomizer.rb
32
+ - pkg
33
+ - pkg/alpha-1.1.gem
34
+ - pkg/alpha-1.2.gem
35
+ - pkg/alpha-1.3.gem
36
+ - pkg/alpha-1.4.gem
37
+ - pkg/alpha-1.5.gem
38
+ - pkg/paul-1.0.gem
39
+ - Rakefile
40
+ - spec
41
+ - spec/alpha
42
+ - spec/alpha/alpha_spec.rb
43
+ - spec/alpha/grid_spec.rb
44
+ - spec/alpha/randomizer_spec.rb
45
+ - spec/spec_helper.rb
46
+ has_rdoc: false
47
+ homepage: http://sparring.rubyforge.org/
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project: sparring
68
+ rubygems_version: 1.3.0
69
+ signing_key:
70
+ specification_version: 2
71
+ summary: Battleship Player:alpha
72
+ test_files: []
73
+