ensign_erratic 1.0.2
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.
- data/Battleship.Rakefile +12 -0
- data/Rakefile +41 -0
- data/lib/ensign_erratic/board.rb +56 -0
- data/lib/ensign_erratic/ensign_erratic.rb +206 -0
- data/pkg/ensign_erratic-1.0.0.1.gem +0 -0
- data/pkg/ensign_erratic-1.0.0.2.gem +0 -0
- data/pkg/ensign_erratic-1.0.0.3.gem +0 -0
- data/pkg/ensign_erratic-1.0.0.gem +0 -0
- data/pkg/ensign_erratic-1.0.1.gem +0 -0
- data/spec/ensign_erratic/board_spec.rb +55 -0
- data/spec/ensign_erratic/ensign_erratic_spec.rb +204 -0
- data/spec/spec_helper.rb +1 -0
- metadata +62 -0
data/Battleship.Rakefile
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
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 = "ensign_erratic"
|
13
|
+
PKG_VERSION = "1.0.2"
|
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:Ensign Erratic"
|
24
|
+
s.rubyforge_project = "sparring"
|
25
|
+
s.homepage = "http://sparring.rubyforge.org/"
|
26
|
+
|
27
|
+
s.description = "Relatively simple Battleship AI that utilizes random targeting and ship placement"
|
28
|
+
s.author = "Jim Suchy"
|
29
|
+
s.email = "jim@8thlight.com"
|
30
|
+
end
|
31
|
+
|
32
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
33
|
+
pkg.need_zip = false
|
34
|
+
pkg.need_tar = false
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Submit your player"
|
38
|
+
task :submit do
|
39
|
+
submitter = BattleshipTournament::Submit.new(PKG_NAME)
|
40
|
+
submitter.submit
|
41
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module EnsignErratic
|
2
|
+
class Board
|
3
|
+
|
4
|
+
attr_reader :placed_ship_sectors
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@placed_ship_sectors = []
|
8
|
+
end
|
9
|
+
|
10
|
+
Row = %w{ A B C D E F G H I J }
|
11
|
+
PlacementRegex = /(([A-J])([1-9]|10)) (HORIZONTAL|VERTICAL)/i
|
12
|
+
CoordinatesRegex = /([A-J])([1-9|10])/i
|
13
|
+
|
14
|
+
def clear
|
15
|
+
@placed_ship_sectors = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def place_ship(size, placement)
|
19
|
+
@possible_ship_sectors = []
|
20
|
+
|
21
|
+
match = PlacementRegex.match(placement)
|
22
|
+
start_coordinates = match[1]
|
23
|
+
row = match[2]
|
24
|
+
column = match[3].to_i
|
25
|
+
orientation = match[4].upcase
|
26
|
+
|
27
|
+
add_sector(start_coordinates)
|
28
|
+
(size - 1).times do |index|
|
29
|
+
new_coordinates = orientation == "HORIZONTAL" ? move_right(row, column, index) : move_down(row, column, index)
|
30
|
+
add_sector(new_coordinates)
|
31
|
+
end
|
32
|
+
|
33
|
+
@placed_ship_sectors.concat(@possible_ship_sectors)
|
34
|
+
end
|
35
|
+
|
36
|
+
private ###############################################
|
37
|
+
|
38
|
+
def add_sector(coordinates)
|
39
|
+
raise "Ships overlap at #{coordinates}" if @placed_ship_sectors.include?(coordinates)
|
40
|
+
@possible_ship_sectors << coordinates
|
41
|
+
end
|
42
|
+
|
43
|
+
def move_right(row, column, number)
|
44
|
+
new_column = column + number + 1
|
45
|
+
raise "Ship would fall off right edge" if new_column > 10
|
46
|
+
return "#{row}#{new_column}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def move_down(row, column, number)
|
50
|
+
new_row = Row[Row.index(row) + number + 1]
|
51
|
+
raise "Ship would fall off bottom edge" if new_row.nil?
|
52
|
+
return "#{new_row}#{column}"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'ensign_erratic/board'
|
2
|
+
|
3
|
+
module EnsignErratic
|
4
|
+
|
5
|
+
class EnsignErratic
|
6
|
+
|
7
|
+
attr_reader :carrier_placement, :battleship_placement, :destroyer_placement, :submarine_placement, :patrolship_placement
|
8
|
+
attr_reader :opponent_name, :result, :disqualification_reason
|
9
|
+
attr_reader :turns, :enemy_targets, :hits
|
10
|
+
|
11
|
+
def name
|
12
|
+
return "Ensign Erratic"
|
13
|
+
end
|
14
|
+
|
15
|
+
def new_game(opponent_name)
|
16
|
+
@opponent_name = opponent_name
|
17
|
+
reset
|
18
|
+
setup_ships
|
19
|
+
end
|
20
|
+
|
21
|
+
def next_target
|
22
|
+
return seek_and_destroy? ? smart_target : random_target
|
23
|
+
end
|
24
|
+
|
25
|
+
def target_result(coordinates, was_hit, ship_sunk)
|
26
|
+
@turns << coordinates
|
27
|
+
@hits << coordinates if was_hit
|
28
|
+
calculate_seek_and_destroy(was_hit, ship_sunk)
|
29
|
+
end
|
30
|
+
|
31
|
+
def enemy_targeting(coordinates)
|
32
|
+
@enemy_targets << coordinates
|
33
|
+
end
|
34
|
+
|
35
|
+
def game_over(result, disqualification_reason=nil)
|
36
|
+
@result = result
|
37
|
+
@disqualification_reason = disqualification_reason
|
38
|
+
end
|
39
|
+
|
40
|
+
def seek_and_destroy?
|
41
|
+
return @seek_and_destroy
|
42
|
+
end
|
43
|
+
|
44
|
+
private ###############################################
|
45
|
+
|
46
|
+
def reset
|
47
|
+
@turns = []
|
48
|
+
@hits = []
|
49
|
+
@enemy_targets = []
|
50
|
+
@seek_and_destroy = false
|
51
|
+
@board = Board.new
|
52
|
+
Kernel.srand
|
53
|
+
end
|
54
|
+
|
55
|
+
def random_target
|
56
|
+
coordinates = random_coordinates
|
57
|
+
return already_targeted?(coordinates) ? random_target : coordinates
|
58
|
+
end
|
59
|
+
|
60
|
+
def smart_target
|
61
|
+
row, column = last_hit_coordinates
|
62
|
+
|
63
|
+
if @seek_and_destroy_direction == "left"
|
64
|
+
return seek_left(row, column)
|
65
|
+
elsif @seek_and_destroy_direction == "right"
|
66
|
+
return target_right(row, column.to_i)
|
67
|
+
elsif @seek_and_destroy_direction == "up"
|
68
|
+
return seek_up(row, column)
|
69
|
+
elsif @seek_and_destroy_direction == "down"
|
70
|
+
return target_down(row, column)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def target_left(row, column)
|
75
|
+
return "#{row}#{column.to_i - 1}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def target_right(row, column)
|
79
|
+
column += 1
|
80
|
+
next_try = "#{row}#{column}"
|
81
|
+
|
82
|
+
while already_targeted?(next_try)
|
83
|
+
column += 1
|
84
|
+
next_try = "#{row}#{column}"
|
85
|
+
end
|
86
|
+
|
87
|
+
return next_try
|
88
|
+
end
|
89
|
+
|
90
|
+
def target_up(row, column)
|
91
|
+
row_above = Board::Row[Board::Row.index(row) - 1]
|
92
|
+
return "#{row_above}#{column}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def target_down(row, column)
|
96
|
+
row_below = Board::Row[Board::Row.index(row) + 1]
|
97
|
+
next_try = "#{row_below}#{column}"
|
98
|
+
while already_targeted?(next_try)
|
99
|
+
row_below = Board::Row[Board::Row.index(row_below) + 1]
|
100
|
+
next_try = "#{row_below}#{column}"
|
101
|
+
end
|
102
|
+
|
103
|
+
return next_try
|
104
|
+
end
|
105
|
+
|
106
|
+
def seek_left(row, column)
|
107
|
+
next_target = target_left(row, column)
|
108
|
+
if valid_target?(next_target)
|
109
|
+
return next_target
|
110
|
+
else
|
111
|
+
return target_right(row, column.to_i)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def seek_up(row, column)
|
116
|
+
next_target = target_up(row, column)
|
117
|
+
if valid_target?(next_target)
|
118
|
+
return next_target
|
119
|
+
else
|
120
|
+
return target_down(row, column)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def calculate_seek_and_destroy(was_hit, ship_sunk)
|
125
|
+
if @seek_and_destroy
|
126
|
+
if ship_sunk
|
127
|
+
@seek_and_destroy = false
|
128
|
+
elsif !was_hit
|
129
|
+
if @seek_and_destroy_direction == "left"
|
130
|
+
@seek_and_destroy_direction = "right"
|
131
|
+
elsif @seek_and_destroy_direction == "right"
|
132
|
+
@seek_and_destroy_direction = "up"
|
133
|
+
elsif @seek_and_destroy_direction == "up"
|
134
|
+
@seek_and_destroy_direction = "down"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
elsif was_hit
|
138
|
+
@seek_and_destroy = true
|
139
|
+
@seek_and_destroy_direction = "left"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def valid_target?(coordinates)
|
144
|
+
row, column = row_and_column_for(coordinates)
|
145
|
+
return false if column.to_i <= 0
|
146
|
+
return false if already_targeted?(coordinates)
|
147
|
+
return true
|
148
|
+
end
|
149
|
+
|
150
|
+
def already_targeted?(coordinates)
|
151
|
+
return @turns.include?(coordinates)
|
152
|
+
end
|
153
|
+
|
154
|
+
def last_hit_coordinates
|
155
|
+
return row_and_column_for(@hits.last)
|
156
|
+
end
|
157
|
+
|
158
|
+
def row_and_column_for(coordinates)
|
159
|
+
match = Board::CoordinatesRegex.match(coordinates)
|
160
|
+
return match[1], match[2]
|
161
|
+
end
|
162
|
+
|
163
|
+
def setup_ships
|
164
|
+
valid_placement = false
|
165
|
+
while !valid_placement
|
166
|
+
randomize_ship_placement
|
167
|
+
begin
|
168
|
+
place_ships
|
169
|
+
valid_placement = true
|
170
|
+
rescue Exception => e
|
171
|
+
# puts e.message
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def randomize_ship_placement
|
177
|
+
@carrier_placement = random_ship_placement
|
178
|
+
@battleship_placement = random_ship_placement
|
179
|
+
@destroyer_placement = random_ship_placement
|
180
|
+
@submarine_placement = random_ship_placement
|
181
|
+
@patrolship_placement = random_ship_placement
|
182
|
+
end
|
183
|
+
|
184
|
+
def random_ship_placement
|
185
|
+
return "#{random_coordinates} #{random_orientation}"
|
186
|
+
end
|
187
|
+
|
188
|
+
def random_coordinates
|
189
|
+
return "#{Board::Row[Kernel.rand(10)]}#{Kernel.rand(10)+1}"
|
190
|
+
end
|
191
|
+
|
192
|
+
def random_orientation
|
193
|
+
return Kernel.rand(2) == 1 ? "horizontal" : "vertical"
|
194
|
+
end
|
195
|
+
|
196
|
+
def place_ships
|
197
|
+
@board.clear
|
198
|
+
@board.place_ship(5, @carrier_placement)
|
199
|
+
@board.place_ship(4, @battleship_placement)
|
200
|
+
@board.place_ship(3, @destroyer_placement)
|
201
|
+
@board.place_ship(3, @submarine_placement)
|
202
|
+
@board.place_ship(2, @patrolship_placement)
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
require 'ensign_erratic/board'
|
3
|
+
|
4
|
+
describe EnsignErratic::Board do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@board = EnsignErratic::Board.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should place ship horizontally" do
|
11
|
+
@board.place_ship(5, "A1 horizontal")
|
12
|
+
|
13
|
+
@board.placed_ship_sectors.size.should == 5
|
14
|
+
@board.placed_ship_sectors.should include("A1")
|
15
|
+
@board.placed_ship_sectors.should include("A2")
|
16
|
+
@board.placed_ship_sectors.should include("A3")
|
17
|
+
@board.placed_ship_sectors.should include("A4")
|
18
|
+
@board.placed_ship_sectors.should include("A5")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should place ship vertically" do
|
22
|
+
@board.place_ship(3, "B1 vertical")
|
23
|
+
|
24
|
+
@board.placed_ship_sectors.size.should == 3
|
25
|
+
@board.placed_ship_sectors.should include("B1")
|
26
|
+
@board.placed_ship_sectors.should include("C1")
|
27
|
+
@board.placed_ship_sectors.should include("D1")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should raise exception if ships would overlap" do
|
31
|
+
@board.place_ship(5, "B2 horizontal")
|
32
|
+
|
33
|
+
lambda {@board.place_ship(3, "A3 vertical")}.should raise_error("Ships overlap at B3")
|
34
|
+
@board.placed_ship_sectors.size.should == 5
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should raise exception if ship would fall off right edge" do
|
38
|
+
lambda {@board.place_ship(5, "A9 horizontal")}.should raise_error("Ship would fall off right edge")
|
39
|
+
@board.placed_ship_sectors.size.should == 0
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should raise exception if ship would fall off bottom edge" do
|
43
|
+
lambda {@board.place_ship(5, "I3 vertical")}.should raise_error("Ship would fall off bottom edge")
|
44
|
+
@board.placed_ship_sectors.size.should == 0
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should clear placed ship sectors" do
|
48
|
+
@board.place_ship(3, "B1 vertical")
|
49
|
+
|
50
|
+
@board.clear
|
51
|
+
|
52
|
+
@board.placed_ship_sectors.size.should == 0
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
require 'ensign_erratic/ensign_erratic'
|
3
|
+
require 'ensign_erratic/board'
|
4
|
+
|
5
|
+
describe EnsignErratic do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
EnsignErratic::Board.stub!(:new).and_return(mock("board", :place_ship => nil, :clear => nil))
|
9
|
+
|
10
|
+
@player = EnsignErratic::EnsignErratic.new
|
11
|
+
@player.new_game("some player")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have a name" do
|
15
|
+
@player.name.should == "Ensign Erratic"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should store opponent's name" do
|
19
|
+
@player.new_game("your opponent")
|
20
|
+
|
21
|
+
@player.opponent_name.should == "your opponent"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should seed rng for each new game" do
|
25
|
+
Kernel.should_receive(:srand)
|
26
|
+
|
27
|
+
@player.new_game("foo")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have game over" do
|
31
|
+
@player.game_over(:disqualified, "no reason")
|
32
|
+
|
33
|
+
@player.result.should == :disqualified
|
34
|
+
@player.disqualification_reason.should == "no reason"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should target a random location" do
|
38
|
+
Kernel.should_receive(:rand).with(10).twice.and_return(3, 7)
|
39
|
+
|
40
|
+
@player.next_target.should == "D8"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not fire at a location that has already been fired at" do
|
44
|
+
@player.target_result("D8", false, nil)
|
45
|
+
@player.target_result("C6", false, nil)
|
46
|
+
Kernel.should_receive(:rand).with(10).and_return(3, 7, 2, 5, 1, 6)
|
47
|
+
|
48
|
+
@player.next_target.should == "B7"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should store whether opponent's target was a hit" do
|
52
|
+
@player.target_result("A1", true, nil)
|
53
|
+
@player.target_result("C8", false, nil)
|
54
|
+
@player.target_result("F4", true, nil)
|
55
|
+
|
56
|
+
@player.hits.size.should == 2
|
57
|
+
@player.hits[0].should == "A1"
|
58
|
+
@player.hits[1].should == "F4"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should store taken turns" do
|
62
|
+
@player.target_result("A1", true, nil)
|
63
|
+
@player.target_result("C8", false, nil)
|
64
|
+
@player.target_result("F4", true, nil)
|
65
|
+
|
66
|
+
@player.turns[0].should == "A1"
|
67
|
+
@player.turns[1].should == "C8"
|
68
|
+
@player.turns[2].should == "F4"
|
69
|
+
@player.hits[0].should == "A1"
|
70
|
+
@player.hits[1].should == "F4"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should store opponent's targets" do
|
74
|
+
@player.enemy_targeting("B7")
|
75
|
+
@player.enemy_targeting("A3")
|
76
|
+
|
77
|
+
@player.enemy_targets[0].should == "B7"
|
78
|
+
@player.enemy_targets[1].should == "A3"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should go to seek and destroy mode after first hit of a ship" do
|
82
|
+
@player.target_result("A1", true, nil)
|
83
|
+
|
84
|
+
@player.seek_and_destroy?.should == true
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should stay in seek and destroy after missing next shot" do
|
88
|
+
@player.target_result("A7", true, nil)
|
89
|
+
@player.target_result("A6", false, nil)
|
90
|
+
|
91
|
+
@player.seek_and_destroy?.should == true
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should go out of seek and destroy mode after ship is sunk" do
|
95
|
+
@player.target_result("A2", true, nil)
|
96
|
+
|
97
|
+
@player.target_result("A1", true, :patrolship)
|
98
|
+
|
99
|
+
@player.seek_and_destroy?.should == false
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should first target to the left of the hit" do
|
103
|
+
@player.target_result("D3", true, nil)
|
104
|
+
|
105
|
+
@player.next_target.should == "D2"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should target right if missed to the left" do
|
109
|
+
@player.target_result("D3", true, nil)
|
110
|
+
@player.target_result("D2", false, nil)
|
111
|
+
|
112
|
+
@player.next_target.should == "D4"
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should continue to the left if hit" do
|
116
|
+
@player.target_result("D3", true, nil)
|
117
|
+
@player.target_result("D2", true, nil)
|
118
|
+
|
119
|
+
@player.next_target.should == "D1"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should target to the right if hit was on the left edge" do
|
123
|
+
@player.target_result("A1", true, nil)
|
124
|
+
|
125
|
+
@player.next_target.should == "A2"
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should target to the right if sector to left of hit was already targeted" do
|
129
|
+
@player.target_result("D4", false, nil)
|
130
|
+
@player.target_result("D5", true, nil)
|
131
|
+
|
132
|
+
@player.next_target.should == "D6"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should target up if no hits to left or right" do
|
136
|
+
@player.target_result("C5", true, nil)
|
137
|
+
@player.target_result("C4", false, nil)
|
138
|
+
@player.target_result("C6", false, nil)
|
139
|
+
|
140
|
+
@player.next_target.should == "B5"
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should target down if no hits left, right or up" do
|
144
|
+
@player.target_result("C5", true, nil)
|
145
|
+
@player.target_result("C4", false, nil)
|
146
|
+
@player.target_result("C6", false, nil)
|
147
|
+
@player.target_result("B5", false, nil)
|
148
|
+
|
149
|
+
@player.next_target.should == "D5"
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should target down after hitting one above then missing above that" do
|
153
|
+
@player.target_result("C5", true, nil)
|
154
|
+
@player.target_result("C4", false, nil)
|
155
|
+
@player.target_result("C6", false, nil)
|
156
|
+
@player.target_result("B5", true, nil)
|
157
|
+
@player.target_result("A5", false, nil)
|
158
|
+
|
159
|
+
@player.next_target.should == "D5"
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should target down if sector above hit was already targeted" do
|
163
|
+
@player.target_result("B5", false, nil)
|
164
|
+
@player.target_result("C5", true, nil)
|
165
|
+
@player.target_result("C4", false, nil)
|
166
|
+
|
167
|
+
@player.next_target.should == "C6"
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should target right if sector above and below already targeted" do
|
171
|
+
@player.target_result("B5", false, nil)
|
172
|
+
@player.target_result("D5", false, nil)
|
173
|
+
@player.target_result("C4", false, nil)
|
174
|
+
@player.target_result("C5", true, nil)
|
175
|
+
|
176
|
+
@player.next_target.should == "C6"
|
177
|
+
end
|
178
|
+
|
179
|
+
# it "should not try to the right when already know the ship is vertical" do
|
180
|
+
# @player.target_result("C8", true, nil)
|
181
|
+
# @player.target_result("C7", false, nil)
|
182
|
+
# @player.target_result("B8", true, nil)
|
183
|
+
# @player.target_result("A8", false, nil)
|
184
|
+
#
|
185
|
+
# @player.next_target.should == "D8"
|
186
|
+
# end
|
187
|
+
|
188
|
+
# it "should handle initial hit in top corner" do
|
189
|
+
# @player.target_result("A10", true, nil)
|
190
|
+
# @player.target_result("A9", false, nil)
|
191
|
+
#
|
192
|
+
# @player.next_target.should == "B10"
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# it "should handle initial hit on right edge" do
|
196
|
+
# @player.target_result("D10", true, nil)
|
197
|
+
# @player.target_result("D9", false, nil)
|
198
|
+
# @player.target_result("C10", false, nil)
|
199
|
+
#
|
200
|
+
# @player.next_target.should == "E10"
|
201
|
+
# end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
extensions: []
|
3
|
+
homepage: http://sparring.rubyforge.org/
|
4
|
+
executables: []
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.2
|
7
|
+
post_install_message:
|
8
|
+
date: 2008-12-01 06:00:00 +00:00
|
9
|
+
files:
|
10
|
+
- Battleship.Rakefile
|
11
|
+
- lib
|
12
|
+
- pkg
|
13
|
+
- Rakefile
|
14
|
+
- spec
|
15
|
+
- lib/ensign_erratic
|
16
|
+
- lib/ensign_erratic/board.rb
|
17
|
+
- lib/ensign_erratic/ensign_erratic.rb
|
18
|
+
- pkg/ensign_erratic-1.0.0.1.gem
|
19
|
+
- pkg/ensign_erratic-1.0.0.2.gem
|
20
|
+
- pkg/ensign_erratic-1.0.0.3.gem
|
21
|
+
- pkg/ensign_erratic-1.0.0.gem
|
22
|
+
- pkg/ensign_erratic-1.0.1.gem
|
23
|
+
- spec/ensign_erratic
|
24
|
+
- spec/spec_helper.rb
|
25
|
+
- spec/ensign_erratic/board_spec.rb
|
26
|
+
- spec/ensign_erratic/ensign_erratic_spec.rb
|
27
|
+
rubygems_version: 1.2.0
|
28
|
+
rdoc_options: []
|
29
|
+
signing_key:
|
30
|
+
cert_chain: []
|
31
|
+
name: ensign_erratic
|
32
|
+
has_rdoc: false
|
33
|
+
platform: ruby
|
34
|
+
summary: Battleship Player:Ensign Erratic
|
35
|
+
default_executable:
|
36
|
+
bindir: bin
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
version:
|
39
|
+
requirements:
|
40
|
+
- - '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: !str 0
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
version:
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: !str 0
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
specification_version: 2
|
52
|
+
test_files: []
|
53
|
+
dependencies: []
|
54
|
+
description: Relatively simple Battleship AI that utilizes random targeting and ship
|
55
|
+
placement
|
56
|
+
email: jim@8thlight.com
|
57
|
+
authors:
|
58
|
+
- Jim Suchy
|
59
|
+
extra_rdoc_files: []
|
60
|
+
requirements: []
|
61
|
+
rubyforge_project: sparring
|
62
|
+
autorequire:
|