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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dbcdb4a9672a1d039ef09cccc368dcaaf01463258683bc3dc80f557e018918f2
4
- data.tar.gz: 0d8cf28d4594433989f48ab193e1db4feb74aa971ec254f123db6d500c8b5046
3
+ metadata.gz: '08f7b2a3342d4355bb117938c6eab6f2d6a10cd31bad0eeee2a6f5b0eee14fb7'
4
+ data.tar.gz: f5fb49a01d5a1a2cee3d5a22a43c3651af02baafa3f8fc775617f37f72c5d329
5
5
  SHA512:
6
- metadata.gz: e7cc7f9587922d5fd23760df797cf5f83aef6f0ad57836b642287b16d9aa446980c6030e1e776496eed0cb12b27a7f56aac18a252ddf2153f0d6c38153b81999
7
- data.tar.gz: ad708fd41faa49f3cc5f090e5d6396efbd33dab9a8ddcfa5cc2cf86f81309293ef0224ede0e788bed7af7dc4f0bfbfd2edaa8d7d0854945f7a508f2a8bd082eb
6
+ metadata.gz: 03b293ca58728b526c868a4382929093bec8c67f5b0ba6a9223a4e14fa0440b695fd1a5ff53a27dbb472b4923407bfaeb1c637ce48b2bf78598bdb3ef18b6740
7
+ data.tar.gz: 41c0e069d78f457ab290f47efe178b97c43d74077b6649aaa0c01a5d51cf16e4171a9b1906ea9ecfd734fbb37f882c49585008d02de486040e95dc563d7d95ae
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ *.swp
@@ -5,4 +5,6 @@ module BoardGameGrid
5
5
 
6
6
  end
7
7
 
8
- require 'board_game_grid/square_set'
8
+ require 'board_game_grid/square_set'
9
+ require 'board_game_grid/square'
10
+ require 'board_game_grid/piece'
@@ -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
- private
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
@@ -1,3 +1,3 @@
1
1
  module BoardGameGrid
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.7"
3
3
  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.2
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: 2020-03-25 00:00:00.000000000 Z
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