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 +4 -4
- data/README.md +12 -0
- data/Rakefile +1 -0
- data/lib/just_checkers/game_state.rb +61 -62
- data/lib/just_checkers/square.rb +32 -3
- data/lib/just_checkers/square_set.rb +16 -3
- data/lib/just_checkers/version.rb +1 -1
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60946aa3db499cb440fd0c2d9979c86f76d535d3
|
4
|
+
data.tar.gz: 58d674537166da0ad642230543b5911e1cfa558f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
@@ -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
|
-
|
140
|
-
|
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
|
-
|
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 |
|
181
|
-
between_square = squares.between(
|
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
|
data/lib/just_checkers/square.rb
CHANGED
@@ -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, (
|
71
|
-
memo.select { |
|
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
|
150
|
+
select(&:unoccupied?)
|
138
151
|
end
|
139
152
|
|
140
153
|
# Returns squares between a and b.
|
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.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-
|
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:
|