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 +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:
|