sonic_death_monkey 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Battleship.Rakefile +12 -0
- data/Rakefile +47 -0
- data/lib/sonic_death_monkey/sonic_death_monkey.rb +169 -0
- data/spec/sonic_death_monkey/sonic_death_monkey_spec.rb +12 -0
- data/spec/spec_helper.rb +4 -0
- metadata +61 -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,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 = "sonic_death_monkey"
|
13
|
+
PKG_VERSION = "1.0"
|
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:Sonic Death Monkey"
|
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 = "A battleship player"
|
34
|
+
s.author = "Anonymous"
|
35
|
+
s.email = "authors@email.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,169 @@
|
|
1
|
+
module SonicDeathMonkey
|
2
|
+
|
3
|
+
# Battleship Player
|
4
|
+
#
|
5
|
+
# Battleship is board game between two players. See http://en.wikipedia.org/wiki/Battleship for more information and
|
6
|
+
# game rules.
|
7
|
+
#
|
8
|
+
# A player represents the conputer AI to play a game of Battleship. It should know how to place ships and target
|
9
|
+
# the opponents ships.
|
10
|
+
#
|
11
|
+
# This version of Battleship is played on a 10 x 10 grid where rows are labled by the letters A - J and
|
12
|
+
# columns are labled by the numbers 1 - 10. At the start of the game, each player will be asked for ship placements.
|
13
|
+
# Once the ships are placed, play proceeeds by each player targeting one square on their opponents map. A player
|
14
|
+
# may only target one square, reguardless of whether it resulted in a hit or not, before changing turns with her opponent.
|
15
|
+
#
|
16
|
+
class SonicDeathMonkey
|
17
|
+
|
18
|
+
# This method is called at the beginning of each game. A player may only be instantiated once and used to play many games.
|
19
|
+
# So new_game should reset any internal state acquired in previous games so that it is prepared for a new game.
|
20
|
+
#
|
21
|
+
# The name of the opponent player is passed in. This allows for the possibility to learn opponent strategy and
|
22
|
+
# play the game differently based on the opponent.
|
23
|
+
#
|
24
|
+
def new_game(opponent_name)
|
25
|
+
reset
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the placement of the carrier. A carrier consumes 5 squares.
|
29
|
+
#
|
30
|
+
# The return value is a string that describes the placements of the ship.
|
31
|
+
# The placement string must be in the following format:
|
32
|
+
#
|
33
|
+
# "#{ROW}#{COL} #{ORIENTATION}"
|
34
|
+
#
|
35
|
+
# eg
|
36
|
+
#
|
37
|
+
# A1 horizontal # the ship will occupy A1, A2, A3, A4, and A5
|
38
|
+
# A1 vertical # the ship will occupy A1, B1, C1, D1, and E1
|
39
|
+
# F5 horizontal # the ship will occupy F5, F6, F7, F8, and F9
|
40
|
+
# F5 vertical # the ship will occupy F5, G5, H5, I5, and J5
|
41
|
+
#
|
42
|
+
# The ship must not fall off the edge of the map. For example, a carrier placement of 'A8 horizontal' would
|
43
|
+
# not leave enough space in the A row to accomidate the carrier since it requires 5 squares.
|
44
|
+
#
|
45
|
+
# Ships may not overlap with other ships. For example a carrier placement of 'A1 horizontal' and a submarine
|
46
|
+
# placement of 'A1 vertical' would be invalid because bothe ships are trying to occupy the square A1.
|
47
|
+
#
|
48
|
+
# Invalid ship placements will result in disqualification of the player.
|
49
|
+
#
|
50
|
+
def carrier_placement
|
51
|
+
return "A1 horizontal"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the placement of the battleship. A battleship consumes 4 squares.
|
55
|
+
#
|
56
|
+
# See carrier_placement for details on ship placement
|
57
|
+
#
|
58
|
+
def battleship_placement
|
59
|
+
return "B1 horizontal"
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the placement of the destroyer. A destroyer consumes 3 squares.
|
63
|
+
#
|
64
|
+
# See carrier_placement for details on ship placement
|
65
|
+
#
|
66
|
+
def destroyer_placement
|
67
|
+
return "C1 horizontal"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the placement of the submarine. A submarine consumes 3 squares.
|
71
|
+
#
|
72
|
+
# See carrier_placement for details on ship placement
|
73
|
+
#
|
74
|
+
def submarine_placement
|
75
|
+
return "D1 horizontal"
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the placement of the patrolship. A patrolship consumes 2 squares.
|
79
|
+
#
|
80
|
+
# See carrier_placement for details on ship placement
|
81
|
+
#
|
82
|
+
def patrolship_placement
|
83
|
+
return "E1 horizontal"
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns the coordinates of the players next target. This method will be called once per turn. The player
|
87
|
+
# should return target coordinates as a string in the form of:
|
88
|
+
#
|
89
|
+
# "#{ROW}#{COL}"
|
90
|
+
#
|
91
|
+
# eg
|
92
|
+
#
|
93
|
+
# A1 # the square in Row A and Column 1
|
94
|
+
# F5 # the square in Row F and Column 5
|
95
|
+
#
|
96
|
+
# 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
|
97
|
+
# COL should be 1, 2, 3, 4, 5, 6, 7, 8, 9, or 10
|
98
|
+
#
|
99
|
+
# Returning coordinates outside the range or in an invalid format will result in the players disqualification.
|
100
|
+
#
|
101
|
+
# It is illegal to illegal to target a sector more than once. Doing so will also result in disqualification.
|
102
|
+
#
|
103
|
+
def next_target
|
104
|
+
target = target_for_current_shot
|
105
|
+
@shots_taken += 1
|
106
|
+
return target
|
107
|
+
end
|
108
|
+
|
109
|
+
# target_result will be called by the system after a call to next_target. The paramters supplied inform the player
|
110
|
+
# of the results of the target.
|
111
|
+
#
|
112
|
+
# coordinates : string. The coordinates targeted. It will be the same value returned by the previous call to next_target
|
113
|
+
# was_hit : boolean. true if the target was occupied by a ship. false otherwise.
|
114
|
+
# ship_sunk : symbol. nil if the target did not result in the sinking of a ship. If the target did result in
|
115
|
+
# in the sinking of a ship, the ship type is supplied (:carrier, :battleship, :destroyer, :submarine, :patrolship).
|
116
|
+
#
|
117
|
+
# An intelligent player will use the information to better play the game. For example, if the result indicates a
|
118
|
+
# hit, a player my choose to target neighboring squares to hit and sink the remainder of the ship.
|
119
|
+
#
|
120
|
+
def target_result(coordinates, was_hit, ship_sunk)
|
121
|
+
end
|
122
|
+
|
123
|
+
# enemy_targeting is called by the system to inform a player of their apponents move. When the opponent targets
|
124
|
+
# a square, this method is called with the coordinates.
|
125
|
+
#
|
126
|
+
# Players may use this information to understand an opponents targeting strategy and place ships differently
|
127
|
+
# in subsequent games.
|
128
|
+
#
|
129
|
+
def enemy_targeting(coordinates)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Called by the system at the end of a game to inform the player of the results.
|
133
|
+
#
|
134
|
+
# result : 1 of 3 possible values (:victory, :defeate, :disqualified)
|
135
|
+
# disqualification_reason : nil unless the game ended as the result of a disqualification. In the event of a
|
136
|
+
# disqualification, this paramter will hold a string description of the reason for disqualification. Both
|
137
|
+
# players will be informed of the reason.
|
138
|
+
#
|
139
|
+
# :victory # indicates the player won the game
|
140
|
+
# :defeat # indicates the player lost the game
|
141
|
+
# :disqualified # indicates the player was disqualified
|
142
|
+
#
|
143
|
+
def game_over(result, disqualification_reason=nil)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Non API methods #####################################
|
147
|
+
|
148
|
+
attr_reader :opponent, :targets, :enemy_targeted_sectors, :result, :disqualification_reason #:nodoc:
|
149
|
+
|
150
|
+
def initialize #:nodoc:
|
151
|
+
reset
|
152
|
+
end
|
153
|
+
|
154
|
+
private ###############################################
|
155
|
+
|
156
|
+
def reset
|
157
|
+
@shots_taken = 0
|
158
|
+
end
|
159
|
+
|
160
|
+
ROWS = %w{ A B C D E F G H I J }
|
161
|
+
def target_for_current_shot
|
162
|
+
row = ROWS[(@shots_taken) / 10]
|
163
|
+
col = @shots_taken % 10 + 1
|
164
|
+
return "#{row}#{col}"
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
require 'sonic_death_monkey/sonic_death_monkey'
|
3
|
+
|
4
|
+
describe SonicDeathMonkey::SonicDeathMonkey do
|
5
|
+
|
6
|
+
it "should be instantiable with no paramters" do
|
7
|
+
|
8
|
+
lambda { SonicDeathMonkey::SonicDeathMonkey.new }.should_not raise_error
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sonic_death_monkey
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.0"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anonymous
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-15 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A battleship player
|
17
|
+
email: authors@email.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- Battleship.Rakefile
|
26
|
+
- lib
|
27
|
+
- lib/sonic_death_monkey
|
28
|
+
- lib/sonic_death_monkey/sonic_death_monkey.rb
|
29
|
+
- Rakefile
|
30
|
+
- spec
|
31
|
+
- spec/sonic_death_monkey
|
32
|
+
- spec/sonic_death_monkey/sonic_death_monkey_spec.rb
|
33
|
+
- spec/spec_helper.rb
|
34
|
+
has_rdoc: false
|
35
|
+
homepage: http://sparring.rubyforge.org/
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
version:
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
requirements: []
|
54
|
+
|
55
|
+
rubyforge_project: sparring
|
56
|
+
rubygems_version: 1.3.1
|
57
|
+
signing_key:
|
58
|
+
specification_version: 2
|
59
|
+
summary: Battleship Player:Sonic Death Monkey
|
60
|
+
test_files: []
|
61
|
+
|