battlesnake 0.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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +76 -0
- data/Guardfile +6 -0
- data/README.md +38 -0
- data/Rakefile +2 -0
- data/battlesnake.gemspec +32 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docs/Battlesnake/Error.html +135 -0
- data/docs/Battlesnake/Location.html +1005 -0
- data/docs/Battlesnake/Snake.html +1349 -0
- data/docs/Battlesnake.html +155 -0
- data/docs/_index.html +152 -0
- data/docs/class_list.html +51 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +497 -0
- data/docs/file.README.html +107 -0
- data/docs/file_list.html +56 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +107 -0
- data/docs/js/app.js +314 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +219 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/battlesnake/location.rb +142 -0
- data/lib/battlesnake/snake.rb +74 -0
- data/lib/battlesnake/version.rb +4 -0
- data/lib/battlesnake.rb +11 -0
- metadata +149 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Battlesnake
|
4
|
+
##
|
5
|
+
# Represents a pair of (x,y) coordinates, and provides helper methods
|
6
|
+
# for managing distance and direction.
|
7
|
+
class Location
|
8
|
+
# @return [Integer] a positive integer representing the distance from the
|
9
|
+
# left side of the board.
|
10
|
+
attr_reader :x
|
11
|
+
|
12
|
+
# @return [Integer] a positive integer representing the distance from the
|
13
|
+
# bottom of the board.
|
14
|
+
attr_reader :y
|
15
|
+
|
16
|
+
# @return [Hash] coordinates as a hash, for integration with other objects.
|
17
|
+
attr_reader :as_json
|
18
|
+
|
19
|
+
# Valid directions.
|
20
|
+
DIRECTIONS = ['up', 'down', 'right', 'left']
|
21
|
+
|
22
|
+
##
|
23
|
+
# Instantiates with the given (x,y) coordinates. Coordinates can be:
|
24
|
+
# * a hash containing "x" and "y" keys
|
25
|
+
# * a JSON string that parses to such a hash
|
26
|
+
# * an array containing (x,y) coordinates
|
27
|
+
# * two separate (x,y) parameters
|
28
|
+
#
|
29
|
+
# @param coordinates [Hash, Array, String] the coordinates
|
30
|
+
#
|
31
|
+
# @return [Location] a new location object with (x,y) coordinates set.
|
32
|
+
def initialize(*coordinates)
|
33
|
+
set_xy(*coordinates)
|
34
|
+
|
35
|
+
@as_json = {'x' => x, 'y' => y}
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Convenience method to return (x,y) coordinates as an array.
|
40
|
+
#
|
41
|
+
# @return [Array]
|
42
|
+
def coords
|
43
|
+
return @coords if defined?(@coords)
|
44
|
+
@coords = [x, y]
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Calculate the distance from this instance to another.
|
49
|
+
#
|
50
|
+
# @param location [Location] another Location instance.
|
51
|
+
#
|
52
|
+
# @return [Integer] the number of blocks away, in "manhattan distance".
|
53
|
+
def distance(location)
|
54
|
+
[delta_x(location).abs, delta_y(location).abs].reduce(:+)
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Determine the most prominent orthoganal direction [see DIRECTIONS]
|
59
|
+
# toward another location.
|
60
|
+
#
|
61
|
+
# @note Returns _nil_ if the locations are the same. Favors "up" or "down"
|
62
|
+
# if horizontal and vertical distances are the same.
|
63
|
+
#
|
64
|
+
# @param location [Location] another location instance.
|
65
|
+
#
|
66
|
+
# @return [one of DIRECTIONS]
|
67
|
+
def direction(location)
|
68
|
+
return nil if distance(location) == 0
|
69
|
+
|
70
|
+
dx = delta_x(location)
|
71
|
+
dy = delta_y(location)
|
72
|
+
|
73
|
+
if dx.abs <= dy.abs
|
74
|
+
dy > 0 ? 'up' : 'down'
|
75
|
+
elsif dx.abs > dy.abs
|
76
|
+
dx > 0 ? 'right' : 'left'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Return a new location instance with coordinates moved one step in the requested direction.
|
82
|
+
#
|
83
|
+
# @note Returns _nil_ if the requested direction is not recognized.
|
84
|
+
#
|
85
|
+
# @param requested_direction [one of DIRECTIONS]
|
86
|
+
#
|
87
|
+
# @return [Location] a new location instance.
|
88
|
+
def move(requested_direction)
|
89
|
+
return nil unless DIRECTIONS.include?(requested_direction)
|
90
|
+
|
91
|
+
new_x = x
|
92
|
+
new_y = y
|
93
|
+
|
94
|
+
case requested_direction
|
95
|
+
when 'right'
|
96
|
+
new_x += 1
|
97
|
+
when 'left'
|
98
|
+
new_x -= 1
|
99
|
+
when 'up'
|
100
|
+
new_y += 1
|
101
|
+
when 'down'
|
102
|
+
new_y -= 1
|
103
|
+
end
|
104
|
+
|
105
|
+
self.class.new(new_x, new_y)
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def set_xy(*coordinates)
|
111
|
+
unless coordinates.is_a?(Array) && coordinates.size == 2
|
112
|
+
coordinates = coordinates.first
|
113
|
+
end
|
114
|
+
|
115
|
+
case coordinates
|
116
|
+
when Hash
|
117
|
+
hash_to_xy(coordinates)
|
118
|
+
when String
|
119
|
+
hash_to_xy(JSON.parse(coordinates))
|
120
|
+
when Array
|
121
|
+
array_to_xy(coordinates)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def hash_to_xy(coordinates)
|
126
|
+
@x = coordinates['x']
|
127
|
+
@y = coordinates['y']
|
128
|
+
end
|
129
|
+
|
130
|
+
def array_to_xy(coordinates)
|
131
|
+
@x, @y = coordinates
|
132
|
+
end
|
133
|
+
|
134
|
+
def delta_x(location)
|
135
|
+
location.x - x
|
136
|
+
end
|
137
|
+
|
138
|
+
def delta_y(location)
|
139
|
+
location.y - y
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Battlesnake
|
4
|
+
##
|
5
|
+
# Represents a single Battlesnake player.
|
6
|
+
class Snake
|
7
|
+
# @return [Hash] snake as a data structure usable by other objects.
|
8
|
+
attr_reader :as_json
|
9
|
+
|
10
|
+
# @return [String] unique string which identifies the player.
|
11
|
+
attr_reader :id
|
12
|
+
|
13
|
+
# @return [String] name of the player.
|
14
|
+
attr_reader :name
|
15
|
+
|
16
|
+
# @return [Array<Location>] locations occupied by the body of the snake.
|
17
|
+
attr_reader :body
|
18
|
+
|
19
|
+
# @return [Integer] latency of given player's API, _nil_ if not provided.
|
20
|
+
attr_reader :latency
|
21
|
+
|
22
|
+
# @return [Integer] health value between 0 and 100.
|
23
|
+
attr_reader :health
|
24
|
+
|
25
|
+
# @return [Location] location of snake head. Should be the same as body[0].
|
26
|
+
attr_reader :head
|
27
|
+
|
28
|
+
# @return [Integer] number of locations occupied by snake body.
|
29
|
+
attr_reader :length
|
30
|
+
|
31
|
+
# @return [String] message to other players.
|
32
|
+
attr_reader :shout
|
33
|
+
|
34
|
+
# @return [String] squad identifer for games played with teams.
|
35
|
+
attr_reader :squad
|
36
|
+
|
37
|
+
# @return [Hash] display customizations.
|
38
|
+
attr_reader :customizations
|
39
|
+
|
40
|
+
##
|
41
|
+
# Returns a new instance of Snake.
|
42
|
+
#
|
43
|
+
# @param json_or_hash [String,Hash] can be a hash of attributes, or a JSON string which
|
44
|
+
# represents such a structure.
|
45
|
+
#
|
46
|
+
# @return [Snake]
|
47
|
+
def initialize(json_or_hash)
|
48
|
+
@as_json = json_or_hash.is_a?(String) ? JSON.parse(json_or_hash) : json_or_hash
|
49
|
+
|
50
|
+
@id = @as_json['id']
|
51
|
+
@name = @as_json['name']
|
52
|
+
@latency = @as_json['latency'].empty? ? nil : @as_json['latency'].to_i
|
53
|
+
@health = @as_json['health']
|
54
|
+
@length = @as_json['length']
|
55
|
+
@shout = @as_json['shout']
|
56
|
+
@squad = @as_json['squad']
|
57
|
+
@customizations = @as_json['customizations']
|
58
|
+
|
59
|
+
@body = @as_json['body'].map{ |coords| Location.new(coords) }
|
60
|
+
@head = Location.new(@as_json['head'])
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# The current direction the snake is facing, based on the first two segments
|
65
|
+
# of the body. If snake only has a head, no direction can be determined, so
|
66
|
+
# _nil_ is returned.
|
67
|
+
#
|
68
|
+
# @return [String] one of (up, down, left, right)
|
69
|
+
def direction
|
70
|
+
return @direction if defined?(@direction)
|
71
|
+
@direction = length > 1 ? body[1].direction(head) : nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/battlesnake.rb
ADDED
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: battlesnake
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jaime Bellmyer
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-11-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.12.0
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.12.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: guard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.18.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.18.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard-rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.7.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.7.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.28
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.9.28
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fabrication
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 2.30.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 2.30.0
|
83
|
+
description: Focus on strategy, rather than the low-level mapping of JSON objects.
|
84
|
+
email:
|
85
|
+
- ruby@bellmyer.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".yardopts"
|
93
|
+
- CHANGELOG.md
|
94
|
+
- Gemfile
|
95
|
+
- Gemfile.lock
|
96
|
+
- Guardfile
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- battlesnake.gemspec
|
100
|
+
- bin/console
|
101
|
+
- bin/setup
|
102
|
+
- docs/Battlesnake.html
|
103
|
+
- docs/Battlesnake/Error.html
|
104
|
+
- docs/Battlesnake/Location.html
|
105
|
+
- docs/Battlesnake/Snake.html
|
106
|
+
- docs/_index.html
|
107
|
+
- docs/class_list.html
|
108
|
+
- docs/css/common.css
|
109
|
+
- docs/css/full_list.css
|
110
|
+
- docs/css/style.css
|
111
|
+
- docs/file.README.html
|
112
|
+
- docs/file_list.html
|
113
|
+
- docs/frames.html
|
114
|
+
- docs/index.html
|
115
|
+
- docs/js/app.js
|
116
|
+
- docs/js/full_list.js
|
117
|
+
- docs/js/jquery.js
|
118
|
+
- docs/method_list.html
|
119
|
+
- docs/top-level-namespace.html
|
120
|
+
- lib/battlesnake.rb
|
121
|
+
- lib/battlesnake/location.rb
|
122
|
+
- lib/battlesnake/snake.rb
|
123
|
+
- lib/battlesnake/version.rb
|
124
|
+
homepage: https://github.com/bellmyer/battlesnake
|
125
|
+
licenses: []
|
126
|
+
metadata:
|
127
|
+
homepage_uri: https://github.com/bellmyer/battlesnake
|
128
|
+
source_code_uri: https://github.com/bellmyer/battlesnake
|
129
|
+
changelog_uri: https://github.com/bellmyer/battlesnake/CHANGELOG.md
|
130
|
+
post_install_message:
|
131
|
+
rdoc_options: []
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.3.0
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
requirements: []
|
145
|
+
rubygems_version: 3.1.4
|
146
|
+
signing_key:
|
147
|
+
specification_version: 4
|
148
|
+
summary: Object modeling and helpful methods for building Battlesnake players.
|
149
|
+
test_files: []
|