qi 7.0.0 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +20 -23
  4. data/lib/qi/action.rb +61 -0
  5. data/lib/qi.rb +26 -57
  6. metadata +50 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18ca7bb7fca15a8ce854e8a205160b05a14127970039a904c3ce8ad6f8baf8fc
4
- data.tar.gz: fc4b915c93488f39835f762b1f89fb44a74ab25ca3faa47fb4a6ea846db66c77
3
+ metadata.gz: 52024f72e11787560aa6fc8bed990c359e49d3e995f2d3cfea875de5febaeba5
4
+ data.tar.gz: d04a6301684f284f29aa1b67c811ca596006a6aa0f33e22d1c67790da55418ef
5
5
  SHA512:
6
- metadata.gz: 6079a5cb3f9b5b83a5bbc0db41694e6037a46a8e5ef6ce8bd4e65f36863d17008cb5d08d806681c4b17daff89ef2d43abd4e260c4ba068b7ac499fe51a36053c
7
- data.tar.gz: 164bb2211d24d9119061a9c771438d0b77f96c0e2d51d4f18c3cfe3f82acdeaf50bd532d4eafb071441a64a18be68cefc9bae9a6dcfcf81b633cf3498912e76c
6
+ metadata.gz: e9afd43466c2ea7b6608d0f94996bffd40622fa2ff98bc008098c78375074c4ae8c6e12235520053a35619fca22b3588ccc120d06910f9b8af10cf349273af6c
7
+ data.tar.gz: 4264fd4ff0e12bc86b1451b1a411bea1e700cb58581f87e0216a0b601bd26c2443e144c44ddb765e8e6428ae0bdc2f406342248851a5c36c9f9c00494c8c1253
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2020 Sashite
3
+ Copyright (c) 2015-2021 Sashite
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # Qi.rb
2
2
 
3
- [![Build Status](https://travis-ci.org/sashite/qi.rb.svg?branch=master)](https://travis-ci.org/sashite/qi.rb)
4
- [![Gem Version](https://badge.fury.io/rb/qi.svg)][gem]
5
- [![Inline docs](https://inch-ci.org/github/sashite/qi.rb.svg?branch=master)][inchpages]
6
- [![Documentation](https://img.shields.io/:yard-docs-38c800.svg)][rubydoc]
3
+ [![Version](https://img.shields.io/github/v/tag/sashite/qi.rb?label=Version&logo=github)](https://github.com/sashite/qi.rb/releases)
4
+ [![Yard documentation](https://img.shields.io/badge/Yard-documentation-blue.svg?logo=github)](https://rubydoc.info/github/sashite/qi.rb/main)
5
+ [![CI](https://github.com/sashite/qi.rb/workflows/CI/badge.svg?branch=main)](https://github.com/sashite/qi.rb/actions?query=workflow%3Aci+branch%3Amain)
6
+ [![RuboCop](https://github.com/sashite/qi.rb/workflows/RuboCop/badge.svg?branch=main)](https://github.com/sashite/qi.rb/actions?query=workflow%3Arubocop+branch%3Amain)
7
+ [![License](https://img.shields.io/github/license/sashite/qi.rb?label=License&logo=github)](https://github.com/sashite/qi.rb/raw/main/LICENSE.md)
7
8
 
8
9
  > `Qi` (棋) is an abstraction for updating positions of chess variants (including Chess, Janggi, Markruk, Shogi, Xiangqi), with a move.
9
10
 
@@ -17,33 +18,33 @@ gem "qi"
17
18
 
18
19
  And then execute:
19
20
 
20
- $ bundle
21
+ ```sh
22
+ bundle
23
+ ```
21
24
 
22
25
  Or install it yourself as:
23
26
 
24
- $ gem install qi
27
+ ```sh
28
+ gem install qi
29
+ ```
25
30
 
26
- ## Examples
31
+ ## Example
27
32
 
28
33
  ```ruby
29
34
  require "qi"
30
35
 
31
36
  Qi.call(
32
- [43, 13, "+B"],
33
- "side_id": 0,
34
- "board": {
35
- 3 => "s",
36
- 4 => "k",
37
- 5 => "s",
37
+ 43, 13, "+B",
38
+ in_hand: %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
39
+ square: {
40
+ 3 => "s",
41
+ 4 => "k",
42
+ 5 => "s",
38
43
  22 => "+P",
39
44
  43 => "+B"
40
- },
41
- "hands": [
42
- %w[S],
43
- %w[r r b g g g g s n n n n p p p p p p p p p p p p p p p p p]
44
- ]
45
+ }
45
46
  )
46
- # => {:side_id=>1, :board=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}, :hands=>[["S"], ["r", "r", "b", "g", "g", "g", "g", "s", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p"]]}
47
+ # => {:in_hand=>["S", "r", "r", "b", "g", "g", "g", "g", "s", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p"], :square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}}
47
48
  ```
48
49
 
49
50
  ## License
@@ -55,7 +56,3 @@ The code is available as open source under the terms of the [MIT License](https:
55
56
  This [gem](https://rubygems.org/gems/qi) is maintained by [Sashite](https://sashite.com/).
56
57
 
57
58
  With some [lines of code](https://github.com/sashite/), let's share the beauty of Chinese, Japanese and Western cultures through the game of chess!
58
-
59
- [gem]: https://rubygems.org/gems/qi
60
- [inchpages]: https://inch-ci.org/github/sashite/qi.rb
61
- [rubydoc]: https://rubydoc.info/gems/qi/frames
data/lib/qi/action.rb ADDED
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Qi
4
+ # The Action abstraction.
5
+ class Action
6
+ # Initialize an action instance.
7
+ #
8
+ # @param src_square_id [Integer, nil] The source square ID.
9
+ # @param dst_square_id [Integer] The target square ID.
10
+ # @param moved_piece_name [String] The moved piece name.
11
+ # @param captured_piece_name [String, nil] The captured piece name.
12
+ #
13
+ # @example Initialize a promoted bishop action from 43 to 13
14
+ # new(43, 13, "+B", nil)
15
+ #
16
+ # @see https://developer.sashite.com/specs/portable-action-notation
17
+ def initialize(src_square_id, dst_square_id, moved_piece_name, captured_piece_name = nil)
18
+ @src_square_id = src_square_id
19
+ @dst_square_id = dst_square_id
20
+ @moved_piece_name = moved_piece_name
21
+ @captured_piece_name = captured_piece_name
22
+ end
23
+
24
+ # Commit an action to the position.
25
+ #
26
+ # @param in_hand [Array] The list of pieces in hand.
27
+ # @param square [Hash] The index of each piece on the board.
28
+ #
29
+ # @example Commit a Shogi action to the piece set of a position
30
+ # call(
31
+ # 43, 13, "+B", nil,
32
+ # in_hand: %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
33
+ # square: {
34
+ # 3 => "s",
35
+ # 4 => "k",
36
+ # 5 => "s",
37
+ # 22 => "+P",
38
+ # 43 => "+B"
39
+ # }
40
+ # )
41
+ # # => {:in_hand=>["S", "r", "r", "b", "g", "g", "g", "g", "s", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p"], :square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}}
42
+ #
43
+ # @return [Hash] The next piece set.
44
+ def call(in_hand:, square:)
45
+ in_hand = in_hand.dup
46
+ square = square.dup
47
+
48
+ if @src_square_id.nil?
49
+ piece_in_hand_id = in_hand.index(@moved_piece_name)
50
+ in_hand.delete_at(piece_in_hand_id) unless piece_in_hand_id.nil?
51
+ else
52
+ square.delete(@src_square_id)
53
+ end
54
+
55
+ square[@dst_square_id] = @moved_piece_name
56
+ in_hand.push(@captured_piece_name) unless @captured_piece_name.nil?
57
+
58
+ { in_hand: in_hand, square: square }
59
+ end
60
+ end
61
+ end
data/lib/qi.rb CHANGED
@@ -1,84 +1,53 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative File.join("qi", "action")
4
+
3
5
  # The Qi abstraction.
4
6
  #
5
- # @example
7
+ # @example Apply a move to a classic Shogi problem
6
8
  # Qi.call(
7
- # [43, 13, "+B"],
8
- # "side_id": 0,
9
- # "board": {
9
+ # 43, 13, "+B",
10
+ # in_hand: %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
11
+ # square: {
10
12
  # 3 => "s",
11
13
  # 4 => "k",
12
14
  # 5 => "s",
13
15
  # 22 => "+P",
14
16
  # 43 => "+B"
15
- # },
16
- # "hands": [
17
- # %w[S],
18
- # %w[r r b g g g g s n n n n p p p p p p p p p p p p p p p p p]
19
- # ]
17
+ # }
20
18
  # )
21
- # # => {:side_id=>1, :board=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}, :hands=>[["S"], ["r", "r", "b", "g", "g", "g", "g", "s", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p"]]}
19
+ # # => {:in_hand=>["S", "r", "r", "b", "g", "g", "g", "g", "s", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p"], :square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}}
22
20
  module Qi
23
- # Apply a move to the position.
21
+ # Apply an action to the position.
24
22
  #
25
- # @param move [Array] The move to play.
26
- # @param side_id [Integer] The identifier of the player who must play.
27
- # @param board [Hash] The indexes of each piece on the board.
28
- # @param hands [Array] The list of pieces in hand grouped by players.
23
+ # @param src_square_id [Integer] A source square index.
24
+ # @param dst_square_id [Integer] A target square index.
25
+ # @param moved_piece_name [String] A piece name.
26
+ # @param captured_piece_name [String] A captured piece name.
27
+ # @param in_hand [Array] The list of pieces in hand.
28
+ # @param square [Hash] The index of each piece on the board.
29
29
  #
30
30
  # @see https://developer.sashite.com/specs/portable-chess-notation
31
31
  # @see https://developer.sashite.com/specs/portable-move-notation
32
32
  #
33
- # @example
33
+ # @example Apply a move to a classic Shogi problem
34
34
  # call(
35
- # [43, 13, "+B"],
36
- # "side_id": 0,
37
- # "board": {
35
+ # 43,
36
+ # 13,
37
+ # "+B",
38
+ # in_hand: %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
39
+ # square: {
38
40
  # 3 => "s",
39
41
  # 4 => "k",
40
42
  # 5 => "s",
41
43
  # 22 => "+P",
42
44
  # 43 => "+B"
43
- # },
44
- # "hands": [
45
- # %w[S],
46
- # %w[r r b g g g g s n n n n p p p p p p p p p p p p p p p p p]
47
- # ]
45
+ # }
48
46
  # )
49
- # # => {:side_id=>1, :board=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}, :hands=>[["S"], ["r", "r", "b", "g", "g", "g", "g", "s", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p"]]}
47
+ # # => {:in_hand=>["S", "r", "r", "b", "g", "g", "g", "g", "s", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p"], :square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}}
50
48
  #
51
- # @return [Hash] The next position.
52
- def self.call(move, side_id:, board:, hands:)
53
- updated_board = board.dup
54
- updated_in_hand_pieces = hands.fetch(side_id).dup
55
-
56
- actions = move.each_slice(4)
57
-
58
- actions.each do |action|
59
- src_square_id = action.fetch(0)
60
- dst_square_id = action.fetch(1)
61
- moved_piece_name = action.fetch(2)
62
- captured_piece_name = action.fetch(3, nil)
63
-
64
- if src_square_id.nil?
65
- piece_in_hand_id = updated_in_hand_pieces.index(moved_piece_name)
66
- updated_in_hand_pieces.delete_at(piece_in_hand_id) unless piece_in_hand_id.nil?
67
- else
68
- updated_board.delete(src_square_id)
69
- end
70
-
71
- updated_board[dst_square_id] = moved_piece_name
72
- updated_in_hand_pieces.push(captured_piece_name) unless captured_piece_name.nil?
73
- end
74
-
75
- updated_hands = hands.dup
76
- updated_hands[side_id] = updated_in_hand_pieces
77
-
78
- {
79
- side_id: side_id.succ % hands.length,
80
- board: updated_board,
81
- hands: updated_hands
82
- }
49
+ # @return [Hash] The piece set of the next position.
50
+ def self.call(src_square_id, dst_square_id, moved_piece_name, captured_piece_name = nil, in_hand:, square:)
51
+ Action.new(src_square_id, dst_square_id, moved_piece_name, captured_piece_name).call(in_hand: in_hand, square: square)
83
52
  end
84
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qi
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.0
4
+ version: 9.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-19 00:00:00.000000000 Z
11
+ date: 2021-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: brutal
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-md
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: rubocop-performance
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +94,20 @@ dependencies:
66
94
  - - ">="
67
95
  - !ruby/object:Gem::Version
68
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
69
111
  - !ruby/object:Gem::Dependency
70
112
  name: rubocop-thread_safety
71
113
  requirement: !ruby/object:Gem::Requirement
@@ -117,6 +159,7 @@ files:
117
159
  - LICENSE.md
118
160
  - README.md
119
161
  - lib/qi.rb
162
+ - lib/qi/action.rb
120
163
  homepage: https://developer.sashite.com/specs/
121
164
  licenses:
122
165
  - MIT
@@ -124,7 +167,7 @@ metadata:
124
167
  bug_tracker_uri: https://github.com/sashite/qi.rb/issues
125
168
  documentation_uri: https://rubydoc.info/gems/qi/index
126
169
  source_code_uri: https://github.com/sashite/qi.rb
127
- post_install_message:
170
+ post_install_message:
128
171
  rdoc_options: []
129
172
  require_paths:
130
173
  - lib
@@ -132,15 +175,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
175
  requirements:
133
176
  - - ">="
134
177
  - !ruby/object:Gem::Version
135
- version: 2.7.0
178
+ version: 3.0.0
136
179
  required_rubygems_version: !ruby/object:Gem::Requirement
137
180
  requirements:
138
181
  - - ">="
139
182
  - !ruby/object:Gem::Version
140
183
  version: '0'
141
184
  requirements: []
142
- rubygems_version: 3.1.2
143
- signing_key:
185
+ rubygems_version: 3.2.22
186
+ signing_key:
144
187
  specification_version: 4
145
188
  summary: Update positions with a move.
146
189
  test_files: []