rear_admiral_randy 1.0
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 +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
|
+
|