chessmate 0.7.0 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d93cf15b660549aaf0e458ec3f190900be90dde590893e521ef75115f00394c5
4
- data.tar.gz: 576c2b0d4ea1c210610f03539fcc6bbaf95b7d1b7e6d04f277f862168fae2825
3
+ metadata.gz: eaacf6aa4d8e0dd9a6b40f01fb136c1fbe50c201fff256d062965dd0e37cea10
4
+ data.tar.gz: fd4f655e91cbc7fa4c47df3b986ce5e77eb918de29e8bbe9f7c59f093b28d5a1
5
5
  SHA512:
6
- metadata.gz: 835c31648c2c01fdb5bf15a4c9ea50c933260601e53f3ae660113dd29d4d4831d638c9ccaef863f0bd94d8e468ee23e89fdce277ef27ecae9bc3c35eaed6faec
7
- data.tar.gz: 3e8061129daa7964e07e8cadf09a560faa5897ac3b2180721423ea9e3784e6363dc49888d01a975a4571773f46243f7c6558c5cd890aad0baa3c69d20a9920dd
6
+ metadata.gz: cb07a9daa65eeafd1158aebcdcd457700d157cd226b5382c8f9a8a794e6397dced03c4223bbaa6bb42b27a1762f078efec21b640ad09c5eb51b07c2f08006bba
7
+ data.tar.gz: 3d1e5177494c9a450ffdc87731551f010035aa24a1f1cec37091345ac9ceddbc13bab8cb1ce4561a94ae1a7dd8e2e4d25e86f2131c4a87fe73a4bc8b527e1981
@@ -0,0 +1,76 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at tyler.b.porter@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
74
+
75
+ For answers to common questions about this code of conduct, see
76
+ https://www.contributor-covenant.org/faq
data/Gemfile CHANGED
File without changes
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- chessmate (0.7.0)
4
+ chessmate (0.8.3)
5
5
  deep_dup (~> 0)
6
6
 
7
7
  GEM
@@ -9,10 +9,18 @@ GEM
9
9
  specs:
10
10
  ast (2.4.0)
11
11
  coderay (1.1.2)
12
+ coveralls (0.8.23)
13
+ json (>= 1.8, < 3)
14
+ simplecov (~> 0.16.1)
15
+ term-ansicolor (~> 1.3)
16
+ thor (>= 0.19.4, < 2.0)
17
+ tins (~> 1.6)
12
18
  deep_dup (0.0.3)
13
- jaro_winkler (1.5.3)
19
+ docile (1.3.2)
20
+ jaro_winkler (1.5.4)
21
+ json (2.3.0)
14
22
  method_source (0.9.2)
15
- parallel (1.18.0)
23
+ parallel (1.19.1)
16
24
  parser (2.6.5.0)
17
25
  ast (~> 2.4.0)
18
26
  pry (0.12.2)
@@ -28,6 +36,15 @@ GEM
28
36
  ruby-progressbar (~> 1.7)
29
37
  unicode-display_width (>= 1.4.0, < 1.7)
30
38
  ruby-progressbar (1.10.1)
39
+ simplecov (0.16.1)
40
+ docile (~> 1.1)
41
+ json (>= 1.8, < 3)
42
+ simplecov-html (~> 0.10.0)
43
+ simplecov-html (0.10.2)
44
+ term-ansicolor (1.7.1)
45
+ tins (~> 1.0)
46
+ thor (1.0.1)
47
+ tins (1.22.2)
31
48
  unicode-display_width (1.6.0)
32
49
 
33
50
  PLATFORMS
@@ -35,9 +52,10 @@ PLATFORMS
35
52
 
36
53
  DEPENDENCIES
37
54
  chessmate!
55
+ coveralls (>= 0.8.23)
38
56
  pry (~> 0)
39
57
  rspec (~> 0)
40
- rubocop (>= 0.49.0)
58
+ rubocop (= 0.75.1)
41
59
 
42
60
  BUNDLED WITH
43
- 2.0.2
61
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Tyler Porter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,130 @@
1
+ <p align="center">
2
+ <img width="800" height="150" src="https://imgur.com/WFCwf9p.png">
3
+ </p>
4
+ <h2 align="center">A dead-simple chess validation gem for Rails</h2>
5
+ <p align="center">
6
+ <a href="https://rubygems.org/gems/chessmate">
7
+ <img src="https://img.shields.io/gem/v/chessmate">
8
+ </a>
9
+ <a href="https://travis-ci.com/pawptart/ChessMate">
10
+ <img src="https://travis-ci.com/pawptart/ChessMate.svg?branch=master">
11
+ </a>
12
+ <a href='https://coveralls.io/github/pawptart/ChessMate?branch=coveralls'>
13
+ <img src='https://coveralls.io/repos/github/pawptart/ChessMate/badge.svg?branch=coveralls' alt='Coverage Status' />
14
+ </a>
15
+ <a href="https://github.com/pawptart/ChessMate/issues">
16
+ <img src="https://img.shields.io/github/issues/pawptart/chessmate">
17
+ </a>
18
+ </p>
19
+
20
+ ## About
21
+ ChessMate was built in around 2 months to be as easy to use as possible to quickly and easily bootstrap a chess game in Rails. The original idea came from a bootcamp exercise to build a working chess game, and so the code that was written there has been ported to ChessMate in order to benefit future programmers.
22
+
23
+ ChessMate is designed to be a backend tool to validate possible chess moves. Therefore, it is intentionally as agnostic to your frontend as possible to integrate into many different frameworks. Because it's designed to be flexible, it even supports custom game boards and can allow out-of-turn movement!
24
+
25
+ Click [here](http://chessmate-demo.herokuapp.com/) to play with a Rails app running ChessMate! (Or check out the source code [here](https://github.com/pawptart/ChessTest).)
26
+
27
+ <p align="center">
28
+ <img src="https://i.imgur.com/vyQjL4Y.png">
29
+ </p>
30
+
31
+ ## Usage
32
+ Simply add ChessMate to your Gemfile:
33
+
34
+ ```ruby
35
+ gem 'chessmate'
36
+ ```
37
+
38
+ and then you can require it in a model, controller, etc.
39
+
40
+ ```ruby
41
+ require 'chessmate'
42
+ ```
43
+
44
+ From there, you are free to utilize all the functions and features of ChessMate!
45
+
46
+ ## Building a new game and playing
47
+
48
+ ```ruby
49
+ game = ChessMate.new
50
+ ```
51
+
52
+ Moving pieces works based on chess notation: for example, a common first move is `e2` to `e4`. ChessMate accepts these squares as arguments to the `move` method, so you don't need to specify a piece type like in normal chess notation. To make this move in ChessMate:
53
+
54
+ ```ruby
55
+ game.move('e2', 'e4')
56
+ ```
57
+
58
+ If a move is invalid, `ChessMate.move` will return `false`, and the board and game state will not update. You also do not need to specify for any "special" moves, like castling or _en passant_, as ChessMate can handle this for you.
59
+
60
+ Other functions you might call:
61
+
62
+ ```ruby
63
+ game.promote?(square) # Check if a square is capable of pawn promotion
64
+ game.promote!(square, piece) # Promote a promotable pawn, accepts 'rook'/'knight'/'bishop'/'queen'
65
+ game.in_check? # Determine if either color is currently in check
66
+ game.checkmate?(color) # Determine if the game is over, accepts 'W'/'B'
67
+ game.draw?(color) # Same as checkmate, for draw
68
+ ```
69
+
70
+ Using these functions, it's quite simple to build a working chess game!
71
+
72
+ ## Custom games
73
+ With ChessMate, it's very easy to build your own custom games. Below is a list of all the defaults ChessMate uses to build a game board, but they can be modified and passed into the `ChessMate.new` method as named arguments in any order, and ChessMate will build a game around your custom params.
74
+
75
+ For instance, for a custom board, on turn 10, with the white king in check:
76
+
77
+ ```ruby
78
+ custom_board = [
79
+ [nil, nil, nil, nil, 'BK', nil, nil, nil],
80
+ [nil, nil, nil, nil, 'BQ', nil, nil, nil],
81
+ [nil, nil, nil, nil, nil, nil, nil, nil],
82
+ [nil, nil, nil, nil, nil, nil, nil, nil],
83
+ [nil, nil, nil, nil, nil, nil, nil, nil],
84
+ [nil, nil, nil, nil, nil, nil, nil, nil],
85
+ ['WP', nil, nil, nil, nil, nil, nil, nil],
86
+ [nil, nil, nil, nil, 'WK', nil, nil, nil]
87
+ ]
88
+ turn = 10
89
+ in_check = { white: true, black: false }
90
+
91
+ game = ChessMate.new(board: custom_board, turn: turn, in_check: in_check)
92
+ ```
93
+
94
+ ChessMate can build a game with those parameters!
95
+
96
+ Here is a list of all the defaults:
97
+ ```ruby
98
+ board: [
99
+ %w[BR BN BB BQ BK BB BN BR],
100
+ %w[BP BP BP BP BP BP BP BP],
101
+ [nil, nil, nil, nil, nil, nil, nil, nil],
102
+ [nil, nil, nil, nil, nil, nil, nil, nil],
103
+ [nil, nil, nil, nil, nil, nil, nil, nil],
104
+ [nil, nil, nil, nil, nil, nil, nil, nil],
105
+ %w[WP WP WP WP WP WP WP WP],
106
+ %w[WR WN WB WQ WK WB WN WR]
107
+ ]
108
+
109
+ turn: 1
110
+
111
+ promotable: nil
112
+
113
+ en_passant: { white: nil, black: nil }
114
+
115
+ in_check: { white: false, black: false }
116
+
117
+ castling: {
118
+ white: {
119
+ kingside: true,
120
+ queenside: true
121
+ },
122
+ black: {
123
+ kingside: true,
124
+ queenside: true
125
+ }
126
+ }
127
+ ```
128
+
129
+ ## Contributing
130
+ ChessMate is open to contributions! If you have a feature request, a bug, or a suggestion, please open an issue! Please note that a review is required and passing TravisCI build before your PR can be merged with master.
@@ -11,8 +11,16 @@ class ChessMate
11
11
  require 'pieces/queen'
12
12
  require 'pieces/king'
13
13
  require 'helpers/default'
14
+ require 'helpers/chess_logger'
14
15
 
15
- attr_reader :board, :turn, :in_check, :promotable, :en_passant, :castling, :allow_out_of_turn
16
+ attr_reader :board,
17
+ :turn,
18
+ :in_check,
19
+ :promotable,
20
+ :en_passant,
21
+ :castling,
22
+ :allow_out_of_turn,
23
+ :move_history
16
24
 
17
25
  def initialize(board: nil,
18
26
  turn: nil,
@@ -20,28 +28,30 @@ class ChessMate
20
28
  en_passant: nil,
21
29
  castling: nil,
22
30
  in_check: nil,
23
- allow_out_of_turn: nil)
31
+ allow_out_of_turn: nil,
32
+ move_history: nil,
33
+ ignore_logging: false)
24
34
  @board = board || DEFAULT[:board].map(&:dup)
25
35
  @turn = turn || DEFAULT[:turn]
26
- @promotable = promotable || DeepDup.deep_dup(DEFAULT[:promotable])
36
+ @promotable = promotable
27
37
  @en_passant = en_passant || DeepDup.deep_dup(DEFAULT[:en_passant])
28
38
  @castling = castling || DeepDup.deep_dup(DEFAULT[:castling])
29
39
  @in_check = in_check || DeepDup.deep_dup(DEFAULT[:in_check])
30
-
40
+
31
41
  @allow_out_of_turn = if allow_out_of_turn.nil?
32
- ENV['TEST'] == 'true' || false
33
- elsif [true, false].include?(allow_out_of_turn)
34
- allow_out_of_turn
35
- else
36
- false
37
- end
42
+ ENV['TEST'] == 'true' || false
43
+ elsif [true, false].include?(allow_out_of_turn)
44
+ allow_out_of_turn
45
+ else
46
+ false
47
+ end
48
+ @move_history = move_history || []
49
+ @ignore_logging = ignore_logging
38
50
  end
39
51
 
40
52
  def update(orig, dest = nil)
41
- orig_y = orig[0]
42
- orig_x = orig[1]
43
- dest_y = dest[0]
44
- dest_x = dest[1]
53
+ orig_y, orig_x = orig
54
+ dest_y, dest_x = dest
45
55
  piece_type = @board[orig_y][orig_x]
46
56
  piece_color = piece_type[0] == 'W' ? :white : :black
47
57
  opposite_color = piece_type[0] == 'W' ? :black : :white
@@ -79,10 +89,16 @@ class ChessMate
79
89
  @board[orig_y][new_rook_x_position] = piece_type[0] + 'R'
80
90
  end
81
91
 
92
+ @promotable = dest if piece_type[1] == 'P' && promote?(orig)
93
+
94
+ unless @ignore_logging
95
+ logger = ChessLogger.new(orig, dest, @board)
96
+ @move_history << logger.log_move
97
+ end
98
+
82
99
  @board[orig_y][orig_x] = nil
83
100
  @board[dest_y][dest_x] = piece_type
84
101
 
85
- @promotable = dest if piece_type[1] == 'P' && promote?(dest)
86
102
  @in_check = in_check?
87
103
  @turn += 1
88
104
  end
@@ -117,6 +133,8 @@ class ChessMate
117
133
  end
118
134
 
119
135
  def move(orig, dest, test = false, test_board = nil)
136
+ return false if @promotable
137
+
120
138
  orig_pos = NotationParser.parse_notation(orig)
121
139
  dest_pos = NotationParser.parse_notation(dest)
122
140
 
@@ -127,9 +145,9 @@ class ChessMate
127
145
 
128
146
  piece = @board[orig_y][orig_x]
129
147
  piece_type = piece[1]
130
- allowed_turn = piece[0] == "W" ? :odd? : :even?
148
+ allowed_turn = piece[0] == 'W' ? :odd? : :even?
131
149
 
132
- return false unless @allow_out_of_turn || @turn.send(allowed_turn)
150
+ return false unless @allow_out_of_turn || @turn.send(allowed_turn) || test
133
151
 
134
152
  board = test_board.nil? ? @board : test_board
135
153
  valid_move = case piece_type
@@ -148,10 +166,10 @@ class ChessMate
148
166
  else
149
167
  false
150
168
  end
151
-
152
- in_check_after_move = in_check_after_move?(orig_pos, dest_pos) unless test
153
-
154
- update(orig_pos, dest_pos) if valid_move && !test && !in_check_after_move
169
+ unless test
170
+ in_check_after_move = in_check_after_move?(orig_pos, dest_pos)
171
+ update(orig_pos, dest_pos) if valid_move && !test && !in_check_after_move
172
+ end
155
173
 
156
174
  valid_move && !in_check_after_move
157
175
  end
@@ -159,10 +177,8 @@ class ChessMate
159
177
  def in_check_after_move?(orig, dest)
160
178
  test_board = @board.map(&:dup)
161
179
 
162
- orig_y = orig[0]
163
- orig_x = orig[1]
164
- dest_y = dest[0]
165
- dest_x = dest[1]
180
+ orig_y, orig_x = orig
181
+ dest_y, dest_x = dest
166
182
  piece = test_board[orig_y][orig_x]
167
183
  piece_type = test_board[orig_y][orig_x]
168
184
  opposite_color = piece_type[0] == 'W' ? :black : :white
@@ -236,8 +252,8 @@ class ChessMate
236
252
  def promote?(square)
237
253
  square_y = square[0]
238
254
  square_x = square[1]
239
- piece = @board[square_y][square_x][0]
240
- promote_column = piece.downcase == 'w' ? 0 : 7
255
+ piece_color = @board[square_y][square_x][0]
256
+ promote_column = piece_color.downcase == 'w' ? 1 : 6
241
257
  promote_column == square_y
242
258
  end
243
259
 
@@ -246,7 +262,7 @@ class ChessMate
246
262
  square_x = square[1]
247
263
 
248
264
  old_piece = @board[square_y][square_x]
249
- return nil if old_piece.nil? || !promote?(square)
265
+ return nil if old_piece.nil? || @promotable != [square_y, square_x]
250
266
 
251
267
  case piece.downcase
252
268
  when 'rook'
@@ -262,5 +278,11 @@ class ChessMate
262
278
  end
263
279
 
264
280
  @board[square_y][square_x] = old_piece[0] + piece_type
281
+ @promotable = nil
282
+
283
+ return if @ignore_logging
284
+
285
+ logger = ChessLogger.new(nil, nil, nil, promotion_type: piece_type, history: @move_history)
286
+ @move_history[-1] += logger.log_promotion
265
287
  end
266
288
  end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'helpers/notation_parser'
4
+ require 'chessmate'
5
+
6
+ class ChessLogger
7
+ def initialize(orig, dest, board, en_passant: false, promotion_type: nil, history: nil)
8
+ @promotion_type = promotion_type
9
+ @history = history
10
+
11
+ return unless orig && dest && board
12
+
13
+ @orig = orig
14
+ @dest = dest
15
+ @board = board
16
+ @en_passant = en_passant
17
+ @orig_y, @orig_x = @orig
18
+ @dest_y, @dest_x = @dest
19
+ @piece = @board[@orig_y][@orig_x]
20
+ @piece_color, @piece_type = @piece.chars
21
+ end
22
+
23
+ def log_move
24
+ if @piece_type == 'K' && (@orig_x - @dest_x).abs > 1
25
+ return (@dest_x - @orig_x).positive? ? '0-0' : '0-0-0'
26
+ end
27
+
28
+ origin = encode_origin
29
+ capture = @board[@dest_y][@dest_x] || @en_passant ? 'x' : ''
30
+ destination = NotationParser.encode_notation(@dest)
31
+
32
+ origin + capture + destination + check_or_mate
33
+ end
34
+
35
+ def log_promotion
36
+ @promotion_type ? "=(#{@promotion_type})" : ''
37
+ end
38
+
39
+ private
40
+
41
+ def encode_origin
42
+ notation_required = [false, false]
43
+ game = ChessMate.new(board: @board)
44
+ encoded_dest = NotationParser.encode_notation(@dest)
45
+
46
+ @board.each_with_index do |row, y|
47
+ row.each_with_index do |col, x|
48
+ next unless @piece == col && [@orig_y, @orig_x] != [y, x]
49
+
50
+ encoded_orig = NotationParser.encode_notation([y, x])
51
+
52
+ if game.move(encoded_orig, encoded_dest, true)
53
+ notation_required[0] = true if @orig_y == y || (@orig_y != y && @orig_x != x)
54
+ notation_required[1] = true if @orig_x == x
55
+ end
56
+ end
57
+ end
58
+
59
+ if notation_required.nil? || notation_required.none?(true)
60
+ if @piece_type == 'P'
61
+ return NotationParser.encode_notation(@orig)[0] if @board[@dest_y][@dest_x] || @en_passant
62
+
63
+ return ''
64
+ end
65
+ return @piece_type
66
+ end
67
+ ambiguous_encoded = @piece_type
68
+ encoded_origin_chars = NotationParser.encode_notation(@orig).chars
69
+ notation_required.each_with_index do |value, i|
70
+ ambiguous_encoded += encoded_origin_chars[i] if value
71
+ end
72
+ ambiguous_encoded
73
+ end
74
+
75
+ def check_or_mate
76
+ game = ChessMate.new(board: @board, ignore_logging: true, allow_out_of_turn: true)
77
+ encoded_orig = NotationParser.encode_notation(@orig)
78
+ encoded_dest = NotationParser.encode_notation(@dest)
79
+ opposite_color_letter = @piece_color == 'W' ? 'B' : 'W'
80
+ opposite_color_string = opposite_color_letter == 'W' ? 'white' : 'black'
81
+
82
+ game.move(encoded_orig, encoded_dest)
83
+ checkmate = game.checkmate?(opposite_color_letter)
84
+ check = game.in_check?[opposite_color_string.to_sym]
85
+
86
+ return '#' if checkmate
87
+ return '+' if check
88
+
89
+ ''
90
+ end
91
+ end
@@ -12,7 +12,6 @@ DEFAULT = {
12
12
  %w[WR WN WB WQ WK WB WN WR]
13
13
  ],
14
14
  turn: 1,
15
- promotable: nil,
16
15
  en_passant: { white: nil, black: nil },
17
16
  in_check: { white: false, black: false },
18
17
  castling: {
File without changes
File without changes
@@ -16,10 +16,8 @@ class King < Piece
16
16
  end
17
17
 
18
18
  def self.valid_castling_move?(orig, dest, board, castling)
19
- orig_y = orig[0]
20
- orig_x = orig[1]
21
- dest_y = dest[0]
22
- dest_x = dest[1]
19
+ orig_y, orig_x = orig
20
+ dest_y, dest_x = dest
23
21
 
24
22
  return false if orig_y != dest_y || (orig_x - dest_x).abs != 2
25
23
 
File without changes
@@ -6,10 +6,8 @@ class Pawn < Piece
6
6
  def self.move_is_valid?(orig, dest, board, en_passant)
7
7
  return true if en_passant(orig, dest, board, en_passant)
8
8
 
9
- orig_y = orig[0]
10
- orig_x = orig[1]
11
- dest_y = dest[0]
12
- dest_x = dest[1]
9
+ orig_y, orig_x = orig
10
+ dest_y, dest_x = dest
13
11
  piece_type = board[orig_y][orig_x]
14
12
  piece_color = piece_type[0].downcase
15
13
 
@@ -36,10 +34,8 @@ class Pawn < Piece
36
34
  end
37
35
 
38
36
  def self.en_passant(orig, dest, board, en_passant)
39
- orig_y = orig[0]
40
- orig_x = orig[1]
41
- dest_y = dest[0]
42
- dest_x = dest[1]
37
+ orig_y, orig_x = orig
38
+ dest_y, dest_x = dest
43
39
  piece_type = board[orig_y][orig_x]
44
40
  opposite_color = piece_type[0].downcase == 'w' ? :black : :white
45
41
  direction = opposite_color == :white ? -1 : 1
@@ -2,10 +2,8 @@
2
2
 
3
3
  class Piece
4
4
  def self.obstructed?(orig, dest, board)
5
- orig_y = orig[0]
6
- orig_x = orig[1]
7
- dest_y = dest[0]
8
- dest_x = dest[1]
5
+ orig_y, orig_x = orig
6
+ dest_y, dest_x = dest
9
7
 
10
8
  if orig_y == dest_y
11
9
 
@@ -14,7 +12,8 @@ class Piece
14
12
  test_pos = orig_x - (x * direction) - direction
15
13
  return true unless board[orig_y][test_pos].nil?
16
14
  end
17
- return false
15
+
16
+ false
18
17
 
19
18
  elsif orig_x == dest_x
20
19
 
@@ -24,7 +23,7 @@ class Piece
24
23
  return true unless board[test_pos][orig_x].nil?
25
24
  end
26
25
 
27
- return false
26
+ false
28
27
 
29
28
  elsif (orig_y - dest_y).abs == (orig_x - dest_x).abs
30
29
 
@@ -37,18 +36,14 @@ class Piece
37
36
  return true unless board[test_y_pos][test_x_pos].nil?
38
37
  end
39
38
 
40
- return false
39
+ false
41
40
 
42
- else
43
- return nil
44
41
  end
45
42
  end
46
43
 
47
44
  def self.capturable?(orig, dest, board)
48
- orig_y = orig[0]
49
- orig_x = orig[1]
50
- dest_y = dest[0]
51
- dest_x = dest[1]
45
+ orig_y, orig_x = orig
46
+ dest_y, dest_x = dest
52
47
  orig_piece = board[orig_y][orig_x]
53
48
  dest_piece = board[dest_y][dest_x]
54
49
 
File without changes
File without changes
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'english'
4
+ require 'rubocop'
5
+
6
+ ADDED_OR_MODIFIED = /A|AM|^M/.freeze
7
+
8
+ changed_files = `git status --porcelain`.split(/\n/).
9
+ select { |file_name_with_status|
10
+ file_name_with_status =~ ADDED_OR_MODIFIED
11
+ }.
12
+ map { |file_name_with_status|
13
+ file_name_with_status.split(' ')[1]
14
+ }.
15
+ select { |file_name|
16
+ File.extname(file_name) == '.rb'
17
+ }.join(' ')
18
+
19
+ success = system(%(rubocop #{changed_files}))
20
+
21
+ STDIN.reopen('/dev/tty')
22
+
23
+ if success == false
24
+ puts "Would you like to continue press 'any key' or 'n/N' to halt?"
25
+ exit(1) if %w(N n).include?(gets.chomp)
26
+ end
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
  require_relative '../lib/chessmate'
5
5
  require_relative '../lib/helpers/notation_parser'
6
6
  require_relative '../lib/helpers/default'
7
- Dir['../lib/pieces/*.rb'].each { |file| require file }
7
+ Dir['../lib/pieces/*.rb'].sort.each { |file| require file }
8
8
 
9
9
  describe ChessMate do
10
10
  describe 'initialize method' do
@@ -59,7 +59,7 @@ describe ChessMate do
59
59
  chess = ChessMate.new
60
60
  expect(chess.board).to eql(DEFAULT[:board])
61
61
  expect(chess.turn).to eql(DEFAULT[:turn])
62
- expect(chess.promotable).to eql(DEFAULT[:promotable])
62
+ expect(chess.promotable).to eql(nil)
63
63
  expect(chess.en_passant).to eql(DEFAULT[:en_passant])
64
64
  expect(chess.castling).to eql(DEFAULT[:castling])
65
65
  expect(chess.in_check).to eql(DEFAULT[:in_check])
@@ -217,8 +217,8 @@ describe ChessMate do
217
217
  chess = ChessMate.new(allow_out_of_turn: false)
218
218
  expect(chess.move('a7', 'a6')).to eql(false)
219
219
  expect(chess.board).to eql(DEFAULT[:board])
220
- expect(chess.move('a2','a3')).to eql(true)
221
- expect(chess.move('a3','a4')).to eql(false)
220
+ expect(chess.move('a2', 'a3')).to eql(true)
221
+ expect(chess.move('a3', 'a4')).to eql(false)
222
222
  end
223
223
 
224
224
  it 'option to allow players to move out of turn' do
@@ -356,6 +356,21 @@ describe ChessMate do
356
356
  )
357
357
  end
358
358
 
359
+ it 'should return false if there is a promotable pawn on the board' do
360
+ board = [
361
+ ['WP', nil, nil, nil, nil, nil, nil, nil],
362
+ [nil, nil, nil, nil, nil, nil, nil, nil],
363
+ [nil, nil, nil, nil, nil, nil, nil, nil],
364
+ [nil, nil, nil, nil, nil, nil, nil, nil],
365
+ [nil, nil, nil, nil, nil, nil, nil, nil],
366
+ [nil, nil, nil, nil, nil, nil, nil, nil],
367
+ ['WP', nil, nil, nil, nil, nil, nil, nil],
368
+ [nil, nil, nil, nil, nil, nil, nil, nil]
369
+ ]
370
+ chess = ChessMate.new(board: board, promotable: [0, 0])
371
+ expect(chess.move('a2', 'a3')).to eql(false)
372
+ end
373
+
359
374
  context 'for pawns' do
360
375
  it 'should update the board if pawn move is valid' do
361
376
  @chess.move('c2', 'c3')
@@ -1357,27 +1372,27 @@ describe ChessMate do
1357
1372
  end
1358
1373
 
1359
1374
  describe 'promote? method' do
1360
- it 'should return true if white piece is on last rank' do
1375
+ it 'should return true if white piece is moving to last rank' do
1361
1376
  board = Array.new(8) { Array.new(8, nil) }
1362
- board[0][0] = 'WP'
1377
+ board[1][0] = 'WP'
1363
1378
  chess = ChessMate.new(board: board)
1364
- expect(chess.promote?([0, 0])).to eql(true)
1379
+ expect(chess.promote?([1, 0])).to eql(true)
1365
1380
  end
1366
1381
 
1367
- it 'should return true if black piece is on last rank' do
1382
+ it 'should return true if black piece is moving to last rank' do
1368
1383
  board = Array.new(8) { Array.new(8, nil) }
1369
- board[7][0] = 'BP'
1384
+ board[6][0] = 'BP'
1370
1385
  chess = ChessMate.new(board: board)
1371
- expect(chess.promote?([7, 0])).to eql(true)
1386
+ expect(chess.promote?([6, 0])).to eql(true)
1372
1387
  end
1373
1388
 
1374
1389
  it 'should return false otherwise' do
1375
1390
  board = Array.new(8) { Array.new(8, nil) }
1376
- board[1][0] = 'WP'
1377
- board[6][0] = 'BP'
1391
+ board[2][0] = 'WP'
1392
+ board[5][0] = 'BP'
1378
1393
  chess = ChessMate.new(board: board)
1379
- expect(chess.promote?([1, 0])).to eql(false)
1380
- expect(chess.promote?([6, 0])).to eql(false)
1394
+ expect(chess.promote?([2, 0])).to eql(false)
1395
+ expect(chess.promote?([5, 0])).to eql(false)
1381
1396
  end
1382
1397
  end
1383
1398
 
@@ -1399,8 +1414,9 @@ describe ChessMate do
1399
1414
  context 'should promote to' do
1400
1415
  before :each do
1401
1416
  board = Array.new(8) { Array.new(8, nil) }
1402
- board[0][0] = 'WP'
1417
+ board[1][0] = 'WP'
1403
1418
  @chess = ChessMate.new(board: board)
1419
+ @chess.move('a7', 'a8')
1404
1420
  end
1405
1421
 
1406
1422
  it 'queen' do
@@ -1423,6 +1439,59 @@ describe ChessMate do
1423
1439
  expect(@chess.board[0][0]).to eql('WR')
1424
1440
  end
1425
1441
  end
1442
+
1443
+ context 'logging' do
1444
+ it 'should correctly handle logging promotion' do
1445
+ board = [
1446
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1447
+ ['WP', nil, nil, nil, nil, nil, nil, nil],
1448
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1449
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1450
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1451
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1452
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1453
+ [nil, nil, nil, nil, nil, nil, nil, nil]
1454
+ ]
1455
+ chess = ChessMate.new(board: board)
1456
+ chess.move('a7', 'a8')
1457
+ chess.promote!([0, 0], 'queen')
1458
+ expect(chess.move_history[-1]).to eql('a8=(Q)')
1459
+ end
1460
+
1461
+ context 'check moves' do
1462
+ it 'logs checks against black' do
1463
+ board = [
1464
+ [nil, nil, nil, 'WQ', nil, nil, nil, nil],
1465
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1466
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1467
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1468
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1469
+ ['WN', nil, nil, nil, nil, nil, nil, nil],
1470
+ [nil, nil, nil, 'BP', nil, 'BP', nil, nil],
1471
+ [nil, nil, nil, 'BR', 'BK', 'BR', nil, nil]
1472
+ ]
1473
+ chess = ChessMate.new(board: board)
1474
+ chess.move('a3', 'c2')
1475
+ expect(chess.move_history.last).to eql('Nc2+')
1476
+ end
1477
+
1478
+ it 'logs checks against white' do
1479
+ board = [
1480
+ [nil, nil, nil, 'BQ', nil, nil, nil, nil],
1481
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1482
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1483
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1484
+ [nil, nil, nil, nil, nil, nil, nil, nil],
1485
+ ['BN', nil, nil, nil, nil, nil, nil, nil],
1486
+ [nil, nil, nil, 'WP', nil, 'WP', nil, nil],
1487
+ [nil, nil, nil, 'WR', 'WK', 'WR', nil, nil]
1488
+ ]
1489
+ chess = ChessMate.new(board: board)
1490
+ chess.move('a3', 'c2')
1491
+ expect(chess.move_history.last).to eql('Nc2+')
1492
+ end
1493
+ end
1494
+ end
1426
1495
  end
1427
1496
 
1428
1497
  describe 'en_passant method' do
@@ -0,0 +1,207 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require_relative '../lib/helpers/chess_logger'
5
+ require 'chessmate'
6
+
7
+ describe 'ChessLogger' do
8
+ before :each do
9
+ @normal_moves_board = [
10
+ [nil, nil, nil, nil, nil, nil, nil, nil],
11
+ [nil, nil, nil, nil, nil, nil, nil, nil],
12
+ [nil, nil, nil, nil, nil, nil, nil, nil],
13
+ [nil, nil, nil, nil, nil, nil, nil, nil],
14
+ [nil, nil, nil, nil, nil, nil, nil, nil],
15
+ [nil, nil, nil, nil, nil, nil, nil, nil],
16
+ ['WP', 'WN', 'WB', 'WQ', 'WK', nil, nil, nil],
17
+ [nil, nil, nil, nil, nil, nil, nil, nil]
18
+ ]
19
+
20
+ @capture_moves_board = [
21
+ [nil, nil, nil, nil, nil, nil, nil, nil],
22
+ [nil, nil, nil, nil, nil, nil, nil, nil],
23
+ [nil, nil, nil, nil, nil, nil, nil, nil],
24
+ [nil, nil, nil, nil, nil, nil, 'WP', 'BP'],
25
+ ['BP', nil, nil, nil, nil, nil, nil, nil],
26
+ [nil, 'BP', nil, 'BP', nil, nil, nil, nil],
27
+ ['WP', 'WN', 'WB', 'WQ', 'WK', nil, nil, nil],
28
+ [nil, nil, nil, nil, nil, nil, nil, nil]
29
+ ]
30
+
31
+ @ambiguous_moves_board = [
32
+ [nil, nil, nil, 'BR', nil, nil, nil, 'BR'],
33
+ ['BB', nil, nil, nil, nil, nil, nil, nil],
34
+ [nil, nil, nil, 'BB', nil, nil, nil, nil],
35
+ ['WR', nil, nil, nil, nil, nil, nil, nil],
36
+ [nil, nil, nil, nil, 'WQ', nil, nil, 'WQ'],
37
+ [nil, nil, nil, nil, nil, nil, nil, nil],
38
+ [nil, nil, nil, nil, nil, nil, nil, nil],
39
+ ['WR', nil, nil, nil, nil, nil, nil, 'WQ']
40
+ ]
41
+
42
+ @specialty_moves_board = [
43
+ [nil, nil, nil, nil, nil, nil, nil, nil],
44
+ ['WP', nil, nil, nil, nil, nil, nil, nil],
45
+ [nil, nil, nil, nil, nil, nil, nil, nil],
46
+ [nil, nil, nil, nil, nil, nil, nil, nil],
47
+ [nil, nil, nil, nil, nil, nil, nil, nil],
48
+ [nil, nil, nil, nil, nil, nil, nil, nil],
49
+ [nil, nil, nil, nil, nil, nil, nil, nil],
50
+ ['WR', nil, nil, nil, 'WK', nil, nil, 'WR']
51
+ ]
52
+
53
+ @white_check_board = [
54
+ [nil, nil, nil, 'BQ', nil, nil, nil, nil],
55
+ [nil, nil, nil, nil, nil, nil, nil, nil],
56
+ [nil, nil, nil, nil, nil, nil, nil, nil],
57
+ [nil, nil, nil, nil, nil, nil, nil, nil],
58
+ [nil, nil, nil, nil, nil, nil, nil, nil],
59
+ ['BN', nil, nil, nil, nil, nil, nil, nil],
60
+ [nil, nil, nil, 'WP', nil, 'WP', nil, nil],
61
+ [nil, nil, nil, 'WR', 'WK', 'WR', nil, nil]
62
+ ]
63
+
64
+ @black_check_board = [
65
+ [nil, nil, nil, 'WQ', nil, nil, nil, nil],
66
+ [nil, nil, nil, nil, nil, nil, nil, nil],
67
+ [nil, nil, nil, nil, nil, nil, nil, nil],
68
+ [nil, nil, nil, nil, nil, nil, nil, nil],
69
+ [nil, nil, nil, nil, nil, nil, nil, nil],
70
+ ['WN', nil, nil, nil, nil, nil, nil, nil],
71
+ [nil, nil, nil, 'BP', nil, 'BP', nil, nil],
72
+ [nil, nil, nil, 'BR', 'BK', 'BR', nil, nil]
73
+ ]
74
+ end
75
+
76
+ context 'pawn moves' do
77
+ it 'should log normal pawn moves' do
78
+ logger = ChessLogger.new([6, 0], [5, 0], @normal_moves_board)
79
+ expect(logger.log_move).to eql('a3')
80
+ end
81
+
82
+ it 'should log capturing moves' do
83
+ logger = ChessLogger.new([6, 0], [5, 1], @capture_moves_board)
84
+ expect(logger.log_move).to eql('axb3')
85
+ end
86
+
87
+ it 'should log en passant moves' do
88
+ logger = ChessLogger.new([3, 6], [2, 7], @capture_moves_board, en_passant: true)
89
+ expect(logger.log_move).to eql('gxh6')
90
+ end
91
+ end
92
+
93
+ context 'knight moves' do
94
+ it 'should log normal knight moves' do
95
+ logger = ChessLogger.new([6, 1], [4, 0], @normal_moves_board)
96
+ expect(logger.log_move).to eql('Na4')
97
+ end
98
+
99
+ it 'should log capturing moves' do
100
+ logger = ChessLogger.new([6, 1], [4, 0], @capture_moves_board)
101
+ expect(logger.log_move).to eql('Nxa4')
102
+ end
103
+ end
104
+
105
+ context 'bishop moves' do
106
+ it 'should log normal bishop moves' do
107
+ logger = ChessLogger.new([6, 2], [5, 1], @normal_moves_board)
108
+ expect(logger.log_move).to eql('Bb3')
109
+ end
110
+
111
+ it 'should log capturing moves' do
112
+ logger = ChessLogger.new([6, 2], [5, 1], @capture_moves_board)
113
+ expect(logger.log_move).to eql('Bxb3')
114
+ end
115
+ end
116
+
117
+ context 'queen moves' do
118
+ it 'should log normal queen moves' do
119
+ logger = ChessLogger.new([6, 3], [5, 3], @normal_moves_board)
120
+ expect(logger.log_move).to eql('Qd3')
121
+ end
122
+
123
+ it 'should log capturing moves' do
124
+ logger = ChessLogger.new([6, 3], [5, 3], @capture_moves_board)
125
+ expect(logger.log_move).to eql('Qxd3')
126
+ end
127
+ end
128
+
129
+ context 'king moves' do
130
+ it 'should log normal king moves' do
131
+ logger = ChessLogger.new([6, 4], [5, 4], @normal_moves_board)
132
+ expect(logger.log_move).to eql('Ke3')
133
+ end
134
+
135
+ it 'should log capturing moves' do
136
+ logger = ChessLogger.new([6, 4], [5, 3], @capture_moves_board)
137
+ expect(logger.log_move).to eql('Kxd3')
138
+ end
139
+ end
140
+
141
+ context 'ambiguous moves' do
142
+ it 'should add file info to log moves with pieces in same file' do
143
+ logger = ChessLogger.new([7, 0], [5, 0], @ambiguous_moves_board)
144
+ expect(logger.log_move).to eql('R1a3')
145
+ end
146
+
147
+ it 'should add rank info to log moves with pieces in same rank' do
148
+ logger = ChessLogger.new([0, 3], [0, 5], @ambiguous_moves_board)
149
+ expect(logger.log_move).to eql('Rdf8')
150
+ end
151
+
152
+ it 'should add file and rank info to log moves with multiple pieces in same file and rank' do
153
+ logger = ChessLogger.new([4, 7], [7, 4], @ambiguous_moves_board)
154
+ expect(logger.log_move).to eql('Qh4e1')
155
+ end
156
+
157
+ it 'should handle knights/bishops/queens with ability to move to dest square' do
158
+ logger = ChessLogger.new([2, 3], [0, 1], @ambiguous_moves_board)
159
+ expect(logger.log_move).to eql('Bdb8')
160
+ end
161
+ end
162
+
163
+ context 'specialty moves' do
164
+ it 'should log kingside castles' do
165
+ logger = ChessLogger.new([7, 4], [7, 6], @specialty_moves_board)
166
+ expect(logger.log_move).to eql('0-0')
167
+ end
168
+
169
+ it 'should log queenside castles' do
170
+ logger = ChessLogger.new([7, 4], [7, 2], @specialty_moves_board)
171
+ expect(logger.log_move).to eql('0-0-0')
172
+ end
173
+
174
+ it 'should log pawn promotion' do
175
+ %w[R N B Q].each do |piece|
176
+ logger = ChessLogger.new(nil, nil, nil, promotion_type: piece)
177
+ expect(logger.log_promotion).to eql("=(#{piece})")
178
+ end
179
+ end
180
+ end
181
+
182
+ context 'game status indications' do
183
+ context 'for white' do
184
+ it 'should log check' do
185
+ logger = ChessLogger.new([5, 0], [6, 2], @white_check_board)
186
+ expect(logger.log_move).to eql('Nc2+')
187
+ end
188
+
189
+ it 'should log checkmate' do
190
+ logger = ChessLogger.new([0, 3], [0, 4], @white_check_board)
191
+ expect(logger.log_move).to eql('Qe8#')
192
+ end
193
+ end
194
+
195
+ context 'for black' do
196
+ it 'should log check' do
197
+ logger = ChessLogger.new([5, 0], [6, 2], @black_check_board)
198
+ expect(logger.log_move).to eql('Nc2+')
199
+ end
200
+
201
+ it 'should log checkmate' do
202
+ logger = ChessLogger.new([0, 3], [0, 4], @black_check_board)
203
+ expect(logger.log_move).to eql('Qe8#')
204
+ end
205
+ end
206
+ end
207
+ end
File without changes
File without changes
@@ -15,6 +15,10 @@
15
15
  # it.
16
16
  #
17
17
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
18
+
19
+ require 'coveralls'
20
+ Coveralls.wear!
21
+
18
22
  RSpec.configure do |config|
19
23
  config.before(:suite) do
20
24
  ENV.fetch('TEST', 'true')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chessmate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Porter
@@ -10,6 +10,20 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2019-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: coveralls
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.8.23
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.23
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: pry
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -42,16 +56,16 @@ dependencies:
42
56
  name: rubocop
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - ">="
59
+ - - '='
46
60
  - !ruby/object:Gem::Version
47
- version: 0.49.0
61
+ version: 0.75.1
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - ">="
66
+ - - '='
53
67
  - !ruby/object:Gem::Version
54
- version: 0.49.0
68
+ version: 0.75.1
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: deep_dup
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -72,9 +86,13 @@ executables: []
72
86
  extensions: []
73
87
  extra_rdoc_files: []
74
88
  files:
89
+ - CODE_OF_CONDUCT.md
75
90
  - Gemfile
76
91
  - Gemfile.lock
92
+ - LICENSE
93
+ - README.md
77
94
  - lib/chessmate.rb
95
+ - lib/helpers/chess_logger.rb
78
96
  - lib/helpers/default.rb
79
97
  - lib/helpers/notation_parser.rb
80
98
  - lib/pieces/bishop.rb
@@ -84,7 +102,9 @@ files:
84
102
  - lib/pieces/piece.rb
85
103
  - lib/pieces/queen.rb
86
104
  - lib/pieces/rook.rb
105
+ - pre-commit.sh
87
106
  - spec/chessmate_spec.rb
107
+ - spec/logger_spec.rb
88
108
  - spec/notation_parser_spec.rb
89
109
  - spec/piece_spec.rb
90
110
  - spec/spec_helper.rb
@@ -101,15 +121,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
121
  requirements:
102
122
  - - ">="
103
123
  - !ruby/object:Gem::Version
104
- version: '0'
124
+ version: 2.5.8
105
125
  required_rubygems_version: !ruby/object:Gem::Requirement
106
126
  requirements:
107
127
  - - ">="
108
128
  - !ruby/object:Gem::Version
109
129
  version: '0'
110
130
  requirements: []
111
- rubyforge_project:
112
- rubygems_version: 2.7.6.2
131
+ rubygems_version: 3.0.3
113
132
  signing_key:
114
133
  specification_version: 4
115
134
  summary: Chess for Rails