board_game_grid 0.1.2 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
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