board_game_grid 0.1.2 → 0.1.7
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 +4 -4
- data/.gitignore +1 -0
- data/lib/board_game_grid.rb +3 -1
- data/lib/board_game_grid/piece.rb +124 -0
- data/lib/board_game_grid/square.rb +28 -6
- data/lib/board_game_grid/square_set.rb +119 -7
- data/lib/board_game_grid/vector.rb +7 -3
- data/lib/board_game_grid/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08f7b2a3342d4355bb117938c6eab6f2d6a10cd31bad0eeee2a6f5b0eee14fb7'
|
4
|
+
data.tar.gz: f5fb49a01d5a1a2cee3d5a22a43c3651af02baafa3f8fc775617f37f72c5d329
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03b293ca58728b526c868a4382929093bec8c67f5b0ba6a9223a4e14fa0440b695fd1a5ff53a27dbb472b4923407bfaeb1c637ce48b2bf78598bdb3ef18b6740
|
7
|
+
data.tar.gz: 41c0e069d78f457ab290f47efe178b97c43d74077b6649aaa0c01a5d51cf16e4171a9b1906ea9ecfd734fbb37f882c49585008d02de486040e95dc563d7d95ae
|
data/.gitignore
CHANGED
data/lib/board_game_grid.rb
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
module BoardGameGrid
|
2
|
+
|
3
|
+
# = Piece
|
4
|
+
#
|
5
|
+
# A piece that can move on a board
|
6
|
+
class Piece
|
7
|
+
# The forwards direciton of the piece for each player
|
8
|
+
FORWARDS_DIRECTION = { 1 => -1, 2 => 1 }
|
9
|
+
|
10
|
+
def initialize(id: , player_number: , type: nil)
|
11
|
+
@id = id
|
12
|
+
@player_number = player_number
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Fixnum] the identifier of the piece.
|
16
|
+
attr_reader :id
|
17
|
+
|
18
|
+
# @return [Fixnum] the owner of the piece.
|
19
|
+
attr_reader :player_number
|
20
|
+
|
21
|
+
# The opposing player number
|
22
|
+
#
|
23
|
+
# @return [Fixnum]
|
24
|
+
def opponent
|
25
|
+
player_number == 1 ? 2 : 1
|
26
|
+
end
|
27
|
+
|
28
|
+
# The stringified identifier of the piece type.
|
29
|
+
#
|
30
|
+
# @return [Fixnum]
|
31
|
+
def type
|
32
|
+
self.class.to_s.split('::').last.downcase
|
33
|
+
end
|
34
|
+
|
35
|
+
# Can the piece move from a square, to a square, given the game state?
|
36
|
+
#
|
37
|
+
# @param [Square] from
|
38
|
+
# the origin square.
|
39
|
+
#
|
40
|
+
# @param [Square] to
|
41
|
+
# the destination square.
|
42
|
+
#
|
43
|
+
# @param [GameState] game_state
|
44
|
+
# the current game state.
|
45
|
+
#
|
46
|
+
# @return [Boolean]
|
47
|
+
def can_move?(from, to, game_state)
|
48
|
+
destinations(from, game_state).include?(to)
|
49
|
+
end
|
50
|
+
|
51
|
+
# All the squares that the piece can move to and/or capture.
|
52
|
+
#
|
53
|
+
# @param [Square] square
|
54
|
+
# the origin square.
|
55
|
+
#
|
56
|
+
# @param [GameState] game_state
|
57
|
+
# the current game state.
|
58
|
+
#
|
59
|
+
# @return [SquareSet]
|
60
|
+
def destinations(square, game_state)
|
61
|
+
[]
|
62
|
+
end
|
63
|
+
|
64
|
+
# All the squares that the piece can move to.
|
65
|
+
#
|
66
|
+
# @param [Square] square
|
67
|
+
# the origin square.
|
68
|
+
#
|
69
|
+
# @param [GameState] game_state
|
70
|
+
# the current game state.
|
71
|
+
#
|
72
|
+
# @return [SquareSet]
|
73
|
+
def move_squares(square, game_state)
|
74
|
+
destinations(square, game_state)
|
75
|
+
end
|
76
|
+
|
77
|
+
# All the squares that the piece can capture.
|
78
|
+
#
|
79
|
+
# @param [Square] square
|
80
|
+
# the origin square.
|
81
|
+
#
|
82
|
+
# @param [GameState] game_state
|
83
|
+
# the current game state.
|
84
|
+
#
|
85
|
+
# @return [SquareSet]
|
86
|
+
def capture_squares(squares, game_state)
|
87
|
+
destinations(squares, game_state)
|
88
|
+
end
|
89
|
+
|
90
|
+
# All the squares that the piece could potentially capture. (i.e. if a piece was there)
|
91
|
+
#
|
92
|
+
# @param [Square] square
|
93
|
+
# the origin square.
|
94
|
+
#
|
95
|
+
# @param [GameState] game_state
|
96
|
+
# the current game state.
|
97
|
+
#
|
98
|
+
# @return [SquareSet]
|
99
|
+
def potential_capture_squares(square, game_state)
|
100
|
+
capture_squares(square, game_state)
|
101
|
+
end
|
102
|
+
|
103
|
+
# returns a serialized piece as a hash
|
104
|
+
#
|
105
|
+
# @return [Hash]
|
106
|
+
def as_json
|
107
|
+
{
|
108
|
+
id: id,
|
109
|
+
player_number: player_number,
|
110
|
+
type: type
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
# returns the direction the piece moves
|
115
|
+
#
|
116
|
+
# player 1 moves up (-1)
|
117
|
+
# player 2 moves down (1)
|
118
|
+
#
|
119
|
+
# @return [Fixnum]
|
120
|
+
def forwards_direction
|
121
|
+
FORWARDS_DIRECTION[player_number]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -48,6 +48,18 @@ module BoardGameGrid
|
|
48
48
|
# @return [Hash,NilClass] The piece on the square if any.
|
49
49
|
attr_accessor :piece
|
50
50
|
|
51
|
+
# A serialized version of the square as a hash
|
52
|
+
#
|
53
|
+
# @return [Hash]
|
54
|
+
def as_json
|
55
|
+
{
|
56
|
+
id: id,
|
57
|
+
x: x,
|
58
|
+
y: y,
|
59
|
+
piece: piece && piece.as_json
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
51
63
|
# checks if the square matches the attributes passed.
|
52
64
|
#
|
53
65
|
# @param [Symbol] attribute
|
@@ -64,6 +76,8 @@ module BoardGameGrid
|
|
64
76
|
value = obj.send(k)
|
65
77
|
if !value.nil? && v.is_a?(Hash)
|
66
78
|
v.all? { |k2,v2| hash_obj_matcher.call(value, k2, v2) }
|
79
|
+
elsif v.is_a?(Array) && !value.is_a?(Array)
|
80
|
+
v.include?(value)
|
67
81
|
else
|
68
82
|
value == v
|
69
83
|
end
|
@@ -86,6 +100,20 @@ module BoardGameGrid
|
|
86
100
|
!piece
|
87
101
|
end
|
88
102
|
|
103
|
+
# Is the square occupied by the specified player?
|
104
|
+
#
|
105
|
+
# @return [Boolean]
|
106
|
+
def occupied_by_player?(player_number)
|
107
|
+
piece && piece.player_number == player_number
|
108
|
+
end
|
109
|
+
|
110
|
+
# Is the square occupied by the specified player?
|
111
|
+
#
|
112
|
+
# @return [Boolean]
|
113
|
+
def occupied_by_opponent?(player_number)
|
114
|
+
piece && piece.player_number != player_number
|
115
|
+
end
|
116
|
+
|
89
117
|
# Is the square the same as another one?
|
90
118
|
#
|
91
119
|
# @return [Boolean]
|
@@ -100,11 +128,5 @@ module BoardGameGrid
|
|
100
128
|
Point.new(x, y)
|
101
129
|
end
|
102
130
|
|
103
|
-
# A serialized version of the square as a hash
|
104
|
-
#
|
105
|
-
# @return [Hash]
|
106
|
-
def as_json
|
107
|
-
{ id: id, x: x, y: y, piece: piece }
|
108
|
-
end
|
109
131
|
end
|
110
132
|
end
|
@@ -47,6 +47,13 @@ module BoardGameGrid
|
|
47
47
|
def_delegator :squares, :each
|
48
48
|
def_delegator :squares, :empty?
|
49
49
|
|
50
|
+
# serializes the squares as a hash
|
51
|
+
#
|
52
|
+
# @return [Hash]
|
53
|
+
def as_json
|
54
|
+
squares.map(&:as_json)
|
55
|
+
end
|
56
|
+
|
50
57
|
# Concat two SquareSets together
|
51
58
|
#
|
52
59
|
# @param [SquareSet] other
|
@@ -188,6 +195,35 @@ module BoardGameGrid
|
|
188
195
|
select { |square| square.x == x && square.y == y }.first
|
189
196
|
end
|
190
197
|
|
198
|
+
# Find the square with the matching piece identifier
|
199
|
+
#
|
200
|
+
# @param [Fixnum] piece_id
|
201
|
+
# the unique identifier of the piece.
|
202
|
+
#
|
203
|
+
# @return [Square]
|
204
|
+
# ==== example:
|
205
|
+
# # Find the square with a piece with id 4
|
206
|
+
# square_set.find_by_piece_id(4)
|
207
|
+
def find_by_piece_id(piece_id)
|
208
|
+
find { |s| s.piece && s.piece.id == piece_id }
|
209
|
+
end
|
210
|
+
|
211
|
+
# Find all squares in the y direction of square
|
212
|
+
#
|
213
|
+
# @param [Square] square
|
214
|
+
# the originating square
|
215
|
+
#
|
216
|
+
# @param [Fixnum] direction_y
|
217
|
+
# the direction, either up (-1) or down (1)
|
218
|
+
#
|
219
|
+
# @return [SquareSet]
|
220
|
+
# ==== Example:
|
221
|
+
# # Get all squares up from square_a
|
222
|
+
# square_set.in_direction(square_a, -1)
|
223
|
+
def in_direction(square, direction_y)
|
224
|
+
select { |s| BoardGameGrid::Vector.new(square, s).direction.y == direction_y }
|
225
|
+
end
|
226
|
+
|
191
227
|
# Find all squares within distance of square
|
192
228
|
#
|
193
229
|
# @param [Square] square
|
@@ -220,6 +256,39 @@ module BoardGameGrid
|
|
220
256
|
select { |square| Vector.new(origin, square).magnitude == distance }
|
221
257
|
end
|
222
258
|
|
259
|
+
|
260
|
+
# Find all squares a certain number of ranks away
|
261
|
+
#
|
262
|
+
# @param [Square] origin
|
263
|
+
# the originating square
|
264
|
+
#
|
265
|
+
# @param [Fixnum] distance
|
266
|
+
# the specified distance from the square
|
267
|
+
#
|
268
|
+
# @return [SquareSet]
|
269
|
+
# ==== Example:
|
270
|
+
# # Get all squares at 2 ranks away from square_a
|
271
|
+
# square_set.ranks_away(square_a, 2)
|
272
|
+
def ranks_away(origin, distance)
|
273
|
+
select { |square| Vector.new(origin, square).dy.abs == distance }
|
274
|
+
end
|
275
|
+
|
276
|
+
# Find all squares a certain number of files away
|
277
|
+
#
|
278
|
+
# @param [Square] origin
|
279
|
+
# the originating square
|
280
|
+
#
|
281
|
+
# @param [Fixnum] distance
|
282
|
+
# the specified distance from the square
|
283
|
+
#
|
284
|
+
# @return [SquareSet]
|
285
|
+
# ==== Example:
|
286
|
+
# # Get all squares at 2 ranks away from square_a
|
287
|
+
# square_set.files_away(square_a, 2)
|
288
|
+
def files_away(origin, distance)
|
289
|
+
select { |square| Vector.new(origin, square).dx.abs == distance }
|
290
|
+
end
|
291
|
+
|
223
292
|
# Find all squares orthogonal from square
|
224
293
|
#
|
225
294
|
# @param [Square] square
|
@@ -272,6 +341,56 @@ module BoardGameGrid
|
|
272
341
|
select { |square| Vector.new(origin, square).not_orthogonal_or_diagonal? }
|
273
342
|
end
|
274
343
|
|
344
|
+
# Takes a player number and returns all squares occupied by the player
|
345
|
+
#
|
346
|
+
# @param [Fixnum] player_number
|
347
|
+
# the player's number.
|
348
|
+
#
|
349
|
+
# @return [SquareSet]
|
350
|
+
def occupied_by_player(player_number)
|
351
|
+
select { |s| s.occupied_by_player?(player_number) }
|
352
|
+
end
|
353
|
+
|
354
|
+
# Takes a player number and returns all squares occupied by the opponent of the player
|
355
|
+
#
|
356
|
+
# @param [Fixnum] player_number
|
357
|
+
# the player's number.
|
358
|
+
#
|
359
|
+
# @return [SquareSet]
|
360
|
+
def occupied_by_opponent(player_number)
|
361
|
+
select { |s| s.occupied_by_opponent?(player_number) }
|
362
|
+
end
|
363
|
+
|
364
|
+
# Takes a player number and returns all squares unoccupied or occupied by the opponent of the player
|
365
|
+
#
|
366
|
+
# @param [Fixnum] player_number
|
367
|
+
# the player's number.
|
368
|
+
#
|
369
|
+
# @return [SquareSet]
|
370
|
+
def unoccupied_or_occupied_by_opponent(player_number)
|
371
|
+
select { |s| s.unoccupied? || s.occupied_by_opponent?(player_number) }
|
372
|
+
end
|
373
|
+
|
374
|
+
# Find all squares occupied by a piece of a particular type
|
375
|
+
#
|
376
|
+
# @param [Class] piece_type
|
377
|
+
# the class of the piece.
|
378
|
+
#
|
379
|
+
# @return [SquareSet]
|
380
|
+
def occupied_by_piece(piece_type)
|
381
|
+
select { |s| s.piece && s.piece.is_a?(piece_type) }
|
382
|
+
end
|
383
|
+
|
384
|
+
# Find all squares occupied by a piece not of a particular type
|
385
|
+
#
|
386
|
+
# @param [Class] piece_type
|
387
|
+
# the class of the piece.
|
388
|
+
#
|
389
|
+
# @return [SquareSet]
|
390
|
+
def excluding_piece(piece_type)
|
391
|
+
select { |s| s.piece && !s.piece.is_a?(piece_type) }
|
392
|
+
end
|
393
|
+
|
275
394
|
# Find all squares without pieces on them.
|
276
395
|
#
|
277
396
|
# @return [SquareSet]
|
@@ -327,12 +446,5 @@ module BoardGameGrid
|
|
327
446
|
|
328
447
|
self.class.new(squares: _squares)
|
329
448
|
end
|
330
|
-
|
331
|
-
# serializes the squares as a hash
|
332
|
-
#
|
333
|
-
# @return [Hash]
|
334
|
-
def as_json
|
335
|
-
squares.map(&:as_json)
|
336
|
-
end
|
337
449
|
end
|
338
450
|
end
|
@@ -73,14 +73,18 @@ module BoardGameGrid
|
|
73
73
|
orthogonal? || diagonal?
|
74
74
|
end
|
75
75
|
|
76
|
-
|
77
|
-
|
76
|
+
# The distance on the x axis
|
77
|
+
#
|
78
|
+
# @return [Fixnum]
|
78
79
|
def dx
|
79
80
|
destination.x - origin.x
|
80
81
|
end
|
81
82
|
|
83
|
+
# The distance on the y axis
|
84
|
+
#
|
85
|
+
# @return [Fixnum]
|
82
86
|
def dy
|
83
87
|
destination.y - origin.y
|
84
88
|
end
|
85
89
|
end
|
86
|
-
end
|
90
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: board_game_grid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Humphreys
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- board_game_grid.gemspec
|
72
72
|
- lib/board_game_grid.rb
|
73
73
|
- lib/board_game_grid/direction.rb
|
74
|
+
- lib/board_game_grid/piece.rb
|
74
75
|
- lib/board_game_grid/point.rb
|
75
76
|
- lib/board_game_grid/square.rb
|
76
77
|
- lib/board_game_grid/square_set.rb
|