rear_admiral_randy 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Battleship.Rakefile +9 -0
- data/Rakefile +34 -0
- data/lib/rear_admiral_randy/grid.rb +83 -0
- data/lib/rear_admiral_randy/rear_admiral_randy.rb +93 -0
- data/lib/rear_admiral_randy/ship.rb +13 -0
- data/spec/rear_admiral_randy/rear_admiral_randy_spec.rb +35 -0
- data/spec/spec_helper.rb +4 -0
- metadata +63 -0
data/Battleship.Rakefile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
|
5
|
+
desc "Run all specs"
|
6
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
7
|
+
t.spec_files = FileList['spec/**/*.rb']
|
8
|
+
t.rcov = false
|
9
|
+
end
|
10
|
+
|
11
|
+
PKG_NAME = "rear_admiral_randy"
|
12
|
+
PKG_VERSION = "1.0"
|
13
|
+
PKG_TAG = "rear_admiral_randy-1_0"
|
14
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
15
|
+
|
16
|
+
spec = Gem::Specification.new do |s|
|
17
|
+
s.name = PKG_NAME
|
18
|
+
s.version = PKG_VERSION
|
19
|
+
s.files = FileList['**/*'].to_a
|
20
|
+
s.require_path = 'lib'
|
21
|
+
s.test_files = Dir.glob('spec/*_spec.rb')
|
22
|
+
s.bindir = 'bin'
|
23
|
+
s.executables = []
|
24
|
+
s.summary = "Battleship Player:Rear Admiral Randy"
|
25
|
+
|
26
|
+
# You may modify the following attributes.
|
27
|
+
s.description = "A Player that positions ships and fires completely randomly."
|
28
|
+
s.author = "Micah Martin"
|
29
|
+
end
|
30
|
+
|
31
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
32
|
+
pkg.need_zip = false
|
33
|
+
pkg.need_tar = false
|
34
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module RearAdmiralRandy
|
2
|
+
class Sector
|
3
|
+
|
4
|
+
attr_accessor :ship, :attacked
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
class Grid
|
9
|
+
|
10
|
+
CoordinatesRegex = /([A-J])(10|[1-9])/
|
11
|
+
PlacementRegex = /([A-J]([1-9]|10)) (HORIZONTAL|VERTICAL)/
|
12
|
+
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
clear
|
16
|
+
end
|
17
|
+
|
18
|
+
def place(ship, placement)
|
19
|
+
match = PlacementRegex.match(placement.upcase)
|
20
|
+
raise Exception.new(placement) if match.nil?
|
21
|
+
coordinates = match[1]
|
22
|
+
orientation = match[3]
|
23
|
+
|
24
|
+
start_index = index = to_index(coordinates)
|
25
|
+
self[index] = ship
|
26
|
+
(ship.length - 1).times do
|
27
|
+
index = orientation == "HORIZONTAL" ? right(index) : down(index)
|
28
|
+
self[index] = ship
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def attack(coordinates)
|
34
|
+
index = to_index(coordinates)
|
35
|
+
sector = @sectors[index]
|
36
|
+
raise Exception.new(coordinates) if sector.attacked
|
37
|
+
sector.attacked = true
|
38
|
+
return sector.ship
|
39
|
+
end
|
40
|
+
|
41
|
+
def [](coordinates)
|
42
|
+
return @sectors[to_index(coordinates)]
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear
|
46
|
+
@sectors = Array.new(100) { Sector.new }
|
47
|
+
end
|
48
|
+
|
49
|
+
private ###############################################
|
50
|
+
|
51
|
+
def []=(index, ship)
|
52
|
+
raise Exception.new(@sectors[index].ship) if @sectors[index].ship
|
53
|
+
@sectors[index].ship = ship
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_index(coordinates)
|
57
|
+
match = CoordinatesRegex.match(coordinates)
|
58
|
+
raise Exception.new(coordinates) if match.nil?
|
59
|
+
row = match[1]
|
60
|
+
col = match[2]
|
61
|
+
|
62
|
+
row_index = row_to_index(row)
|
63
|
+
col_index = col.to_i - 1
|
64
|
+
return row_index * 10 + col_index
|
65
|
+
end
|
66
|
+
|
67
|
+
Rows = %w{ A B C D E F G H I J }
|
68
|
+
def row_to_index(row)
|
69
|
+
return Rows.index(row)
|
70
|
+
end
|
71
|
+
|
72
|
+
def right(index)
|
73
|
+
raise Exception.new("Sector index #{index} is on the right edge") if index % 10 == 9
|
74
|
+
return index + 1
|
75
|
+
end
|
76
|
+
|
77
|
+
def down(index)
|
78
|
+
raise Exception.new("Sector index #{index} is on the bottom edge") if index > 89
|
79
|
+
return index + 10
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rear_admiral_randy/grid'
|
2
|
+
require 'rear_admiral_randy/ship'
|
3
|
+
|
4
|
+
module RearAdmiralRandy
|
5
|
+
|
6
|
+
class RearAdmiralRandy
|
7
|
+
|
8
|
+
def new_game(opponent_name)
|
9
|
+
find_valid_placements
|
10
|
+
build_move_list
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :carrier_placement, :battleship_placement, :destroyer_placement, :submarine_placement, :patrolship_placement
|
14
|
+
|
15
|
+
def next_target
|
16
|
+
return @targets.shift
|
17
|
+
end
|
18
|
+
|
19
|
+
def target_result(coordinates, was_hit, ship_sunk)
|
20
|
+
end
|
21
|
+
|
22
|
+
def enemy_targeting(coordinates)
|
23
|
+
end
|
24
|
+
|
25
|
+
def game_over(result, disqualification_reason=nil)
|
26
|
+
end
|
27
|
+
|
28
|
+
private #################################################
|
29
|
+
|
30
|
+
ROWS = %w{ A B C D E F G H I J }
|
31
|
+
|
32
|
+
def random_row
|
33
|
+
return ROWS[rand(10)]
|
34
|
+
end
|
35
|
+
|
36
|
+
def random_col
|
37
|
+
return rand(10) + 1
|
38
|
+
end
|
39
|
+
|
40
|
+
def random_orientation
|
41
|
+
return rand(2) == 0 ? "vertical" : "horizontal"
|
42
|
+
end
|
43
|
+
|
44
|
+
def random_placement
|
45
|
+
return "#{random_row}#{random_col} #{random_orientation}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_valid_placements
|
49
|
+
need_valid_placement = true
|
50
|
+
attempts = 0
|
51
|
+
while need_valid_placement
|
52
|
+
attempts += 1
|
53
|
+
begin
|
54
|
+
create_random_placements
|
55
|
+
attempt_placements
|
56
|
+
need_valid_placement = false
|
57
|
+
rescue Exception => e
|
58
|
+
# ignore
|
59
|
+
# puts "failed attempt ##{attempts} : #{e}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def create_random_placements
|
65
|
+
@carrier_placement = random_placement
|
66
|
+
@battleship_placement = random_placement
|
67
|
+
@destroyer_placement = random_placement
|
68
|
+
@submarine_placement = random_placement
|
69
|
+
@patrolship_placement = random_placement
|
70
|
+
end
|
71
|
+
|
72
|
+
def attempt_placements
|
73
|
+
grid = Grid.new
|
74
|
+
grid.place(Ship.new(5), @carrier_placement)
|
75
|
+
grid.place(Ship.new(4), @battleship_placement)
|
76
|
+
grid.place(Ship.new(3), @destroyer_placement)
|
77
|
+
grid.place(Ship.new(3), @submarine_placement)
|
78
|
+
grid.place(Ship.new(2), @patrolship_placement)
|
79
|
+
end
|
80
|
+
|
81
|
+
def build_move_list
|
82
|
+
moves = []
|
83
|
+
ROWS.each do |row|
|
84
|
+
(1..10).each do |col|
|
85
|
+
moves << ["#{row}#{col}", rand(10000)]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
moves.sort! { |a, b| a[1] <=> b[1] }
|
89
|
+
@targets = moves.collect { |move| move[0] }
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
require 'rear_admiral_randy/rear_admiral_randy'
|
3
|
+
|
4
|
+
describe RearAdmiralRandy::RearAdmiralRandy do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@randy = RearAdmiralRandy::RearAdmiralRandy.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should find valid ship placements" do
|
11
|
+
@randy.new_game("Captain Katie")
|
12
|
+
|
13
|
+
grid = RearAdmiralRandy::Grid.new
|
14
|
+
lambda do
|
15
|
+
grid.place(RearAdmiralRandy::Ship.new(5), @randy.carrier_placement)
|
16
|
+
grid.place(RearAdmiralRandy::Ship.new(4), @randy.battleship_placement)
|
17
|
+
grid.place(RearAdmiralRandy::Ship.new(3), @randy.destroyer_placement)
|
18
|
+
grid.place(RearAdmiralRandy::Ship.new(3), @randy.submarine_placement)
|
19
|
+
grid.place(RearAdmiralRandy::Ship.new(2), @randy.patrolship_placement)
|
20
|
+
end.should_not raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have a random move list" do
|
24
|
+
@randy.new_game("Captain Katie")
|
25
|
+
|
26
|
+
targets = []
|
27
|
+
100.times do
|
28
|
+
target = @randy.next_target
|
29
|
+
targets.should_not include(target)
|
30
|
+
targets << target
|
31
|
+
end
|
32
|
+
targets.sort.should_not == targets
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rear_admiral_randy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.0"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Micah Martin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-02 01:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A Player that positions ships and fires completely randomly.
|
17
|
+
email:
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- Battleship.Rakefile
|
26
|
+
- lib
|
27
|
+
- lib/rear_admiral_randy
|
28
|
+
- lib/rear_admiral_randy/grid.rb
|
29
|
+
- lib/rear_admiral_randy/rear_admiral_randy.rb
|
30
|
+
- lib/rear_admiral_randy/ship.rb
|
31
|
+
- Rakefile
|
32
|
+
- spec
|
33
|
+
- spec/rear_admiral_randy
|
34
|
+
- spec/rear_admiral_randy/rear_admiral_randy_spec.rb
|
35
|
+
- spec/spec_helper.rb
|
36
|
+
has_rdoc: false
|
37
|
+
homepage:
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
version:
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.2.0
|
59
|
+
signing_key:
|
60
|
+
specification_version: 2
|
61
|
+
summary: Battleship Player:Rear Admiral Randy
|
62
|
+
test_files: []
|
63
|
+
|