just_checkers 0.2.0 → 0.3.0

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
  SHA1:
3
- metadata.gz: 404c68f0f2336d1e7082534610f59f9a82dfe427
4
- data.tar.gz: af653b067e74d1e31d4f97a5bccaef45b4c78e4a
3
+ metadata.gz: 60946aa3db499cb440fd0c2d9979c86f76d535d3
4
+ data.tar.gz: 58d674537166da0ad642230543b5911e1cfa558f
5
5
  SHA512:
6
- metadata.gz: 9088167eaa8e61a7c0fcbc2a45ecddce41c845810471fa593e3e84668e75b37a9cab2326f80fa0bd2c8cf85b1bffc01588beb802156de686ff52ef2765077a39
7
- data.tar.gz: fd1903da0c448ac2208cd44232a0722b23f0e9e7356a68039c9bb702809538a668744155bd2ba28182521ed75e9d947017e66aba914b2bd4d5ca89dcb92d481a
6
+ metadata.gz: 9a57e7a29e8e0c6f950abac5d470501fd55977c78fe502414dd78130b6957ef113df5437a3ba5f35319f6905441769fc47e75a934cd31dbba603734feec550a4
7
+ data.tar.gz: 7d6f5c656e3d79558dc7ada2ec6d442d6badc247803632a8abbb5117aaf9f01d44f7e7608e5b71afaf5f0603e11fae9dcf6a1433697e24f721665473ddad4365
data/README.md CHANGED
@@ -29,6 +29,18 @@ Moves can be made by passing in the player number, from co-ordinates and an arra
29
29
  game_state.move(1, {x: 1, y: 2}, [{x: 2, y: 3}])
30
30
  ```
31
31
 
32
+ Alternatively, moves can be made by specifying the ids of the squares.
33
+
34
+ ```ruby
35
+ game_state.move(1, 1, [2])
36
+ ```
37
+
38
+ The last change with all its details are found in the `last_change` attribute
39
+
40
+ ```ruby
41
+ game_state.last_change
42
+ ```
43
+
32
44
  If something happens errors may be found in the errors attribute
33
45
 
34
46
  ```ruby
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rake/testtask'
2
+ require 'bundler/gem_tasks'
2
3
 
3
4
  Rake::TestTask.new do |t|
4
5
  t.libs << 'test'
@@ -31,6 +31,7 @@ module JustCheckers
31
31
  @current_player_number = current_player_number
32
32
  @squares = SquareSet.new(squares: squares)
33
33
  @errors = []
34
+ @last_change = {}
34
35
  end
35
36
 
36
37
  # @return [Fixnum] who's turn it is.
@@ -42,6 +43,9 @@ module JustCheckers
42
43
  # @return [Array<Error>] errors if any.
43
44
  attr_reader :errors
44
45
 
46
+ # @return [Hash] most recent change.
47
+ attr_reader :last_change
48
+
45
49
  # Instantiates a new GameState object in the starting position
46
50
  #
47
51
  # @return [GameState]
@@ -49,45 +53,45 @@ module JustCheckers
49
53
  new({
50
54
  current_player_number: 1,
51
55
  squares: [
52
- { x: 1, y: 0, piece: { player_number: 1, direction: 1, king: false }},
53
- { x: 3, y: 0, piece: { player_number: 1, direction: 1, king: false }},
54
- { x: 5, y: 0, piece: { player_number: 1, direction: 1, king: false }},
55
- { x: 7, y: 0, piece: { player_number: 1, direction: 1, king: false }},
56
-
57
- { x: 0, y: 1, piece: { player_number: 1, direction: 1, king: false }},
58
- { x: 2, y: 1, piece: { player_number: 1, direction: 1, king: false }},
59
- { x: 4, y: 1, piece: { player_number: 1, direction: 1, king: false }},
60
- { x: 6, y: 1, piece: { player_number: 1, direction: 1, king: false }},
61
-
62
- { x: 1, y: 2, piece: { player_number: 1, direction: 1, king: false }},
63
- { x: 3, y: 2, piece: { player_number: 1, direction: 1, king: false }},
64
- { x: 5, y: 2, piece: { player_number: 1, direction: 1, king: false }},
65
- { x: 7, y: 2, piece: { player_number: 1, direction: 1, king: false }},
66
-
67
- { x: 0, y: 3, piece: nil },
68
- { x: 2, y: 3, piece: nil },
69
- { x: 4, y: 3, piece: nil },
70
- { x: 6, y: 3, piece: nil },
71
-
72
- { x: 1, y: 4, piece: nil },
73
- { x: 3, y: 4, piece: nil },
74
- { x: 5, y: 4, piece: nil },
75
- { x: 7, y: 4, piece: nil },
76
-
77
- { x: 0, y: 5, piece: { player_number: 2, direction: -1, king: false }},
78
- { x: 2, y: 5, piece: { player_number: 2, direction: -1, king: false }},
79
- { x: 4, y: 5, piece: { player_number: 2, direction: -1, king: false }},
80
- { x: 6, y: 5, piece: { player_number: 2, direction: -1, king: false }},
81
-
82
- { x: 1, y: 6, piece: { player_number: 2, direction: -1, king: false }},
83
- { x: 3, y: 6, piece: { player_number: 2, direction: -1, king: false }},
84
- { x: 5, y: 6, piece: { player_number: 2, direction: -1, king: false }},
85
- { x: 7, y: 6, piece: { player_number: 2, direction: -1, king: false }},
86
-
87
- { x: 0, y: 7, piece: { player_number: 2, direction: -1, king: false }},
88
- { x: 2, y: 7, piece: { player_number: 2, direction: -1, king: false }},
89
- { x: 4, y: 7, piece: { player_number: 2, direction: -1, king: false }},
90
- { x: 6, y: 7, piece: { player_number: 2, direction: -1, king: false }},
56
+ { id: 1, x: 1, y: 0, piece: { player_number: 1, direction: 1, king: false }},
57
+ { id: 2, x: 3, y: 0, piece: { player_number: 1, direction: 1, king: false }},
58
+ { id: 3, x: 5, y: 0, piece: { player_number: 1, direction: 1, king: false }},
59
+ { id: 4, x: 7, y: 0, piece: { player_number: 1, direction: 1, king: false }},
60
+
61
+ { id: 5, x: 0, y: 1, piece: { player_number: 1, direction: 1, king: false }},
62
+ { id: 6, x: 2, y: 1, piece: { player_number: 1, direction: 1, king: false }},
63
+ { id: 7, x: 4, y: 1, piece: { player_number: 1, direction: 1, king: false }},
64
+ { id: 8, x: 6, y: 1, piece: { player_number: 1, direction: 1, king: false }},
65
+
66
+ { id: 9, x: 1, y: 2, piece: { player_number: 1, direction: 1, king: false }},
67
+ { id: 10, x: 3, y: 2, piece: { player_number: 1, direction: 1, king: false }},
68
+ { id: 11, x: 5, y: 2, piece: { player_number: 1, direction: 1, king: false }},
69
+ { id: 12, x: 7, y: 2, piece: { player_number: 1, direction: 1, king: false }},
70
+
71
+ { id: 13, x: 0, y: 3, piece: nil },
72
+ { id: 14, x: 2, y: 3, piece: nil },
73
+ { id: 15, x: 4, y: 3, piece: nil },
74
+ { id: 16, x: 6, y: 3, piece: nil },
75
+
76
+ { id: 17, x: 1, y: 4, piece: nil },
77
+ { id: 18, x: 3, y: 4, piece: nil },
78
+ { id: 19, x: 5, y: 4, piece: nil },
79
+ { id: 20, x: 7, y: 4, piece: nil },
80
+
81
+ { id: 21, x: 0, y: 5, piece: { player_number: 2, direction: -1, king: false }},
82
+ { id: 22, x: 2, y: 5, piece: { player_number: 2, direction: -1, king: false }},
83
+ { id: 23, x: 4, y: 5, piece: { player_number: 2, direction: -1, king: false }},
84
+ { id: 24, x: 6, y: 5, piece: { player_number: 2, direction: -1, king: false }},
85
+
86
+ { id: 25, x: 1, y: 6, piece: { player_number: 2, direction: -1, king: false }},
87
+ { id: 26, x: 3, y: 6, piece: { player_number: 2, direction: -1, king: false }},
88
+ { id: 27, x: 5, y: 6, piece: { player_number: 2, direction: -1, king: false }},
89
+ { id: 28, x: 7, y: 6, piece: { player_number: 2, direction: -1, king: false }},
90
+
91
+ { id: 29, x: 0, y: 7, piece: { player_number: 2, direction: -1, king: false }},
92
+ { id: 30, x: 2, y: 7, piece: { player_number: 2, direction: -1, king: false }},
93
+ { id: 31, x: 4, y: 7, piece: { player_number: 2, direction: -1, king: false }},
94
+ { id: 32, x: 6, y: 7, piece: { player_number: 2, direction: -1, king: false }},
91
95
  ]
92
96
  })
93
97
  end
@@ -127,23 +131,34 @@ module JustCheckers
127
131
  # @param [Fixnum] player_number
128
132
  # the player number, 1 or 2.
129
133
  #
130
- # @param [Hash] from
134
+ # @param [Hash, Fixnum] from
131
135
  # where the moving piece currently is.
132
136
  #
133
- # @param [Array<Hash>] to
137
+ # @param [Array<Hash>, Array<Fixnum>] to
134
138
  # each place the piece is going to move to.
135
139
  #
136
140
  # @return [Boolean]
137
141
  def move(player_number, from, to)
138
142
  @errors = []
139
- from_square = squares.find_by_x_and_y(from[:x].to_i, from[:y].to_i)
140
- to_squares = to.map { |s| squares.find_by_x_and_y(s[:x].to_i, s[:y].to_i) }
143
+
144
+ from_square = if from.is_a?(Hash)
145
+ squares.find_by_x_and_y(from[:x].to_i, from[:y].to_i)
146
+ else
147
+ squares.find_by_id(from.to_i)
148
+ end
149
+
150
+ to_squares = if to.all? { |s| s.is_a?(Hash) }
151
+ to.map { |position| squares.find_by_x_and_y(position[:x].to_i, position[:y].to_i) }
152
+ else
153
+ to.map { |id| squares.find_by_id(id) }
154
+ end
141
155
 
142
156
  if player_number != current_player_number
143
157
  @errors.push NotPlayersTurnError.new
144
158
  elsif move_valid?(from_square, to_squares)
159
+ @last_change = { type: 'move', data: {player_number: player_number, from: from, to: to} }
145
160
  perform_move(from_square, to_squares)
146
- promote(to_squares.last) if promotable?(to_squares.last)
161
+ to_squares.last.promote if to_squares.last.promotable?
147
162
  turn
148
163
  end
149
164
 
@@ -171,14 +186,10 @@ module JustCheckers
171
186
  @errors.empty?
172
187
  end
173
188
 
174
- def promote(square) # :nodoc:
175
- square.piece.promote
176
- end
177
-
178
189
  def perform_move(from, to) # :nodoc:
179
190
  legs = to.unshift(from)
180
- legs.each_cons(2) do |a, b|
181
- between_square = squares.between(a, b).first
191
+ legs.each_cons(2) do |origin, destination|
192
+ between_square = squares.between(origin, destination).first
182
193
  between_square.piece = nil if between_square
183
194
  end
184
195
 
@@ -197,17 +208,5 @@ module JustCheckers
197
208
  def no_pieces_for_player?(player_number) # :nodoc:
198
209
  squares.occupied_by(player_number).none? { |s| s.possible_jumps(s.piece, squares).any? || s.possible_moves(s.piece, squares).any? }
199
210
  end
200
-
201
- def promotable?(square) # :nodoc:
202
- case square.piece.direction
203
- when 1
204
- square.y == 7
205
- when -1
206
- square.y == 0
207
- else
208
- false
209
- end
210
- end
211
-
212
211
  end
213
212
  end
@@ -10,6 +10,9 @@ module JustCheckers
10
10
 
11
11
  # New objects can be instantiated by passing in a hash with
12
12
  #
13
+ # @param [Fixnum] id
14
+ # the unique identifier of the square.
15
+ #
13
16
  # @param [Fixnum] x
14
17
  # the x co-ordinate of the square.
15
18
  #
@@ -22,11 +25,13 @@ module JustCheckers
22
25
  # ==== Example:
23
26
  # # Instantiates a new Square
24
27
  # JustCheckers::Square.new({
28
+ # id: 1,
25
29
  # x: 1,
26
30
  # y: 0,
27
31
  # piece: { player_number: 1, direction: 1, king: false }
28
32
  # })
29
- def initialize(x: , y: , piece: nil)
33
+ def initialize(id: , x: , y: , piece: nil)
34
+ @id = id
30
35
  @x = x
31
36
  @y = y
32
37
  @piece = if piece.is_a?(Hash)
@@ -36,6 +41,9 @@ module JustCheckers
36
41
  end
37
42
  end
38
43
 
44
+ # @return [Fixnum] the unique identifier of the square.
45
+ attr_reader :id
46
+
39
47
  # @return [Fixnum] the x co-ordinate of the square.
40
48
  attr_reader :x
41
49
 
@@ -111,11 +119,32 @@ module JustCheckers
111
119
  squares.one_square_away_from(self).in_direction_of(piece, self).unoccupied
112
120
  end
113
121
 
122
+ # Checks if the piece on the square can promote.
123
+ #
124
+ # @return [Boolean]
125
+ def promotable?
126
+ case piece && piece.direction
127
+ when 1
128
+ y == 7
129
+ when -1
130
+ y == 0
131
+ else
132
+ false
133
+ end
134
+ end
135
+
136
+ # Promotes the piece if the piece exists.
137
+ #
138
+ # @return [Boolean]
139
+ def promote
140
+ piece && piece.promote
141
+ end
142
+
114
143
  # A serialized version of the square as a hash
115
144
  #
116
145
  # @return [Hash]
117
146
  def as_json
118
- { x: x, y: y, piece: piece && piece.as_json }
147
+ { id: id, x: x, y: y, piece: piece && piece.as_json }
119
148
  end
120
149
  end
121
- end
150
+ end
@@ -67,8 +67,8 @@ module JustCheckers
67
67
  # # Find all squares where piece is nil
68
68
  # square_set.where(piece: nil)
69
69
  def where(hash)
70
- res = hash.inject(squares) do |memo, (k, v)|
71
- memo.select { |s| s.attribute_match?(k, v) }
70
+ res = hash.inject(squares) do |memo, (attribute, value)|
71
+ memo.select { |square| square.attribute_match?(attribute, value) }
72
72
  end
73
73
  self.class.new(squares: res)
74
74
  end
@@ -89,6 +89,19 @@ module JustCheckers
89
89
  select { |s| s.x == x && s.y == y }.first
90
90
  end
91
91
 
92
+ # Find the square with the matching unique identifier
93
+ #
94
+ # @param [Fixnum] id
95
+ # the unique identifier.
96
+ #
97
+ # @return [Square]
98
+ # ==== Example:
99
+ # # Find the square with id 4
100
+ # square_set.find_by_id(4)
101
+ def find_by_id(id)
102
+ select { |s| s.id == id }.first
103
+ end
104
+
92
105
  # Return all squares that are one square away from the passed square.
93
106
  #
94
107
  # @param [Square] square
@@ -134,7 +147,7 @@ module JustCheckers
134
147
  #
135
148
  # @return [SquareSet]
136
149
  def unoccupied
137
- select { |s| s.piece.nil? }
150
+ select(&:unoccupied?)
138
151
  end
139
152
 
140
153
  # Returns squares between a and b.
@@ -1,4 +1,4 @@
1
1
  module JustCheckers
2
2
  # :nodoc:
3
- VERSION = "0.2.0"
3
+ VERSION = "0.3.0"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: just_checkers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Humphreys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-11 00:00:00.000000000 Z
11
+ date: 2016-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,4 +108,3 @@ signing_key:
108
108
  specification_version: 4
109
109
  summary: A checkers engine written in ruby
110
110
  test_files: []
111
- has_rdoc: