just_checkers 0.1.3 → 0.2.0
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/README.md +3 -3
- data/just_checkers.gemspec +1 -1
- data/lib/just_checkers.rb +1 -0
- data/lib/just_checkers/errors/empty_square_error.rb +22 -0
- data/lib/just_checkers/errors/error.rb +20 -0
- data/lib/just_checkers/errors/invalid_move_error.rb +22 -0
- data/lib/just_checkers/errors/not_players_turn_error.rb +22 -0
- data/lib/just_checkers/errors/piece_must_capture_error.rb +22 -0
- data/lib/just_checkers/game_state.rb +40 -46
- data/lib/just_checkers/piece.rb +4 -7
- data/lib/just_checkers/point.rb +1 -1
- data/lib/just_checkers/square.rb +3 -6
- data/lib/just_checkers/square_set.rb +1 -4
- data/lib/just_checkers/version.rb +2 -1
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 404c68f0f2336d1e7082534610f59f9a82dfe427
|
4
|
+
data.tar.gz: af653b067e74d1e31d4f97a5bccaef45b4c78e4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
29
|
+
game_state.move(1, {x: 1, y: 2}, [{x: 2, y: 3}])
|
30
30
|
```
|
31
31
|
|
32
|
-
If something happens
|
32
|
+
If something happens errors may be found in the errors attribute
|
33
33
|
|
34
34
|
```ruby
|
35
|
-
game_state.
|
35
|
+
game_state.errors
|
36
36
|
```
|
37
37
|
|
38
38
|
The Winner can be found by calling winner on the object.
|
data/just_checkers.gemspec
CHANGED
@@ -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 = '
|
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
@@ -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 [
|
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
|
-
# @
|
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
|
-
@
|
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<
|
42
|
-
attr_reader :
|
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
|
109
|
+
if no_pieces_for_player?(1)
|
109
110
|
2
|
110
|
-
elsif
|
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
|
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
|
137
|
-
@
|
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 { |
|
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
|
-
@
|
143
|
-
|
144
|
-
|
145
|
-
if
|
146
|
-
|
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
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
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
|
-
|
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
|
-
@
|
180
|
-
false
|
168
|
+
@errors.push EmptySquareError.new
|
181
169
|
end
|
170
|
+
|
171
|
+
@errors.empty?
|
182
172
|
end
|
183
173
|
|
184
|
-
def promote
|
185
|
-
square.piece.promote
|
174
|
+
def promote(square) # :nodoc:
|
175
|
+
square.piece.promote
|
186
176
|
end
|
187
177
|
|
188
|
-
def perform_move
|
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
|
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
|
data/lib/just_checkers/piece.rb
CHANGED
@@ -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 [
|
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
|
-
# @
|
12
|
+
# @param [Fixnum] direction
|
16
13
|
# the direction forward on the board, 1 for moving down, -1 for moving up.
|
17
14
|
#
|
18
|
-
# @option
|
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
|
|
data/lib/just_checkers/point.rb
CHANGED
data/lib/just_checkers/square.rb
CHANGED
@@ -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 [
|
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
|
-
# @
|
16
|
+
# @param [Fixnum] y
|
20
17
|
# the y co-ordinate of the square.
|
21
18
|
#
|
22
|
-
# @option
|
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]
|
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:
|
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.
|
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-
|
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:
|