just_shogi 0.1.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 +7 -0
- data/.gitignore +8 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +21 -0
- data/README.md +80 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/just_shogi.gemspec +29 -0
- data/lib/just_shogi.rb +8 -0
- data/lib/just_shogi/errors/causes_check_error.rb +22 -0
- data/lib/just_shogi/errors/dropped_into_check_error.rb +22 -0
- data/lib/just_shogi/errors/error.rb +20 -0
- data/lib/just_shogi/errors/invalid_move_error.rb +22 -0
- data/lib/just_shogi/errors/invalid_promotion_error.rb +22 -0
- data/lib/just_shogi/errors/moved_into_check_error.rb +22 -0
- data/lib/just_shogi/errors/no_piece_error.rb +22 -0
- data/lib/just_shogi/errors/not_players_turn_error.rb +22 -0
- data/lib/just_shogi/errors/off_board_error.rb +22 -0
- data/lib/just_shogi/errors/piece_not_found_error.rb +22 -0
- data/lib/just_shogi/errors/square_occupied_error.rb +22 -0
- data/lib/just_shogi/game_state.rb +355 -0
- data/lib/just_shogi/hand.rb +48 -0
- data/lib/just_shogi/piece_factory.rb +87 -0
- data/lib/just_shogi/pieces/fuhyou.rb +23 -0
- data/lib/just_shogi/pieces/ginshou.rb +23 -0
- data/lib/just_shogi/pieces/gyokushou.rb +9 -0
- data/lib/just_shogi/pieces/hisha.rb +23 -0
- data/lib/just_shogi/pieces/kakugyou.rb +23 -0
- data/lib/just_shogi/pieces/keima.rb +23 -0
- data/lib/just_shogi/pieces/kin_base.rb +23 -0
- data/lib/just_shogi/pieces/kinshou.rb +9 -0
- data/lib/just_shogi/pieces/kyousha.rb +23 -0
- data/lib/just_shogi/pieces/narigin.rb +9 -0
- data/lib/just_shogi/pieces/narikei.rb +9 -0
- data/lib/just_shogi/pieces/narikyou.rb +9 -0
- data/lib/just_shogi/pieces/ou_base.rb +70 -0
- data/lib/just_shogi/pieces/oushou.rb +9 -0
- data/lib/just_shogi/pieces/piece.rb +18 -0
- data/lib/just_shogi/pieces/ryuuma.rb +23 -0
- data/lib/just_shogi/pieces/ryuuou.rb +23 -0
- data/lib/just_shogi/pieces/tokin.rb +9 -0
- data/lib/just_shogi/promotion_factory.rb +71 -0
- data/lib/just_shogi/square.rb +51 -0
- data/lib/just_shogi/square_set.rb +64 -0
- data/lib/just_shogi/version.rb +3 -0
- metadata +147 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'board_game_grid'
|
2
|
+
|
3
|
+
module JustShogi
|
4
|
+
|
5
|
+
# = Piece
|
6
|
+
#
|
7
|
+
# A piece that can move on a chess board
|
8
|
+
class Piece < BoardGameGrid::Piece
|
9
|
+
def initialize(id: , player_number: , type: nil)
|
10
|
+
@id = id
|
11
|
+
@player_number = player_number
|
12
|
+
end
|
13
|
+
|
14
|
+
def switch_player
|
15
|
+
@player_number = opponent
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'just_shogi/pieces/piece'
|
2
|
+
|
3
|
+
module JustShogi
|
4
|
+
|
5
|
+
# = Ryuuma
|
6
|
+
#
|
7
|
+
# The piece that moves diagonally any number of squares and 1 space orthogonally
|
8
|
+
class Ryuuma < Piece
|
9
|
+
|
10
|
+
# All the squares that the piece can move to and/or capture.
|
11
|
+
#
|
12
|
+
# @param [Square] square
|
13
|
+
# the origin square.
|
14
|
+
#
|
15
|
+
# @param [GameState] game_state
|
16
|
+
# the current game state.
|
17
|
+
#
|
18
|
+
# @return [SquareSet]
|
19
|
+
def destinations(square, game_state)
|
20
|
+
(game_state.squares.diagonal(square) | game_state.squares.at_range(square, 1)).unoccupied_or_occupied_by_opponent(player_number).unblocked(square, game_state.squares)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'just_shogi/pieces/piece'
|
2
|
+
|
3
|
+
module JustShogi
|
4
|
+
|
5
|
+
# = Ryuuou
|
6
|
+
#
|
7
|
+
# The piece that moves any number of squares orthogonally and 1 space diagonally.
|
8
|
+
class Ryuuou < Piece
|
9
|
+
|
10
|
+
# All the squares that the piece can move to and/or capture.
|
11
|
+
#
|
12
|
+
# @param [Square] square
|
13
|
+
# the origin square.
|
14
|
+
#
|
15
|
+
# @param [GameState] game_state
|
16
|
+
# the current game state.
|
17
|
+
#
|
18
|
+
# @return [SquareSet]
|
19
|
+
def destinations(square, game_state)
|
20
|
+
(game_state.squares.orthogonal(square) | game_state.squares.at_range(square, 1)).unoccupied_or_occupied_by_opponent(player_number).unblocked(square, game_state.squares)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'just_shogi/pieces/fuhyou'
|
2
|
+
require 'just_shogi/pieces/kakugyou'
|
3
|
+
require 'just_shogi/pieces/hisha'
|
4
|
+
require 'just_shogi/pieces/kyousha'
|
5
|
+
require 'just_shogi/pieces/keima'
|
6
|
+
require 'just_shogi/pieces/ginshou'
|
7
|
+
require 'just_shogi/pieces/kinshou'
|
8
|
+
require 'just_shogi/pieces/oushou'
|
9
|
+
require 'just_shogi/pieces/gyokushou'
|
10
|
+
|
11
|
+
require 'just_shogi/pieces/tokin'
|
12
|
+
require 'just_shogi/pieces/narikyou'
|
13
|
+
require 'just_shogi/pieces/narikei'
|
14
|
+
require 'just_shogi/pieces/narigin'
|
15
|
+
require 'just_shogi/pieces/ryuuma'
|
16
|
+
require 'just_shogi/pieces/ryuuou'
|
17
|
+
|
18
|
+
module JustShogi
|
19
|
+
|
20
|
+
# = Promotion Factory
|
21
|
+
#
|
22
|
+
# Generates the promoted or demoted piece given a piece
|
23
|
+
class PromotionFactory
|
24
|
+
|
25
|
+
# A mapping of promotions
|
26
|
+
PROMOTIONS = {
|
27
|
+
Fuhyou => Tokin,
|
28
|
+
Kakugyou => Ryuuma,
|
29
|
+
Hisha => Ryuuou,
|
30
|
+
Kyousha => Narikyou,
|
31
|
+
Keima => Narikei,
|
32
|
+
Ginshou => Narigin
|
33
|
+
}
|
34
|
+
|
35
|
+
# New objects can be instantiated by passing in the piece
|
36
|
+
#
|
37
|
+
# @params [Piece] piece
|
38
|
+
# the piece to be promoted
|
39
|
+
def initialize(piece)
|
40
|
+
@piece = piece
|
41
|
+
end
|
42
|
+
|
43
|
+
def promotable?
|
44
|
+
!PROMOTIONS[@piece.class].nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
def demotable?
|
48
|
+
!PROMOTIONS.key(@piece.class).nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the promoted piece
|
52
|
+
def promote
|
53
|
+
promoted_klass = PROMOTIONS[@piece.class]
|
54
|
+
if promoted_klass
|
55
|
+
promoted_klass.new(id: @piece.id, player_number: @piece.player_number)
|
56
|
+
else
|
57
|
+
raise ArgumentError, "Piece cannot be promoted."
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the demoted piece
|
62
|
+
def demote
|
63
|
+
demoted_klass = PROMOTIONS.key(@piece.class)
|
64
|
+
if demoted_klass
|
65
|
+
demoted_klass.new(id: @piece.id, player_number: @piece.player_number)
|
66
|
+
else
|
67
|
+
raise ArgumentError, "Piece cannot be demoted."
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'just_shogi/piece_factory'
|
2
|
+
require 'board_game_grid'
|
3
|
+
|
4
|
+
module JustShogi
|
5
|
+
|
6
|
+
# = Square
|
7
|
+
#
|
8
|
+
# A Square on a shogi board.
|
9
|
+
class Square < BoardGameGrid::Square
|
10
|
+
|
11
|
+
# New object can be instantiated by passing in a hash with
|
12
|
+
#
|
13
|
+
# @param [String] id
|
14
|
+
# the unique identifier of the square.
|
15
|
+
#
|
16
|
+
# @param [Fixnum] x
|
17
|
+
# the x co-ordinate of the square.
|
18
|
+
#
|
19
|
+
# @param [Fixnum] y
|
20
|
+
# the y co-ordinate of the square.
|
21
|
+
#
|
22
|
+
# @option [Piece,Hash,NilClass] piece
|
23
|
+
# The piece on the square, can be a piece object or hash or nil.
|
24
|
+
#
|
25
|
+
# ==== Example:
|
26
|
+
# # Instantiates a new Square
|
27
|
+
# JustShogi::Square.new({
|
28
|
+
# id: '91',
|
29
|
+
# x: 0,
|
30
|
+
# y: 0,
|
31
|
+
# piece: { id: 1, player_number: 1, type: 'fuhyou' }
|
32
|
+
# })
|
33
|
+
def initialize(id: , x: , y: , piece: nil)
|
34
|
+
@id = id
|
35
|
+
@x = x
|
36
|
+
@y = y
|
37
|
+
@piece = PieceFactory.new(piece).build
|
38
|
+
end
|
39
|
+
|
40
|
+
def promotion_zone(player_number)
|
41
|
+
case player_number
|
42
|
+
when 1
|
43
|
+
(0..2).include?(y)
|
44
|
+
when 2
|
45
|
+
(6..8).include?(y)
|
46
|
+
else
|
47
|
+
raise ArgumentError, "Invalid Player Number"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'just_shogi/square'
|
2
|
+
require 'board_game_grid'
|
3
|
+
|
4
|
+
module JustShogi
|
5
|
+
|
6
|
+
# = Square Set
|
7
|
+
#
|
8
|
+
# A collection of Squares with useful filtering functions
|
9
|
+
class SquareSet < BoardGameGrid::SquareSet
|
10
|
+
|
11
|
+
# New objects can be instantiated by passing in a hash with squares.
|
12
|
+
# They can be square objects or hashes.
|
13
|
+
#
|
14
|
+
# @param [Array<Square,Hash>] squares
|
15
|
+
# An array of squares, each with an x and y co-oordinates an a piece.
|
16
|
+
#
|
17
|
+
# ==== Example:
|
18
|
+
# # Instantiates a new Square Sete
|
19
|
+
# JustShogi::SquareSet.new({
|
20
|
+
# squares: [
|
21
|
+
# { id: '91', x: 0, y: 0, piece: { id: 1, player_number: 1, type: 'fuhyou' } }
|
22
|
+
# ]
|
23
|
+
# })
|
24
|
+
def initialize(squares: )
|
25
|
+
@squares = if squares.all? { |s| s.instance_of?(Hash) }
|
26
|
+
squares.map { |s| Square.new(**s) }
|
27
|
+
elsif squares.all? { |s| s.instance_of?(Square) }
|
28
|
+
squares
|
29
|
+
else
|
30
|
+
raise ArgumentError, "all squares must have the same class"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Find the square occupied by the player's king
|
35
|
+
#
|
36
|
+
# @param [Fixnum] player_number
|
37
|
+
# the number of the player
|
38
|
+
#
|
39
|
+
# @return [Square]
|
40
|
+
# ==== Example:
|
41
|
+
# # Find the square occupied by player 2's ou
|
42
|
+
# square_est.find_ou_for_player(2)
|
43
|
+
def find_ou_for_player(player_number)
|
44
|
+
find { |s| s.piece && s.piece.is_a?(JustShogi::OuBase) && s.occupied_by_player?(player_number) }
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns all squares threatened by the specified player
|
48
|
+
#
|
49
|
+
# @param [Fixnum] player_number
|
50
|
+
# the player's number.
|
51
|
+
#
|
52
|
+
# @param [GameState] game_state
|
53
|
+
# the current game state.
|
54
|
+
#
|
55
|
+
# @return [SquareSet]
|
56
|
+
def threatened_by(player_number, game_state)
|
57
|
+
_squares = occupied_by_player(player_number).map do |s|
|
58
|
+
s.piece.potential_capture_squares(s, game_state).squares
|
59
|
+
end.flatten.uniq
|
60
|
+
|
61
|
+
self.class.new(squares: _squares)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: just_shogi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Humphreys
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.1.4
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.1.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 13.0.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 13.0.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.14.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.14.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: board_game_grid
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.1.6
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.1.6
|
69
|
+
description: Provides a representation of a shogi game complete with rules enforcement
|
70
|
+
and serialisation.
|
71
|
+
email:
|
72
|
+
- mark@mrlhumphreys.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- CODE_OF_CONDUCT.md
|
79
|
+
- Gemfile
|
80
|
+
- Gemfile.lock
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- bin/console
|
85
|
+
- bin/setup
|
86
|
+
- just_shogi.gemspec
|
87
|
+
- lib/just_shogi.rb
|
88
|
+
- lib/just_shogi/errors/causes_check_error.rb
|
89
|
+
- lib/just_shogi/errors/dropped_into_check_error.rb
|
90
|
+
- lib/just_shogi/errors/error.rb
|
91
|
+
- lib/just_shogi/errors/invalid_move_error.rb
|
92
|
+
- lib/just_shogi/errors/invalid_promotion_error.rb
|
93
|
+
- lib/just_shogi/errors/moved_into_check_error.rb
|
94
|
+
- lib/just_shogi/errors/no_piece_error.rb
|
95
|
+
- lib/just_shogi/errors/not_players_turn_error.rb
|
96
|
+
- lib/just_shogi/errors/off_board_error.rb
|
97
|
+
- lib/just_shogi/errors/piece_not_found_error.rb
|
98
|
+
- lib/just_shogi/errors/square_occupied_error.rb
|
99
|
+
- lib/just_shogi/game_state.rb
|
100
|
+
- lib/just_shogi/hand.rb
|
101
|
+
- lib/just_shogi/piece_factory.rb
|
102
|
+
- lib/just_shogi/pieces/fuhyou.rb
|
103
|
+
- lib/just_shogi/pieces/ginshou.rb
|
104
|
+
- lib/just_shogi/pieces/gyokushou.rb
|
105
|
+
- lib/just_shogi/pieces/hisha.rb
|
106
|
+
- lib/just_shogi/pieces/kakugyou.rb
|
107
|
+
- lib/just_shogi/pieces/keima.rb
|
108
|
+
- lib/just_shogi/pieces/kin_base.rb
|
109
|
+
- lib/just_shogi/pieces/kinshou.rb
|
110
|
+
- lib/just_shogi/pieces/kyousha.rb
|
111
|
+
- lib/just_shogi/pieces/narigin.rb
|
112
|
+
- lib/just_shogi/pieces/narikei.rb
|
113
|
+
- lib/just_shogi/pieces/narikyou.rb
|
114
|
+
- lib/just_shogi/pieces/ou_base.rb
|
115
|
+
- lib/just_shogi/pieces/oushou.rb
|
116
|
+
- lib/just_shogi/pieces/piece.rb
|
117
|
+
- lib/just_shogi/pieces/ryuuma.rb
|
118
|
+
- lib/just_shogi/pieces/ryuuou.rb
|
119
|
+
- lib/just_shogi/pieces/tokin.rb
|
120
|
+
- lib/just_shogi/promotion_factory.rb
|
121
|
+
- lib/just_shogi/square.rb
|
122
|
+
- lib/just_shogi/square_set.rb
|
123
|
+
- lib/just_shogi/version.rb
|
124
|
+
homepage: https://github.com/mrlhumphreys/just_shogi
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
metadata: {}
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: 2.7.0
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubygems_version: 3.1.2
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: A Shogi engine written in ruby
|
147
|
+
test_files: []
|