just_checkers 0.1.3 → 0.2.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: 9f9a84872947e5dddb0826c13edd669786b581fe
4
- data.tar.gz: 34a9dbadce0fc0b47e8d564fbb0888a342ae093c
3
+ metadata.gz: 404c68f0f2336d1e7082534610f59f9a82dfe427
4
+ data.tar.gz: af653b067e74d1e31d4f97a5bccaef45b4c78e4a
5
5
  SHA512:
6
- metadata.gz: fd608fe24b0e129f86a580c24902340b6119da7962aafcec9f75cae7b55b72b6f628284823e4f9cfe068d143e7dc9bd4115cf16f50f14c80bf9c1c2a3099b9ae
7
- data.tar.gz: d252d1405ea6fca132d01d379a0ad5ecafe34a3549a97d03b2dcbb6c7ca74fb170d4619895aa80868b664c202840666b6acd7e9471534694a9c5b44b4f3499dd
6
+ metadata.gz: 9088167eaa8e61a7c0fcbc2a45ecddce41c845810471fa593e3e84668e75b37a9cab2326f80fa0bd2c8cf85b1bffc01588beb802156de686ff52ef2765077a39
7
+ data.tar.gz: fd1903da0c448ac2208cd44232a0722b23f0e9e7356a68039c9bb702809538a668744155bd2ba28182521ed75e9d947017e66aba914b2bd4d5ca89dcb92d481a
data/README.md CHANGED
@@ -26,13 +26,13 @@ Moves can be made by passing in the player number, from co-ordinates and an arra
26
26
 
27
27
 
28
28
  ```ruby
29
- game_state.move!(1, {x: 1, y: 2}, [{x: 2, y: 3}])
29
+ game_state.move(1, {x: 1, y: 2}, [{x: 2, y: 3}])
30
30
  ```
31
31
 
32
- If something happens a message may be found in the messages attribute
32
+ If something happens errors may be found in the errors attribute
33
33
 
34
34
  ```ruby
35
- game_state.messages
35
+ game_state.errors
36
36
  ```
37
37
 
38
38
  The Winner can be found by calling winner on the object.
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.required_ruby_version = '~> 2.1'
22
+ spec.required_ruby_version = '>= 2.1'
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.11"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
data/lib/just_checkers.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "just_checkers/version"
2
2
 
3
+ # :nodoc:
3
4
  module JustCheckers
4
5
 
5
6
  end
@@ -0,0 +1,22 @@
1
+ require 'just_checkers/errors/error'
2
+
3
+ module JustCheckers
4
+
5
+ # = EmptySquareError
6
+ #
7
+ # An empty square error with a message
8
+ class EmptySquareError < Error
9
+
10
+ # New empty square errors can be instantiated with
11
+ #
12
+ # @option [String] message
13
+ # the x co-ordinate.
14
+ #
15
+ # ==== Example:
16
+ # # Instantiates a new EmptySquareError
17
+ # JustCheckers::EmptySquareError.new("Custom Message")
18
+ def initialize(message="Square is empty.")
19
+ super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module JustCheckers
2
+
3
+ # = Error
4
+ #
5
+ # An error with a message
6
+ class Error
7
+
8
+ # New errors can be instantiated with
9
+ #
10
+ # @option [String] message
11
+ # the x co-ordinate.
12
+ #
13
+ # ==== Example:
14
+ # # Instantiates a new Error
15
+ # JustCheckers::Error.new("Custom Message")
16
+ def initialize(message="Generic Error")
17
+ @message = message
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ require 'just_checkers/errors/error'
2
+
3
+ module JustCheckers
4
+
5
+ # = InvalidMoveError
6
+ #
7
+ # An invalid move error with a message
8
+ class InvalidMoveError < Error
9
+
10
+ # New invalid move errors can be instantiated with
11
+ #
12
+ # @option [String] message
13
+ # the x co-ordinate.
14
+ #
15
+ # ==== Example:
16
+ # # Instantiates a new InvalidMoveError
17
+ # JustCheckers::InvalidMoveError.new("Custom Message")
18
+ def initialize(message="Move is invalid.")
19
+ super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'just_checkers/errors/error'
2
+
3
+ module JustCheckers
4
+
5
+ # = NotPlayersTurnError
6
+ #
7
+ # A not players turn error with a message
8
+ class NotPlayersTurnError < Error
9
+
10
+ # New not players turn errors can be instantiated with
11
+ #
12
+ # @option [String] message
13
+ # the x co-ordinate.
14
+ #
15
+ # ==== Example:
16
+ # # Instantiates a new NotPlayersTurnError
17
+ # JustCheckers::NotPlayersTurnError.new("Custom Message")
18
+ def initialize(message="It is not the player's turn yet.")
19
+ super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'just_checkers/errors/error'
2
+
3
+ module JustCheckers
4
+
5
+ # = PieceMustCaptureError
6
+ #
7
+ # A piece must capture error with a message
8
+ class PieceMustCaptureError < Error
9
+
10
+ # New piece must capture errors can be instantiated with
11
+ #
12
+ # @option [String] message
13
+ # the x co-ordinate.
14
+ #
15
+ # ==== Example:
16
+ # # Instantiates a new PieceMustCaptureError
17
+ # JustCheckers::PieceMustCaptureError.new("Custom Message")
18
+ def initialize(message="Another piece must capture first.")
19
+ super
20
+ end
21
+ end
22
+ end
@@ -1,4 +1,8 @@
1
1
  require 'just_checkers/square_set'
2
+ require 'just_checkers/errors/not_players_turn_error'
3
+ require 'just_checkers/errors/piece_must_capture_error'
4
+ require 'just_checkers/errors/invalid_move_error'
5
+ require 'just_checkers/errors/empty_square_error'
2
6
 
3
7
  module JustCheckers
4
8
 
@@ -9,13 +13,10 @@ module JustCheckers
9
13
 
10
14
  # New objects can be instantiated.
11
15
  #
12
- # @param [Hash] args
13
- # The data needed for a game
14
- #
15
- # @option args [Fixnum] :current_player_number
16
+ # @param [Fixnum] current_player_number
16
17
  # Who's turn it is, 1 or 2
17
18
  #
18
- # @option args [Array<Square>] :squares
19
+ # @param [Array<Square>] squares
19
20
  # An array of squares, each with x and y co-ordinates and a piece.
20
21
  #
21
22
  # ==== Example:
@@ -29,7 +30,7 @@ module JustCheckers
29
30
  def initialize(current_player_number: , squares: [])
30
31
  @current_player_number = current_player_number
31
32
  @squares = SquareSet.new(squares: squares)
32
- @messages = []
33
+ @errors = []
33
34
  end
34
35
 
35
36
  # @return [Fixnum] who's turn it is.
@@ -38,8 +39,8 @@ module JustCheckers
38
39
  # @return [Array<Square>] the board state.
39
40
  attr_reader :squares
40
41
 
41
- # @return [Array<String>] useful messages if any.
42
- attr_reader :messages
42
+ # @return [Array<Error>] errors if any.
43
+ attr_reader :errors
43
44
 
44
45
  # Instantiates a new GameState object in the starting position
45
46
  #
@@ -105,9 +106,9 @@ module JustCheckers
105
106
  #
106
107
  # @return [Fixnum,NilClass]
107
108
  def winner
108
- if squares.occupied_by(1).none? { |s| s.possible_jumps(s.piece, squares).any? || s.possible_moves(s.piece, squares).any? }
109
+ if no_pieces_for_player?(1)
109
110
  2
110
- elsif squares.occupied_by(2).none? { |s| s.possible_jumps(s.piece, squares).any? || s.possible_moves(s.piece, squares).any? }
111
+ elsif no_pieces_for_player?(2)
111
112
  1
112
113
  else
113
114
  nil
@@ -121,7 +122,7 @@ module JustCheckers
121
122
  #
122
123
  # ==== Example:
123
124
  # # Moves a piece from a square to perform a double jump
124
- # game_state.move!(1, {x: 0, y: 1}, [{x: 1, y: 2}, {x: 3, y: 4}])
125
+ # game_state.move(1, {x: 0, y: 1}, [{x: 1, y: 2}, {x: 3, y: 4}])
125
126
  #
126
127
  # @param [Fixnum] player_number
127
128
  # the player number, 1 or 2.
@@ -133,59 +134,48 @@ module JustCheckers
133
134
  # each place the piece is going to move to.
134
135
  #
135
136
  # @return [Boolean]
136
- def move!(player_number, from, to)
137
- @messages = []
137
+ def move(player_number, from, to)
138
+ @errors = []
138
139
  from_square = squares.find_by_x_and_y(from[:x].to_i, from[:y].to_i)
139
- to_squares = to.map { |p| squares.find_by_x_and_y(p[:x].to_i, p[:y].to_i) }
140
+ to_squares = to.map { |s| squares.find_by_x_and_y(s[:x].to_i, s[:y].to_i) }
140
141
 
141
142
  if player_number != current_player_number
142
- @messages.push("It is not that player's turn.")
143
- false
144
- else
145
- if move_valid?(from_square, to_squares)
146
- perform_move!(from_square, to_squares)
147
- promote!(to_squares.last) if promotable?(to_squares.last)
148
- turn!
149
- true
150
- else
151
- false
152
- end
143
+ @errors.push NotPlayersTurnError.new
144
+ elsif move_valid?(from_square, to_squares)
145
+ perform_move(from_square, to_squares)
146
+ promote(to_squares.last) if promotable?(to_squares.last)
147
+ turn
153
148
  end
149
+
150
+ @errors.empty?
154
151
  end
155
152
 
156
153
  private
157
154
 
158
155
  def move_valid?(from, to) # :nodoc:
159
156
  legs = to.unshift(from)
160
- if from && from.piece
161
- legs.each_cons(2).map do |a, b|
162
- if squares.occupied_by(from.piece.player_number).any? { |s| s.possible_jumps(s.piece, squares).any? }
163
- if a.possible_jumps(from.piece, squares).include?(b)
164
- true
165
- else
166
- @messages.push('Another piece must capture first.')
167
- false
168
- end
157
+ from_piece = from && from.piece
158
+
159
+ if from_piece
160
+ legs.each_cons(2).map do |origin, destination|
161
+ if squares.occupied_by(from_piece.player_number).any? { |s| s.possible_jumps(s.piece, squares).any? }
162
+ @errors.push(PieceMustCaptureError.new) unless origin.possible_jumps(from_piece, squares).include?(destination)
169
163
  else
170
- if a.possible_moves(from.piece, squares).include?(b)
171
- true
172
- else
173
- @messages.push('That piece cannot move like that.')
174
- false
175
- end
164
+ @errors.push(InvalidMoveError.new) unless origin.possible_moves(from_piece, squares).include?(destination)
176
165
  end
177
166
  end.all?
178
167
  else
179
- @messages.push('There is no piece there.')
180
- false
168
+ @errors.push EmptySquareError.new
181
169
  end
170
+
171
+ @errors.empty?
182
172
  end
183
173
 
184
- def promote!(square) # :nodoc:
185
- square.piece.promote!
174
+ def promote(square) # :nodoc:
175
+ square.piece.promote
186
176
  end
187
177
 
188
- def perform_move!(from, to) # :nodoc:
178
+ def perform_move(from, to) # :nodoc:
189
179
  legs = to.unshift(from)
190
180
  legs.each_cons(2) do |a, b|
191
181
  between_square = squares.between(a, b).first
@@ -196,7 +186,7 @@ module JustCheckers
196
186
  from.piece = nil
197
187
  end
198
188
 
199
- def turn! # :nodoc:
189
+ def turn # :nodoc:
200
190
  @current_player_number = other_player_number
201
191
  end
202
192
 
@@ -204,6 +194,10 @@ module JustCheckers
204
194
  current_player_number == 1 ? 2 : 1
205
195
  end
206
196
 
197
+ def no_pieces_for_player?(player_number) # :nodoc:
198
+ squares.occupied_by(player_number).none? { |s| s.possible_jumps(s.piece, squares).any? || s.possible_moves(s.piece, squares).any? }
199
+ end
200
+
207
201
  def promotable?(square) # :nodoc:
208
202
  case square.piece.direction
209
203
  when 1
@@ -6,16 +6,13 @@ module JustCheckers
6
6
 
7
7
  # New objects can be instantiated by passing in a hash with
8
8
  #
9
- # @param [Hash] args
10
- # The data needed for a piece
11
- #
12
- # @option args [Fixnum] player_number
9
+ # @param [Fixnum] player_number
13
10
  # the owner of the piece.
14
11
  #
15
- # @option args [Fixnum] direction
12
+ # @param [Fixnum] direction
16
13
  # the direction forward on the board, 1 for moving down, -1 for moving up.
17
14
  #
18
- # @option args [Boolean] king
15
+ # @option [Boolean] king
19
16
  # set to true if the piece has been crowned.
20
17
  #
21
18
  # ==== Example:
@@ -45,7 +42,7 @@ module JustCheckers
45
42
  # promotes the piece by setting the +king+ attribute to true.
46
43
  #
47
44
  # @return [TrueClass]
48
- def promote!
45
+ def promote
49
46
  @king = true
50
47
  end
51
48
 
@@ -25,7 +25,7 @@ module JustCheckers
25
25
 
26
26
  # @return [Fixnum] the x co-ordinate.
27
27
  attr_reader :x
28
-
28
+
29
29
  # @return [Fixnum] the y co-ordinate.
30
30
  attr_reader :y
31
31
 
@@ -10,16 +10,13 @@ module JustCheckers
10
10
 
11
11
  # New objects can be instantiated by passing in a hash with
12
12
  #
13
- # @param [Hash] args
14
- # The data needed for a square
15
- #
16
- # @option args [Fixnum] x
13
+ # @param [Fixnum] x
17
14
  # the x co-ordinate of the square.
18
15
  #
19
- # @option args [Fixnum] y
16
+ # @param [Fixnum] y
20
17
  # the y co-ordinate of the square.
21
18
  #
22
- # @option args [Piece,Hash,NilClass] piece
19
+ # @option [Piece,Hash,NilClass] piece
23
20
  # The piece on the square, can be a piece object or hash or nil.
24
21
  #
25
22
  # ==== Example:
@@ -13,10 +13,7 @@ module JustCheckers
13
13
  # New objects can be instantiated by passing in a hash with squares.
14
14
  # They can be square objects or hashes.
15
15
  #
16
- # @param [Hash] args
17
- # The data needed for the squares
18
- #
19
- # @option args [Array<Square,Hash>] squares
16
+ # @param [Array<Square,Hash>] squares
20
17
  # An array of squares, each with x and y co-ordinates and a piece.
21
18
  #
22
19
  # ==== Example:
@@ -1,3 +1,4 @@
1
1
  module JustCheckers
2
- VERSION = "0.1.3"
2
+ # :nodoc:
3
+ VERSION = "0.2.0"
3
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.1.3
4
+ version: 0.2.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-07-31 00:00:00.000000000 Z
11
+ date: 2016-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -71,6 +71,11 @@ files:
71
71
  - just_checkers.gemspec
72
72
  - lib/just_checkers.rb
73
73
  - lib/just_checkers/direction.rb
74
+ - lib/just_checkers/errors/empty_square_error.rb
75
+ - lib/just_checkers/errors/error.rb
76
+ - lib/just_checkers/errors/invalid_move_error.rb
77
+ - lib/just_checkers/errors/not_players_turn_error.rb
78
+ - lib/just_checkers/errors/piece_must_capture_error.rb
74
79
  - lib/just_checkers/game_state.rb
75
80
  - lib/just_checkers/piece.rb
76
81
  - lib/just_checkers/point.rb
@@ -88,7 +93,7 @@ require_paths:
88
93
  - lib
89
94
  required_ruby_version: !ruby/object:Gem::Requirement
90
95
  requirements:
91
- - - "~>"
96
+ - - ">="
92
97
  - !ruby/object:Gem::Version
93
98
  version: '2.1'
94
99
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -103,3 +108,4 @@ signing_key:
103
108
  specification_version: 4
104
109
  summary: A checkers engine written in ruby
105
110
  test_files: []
111
+ has_rdoc: