chess_rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/chess_rb/move.rb +86 -0
- data/lib/chess_rb/notation.rb +52 -0
- data/lib/chess_rb/piece.rb +52 -0
- data/lib/chess_rb/position.rb +72 -0
- data/lib/chess_rb.rb +10 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fa3d318cecdbf7ca433d3dbd4a05f865d6acd390
|
4
|
+
data.tar.gz: 0674fc6547bed63a77ad029af20815221f1731c7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0fbc9bf5696a3b468989ee3b00b151f9e36ca6a84ab4a6e3249c3313e6e1ff2be8c25fdf9a5b63d9c4ed05f36600ba897fba4c7aea9daa25afc7d837068ae1eb
|
7
|
+
data.tar.gz: 7dc55e6ddb44420f5ff44c0abe1c5aced4243015ecfa195a5888bb3e8a232a4a1b29cb3eb636bf7ca7294493433b5b302857fd172f64cb3c06d10bbd3d927753
|
@@ -0,0 +1,86 @@
|
|
1
|
+
class ChessRB::Move
|
2
|
+
FILE_TO_NUM = [nil, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
|
3
|
+
|
4
|
+
attr_reader :to, :from, :promotion, :square, :san, :board
|
5
|
+
|
6
|
+
def initialize(move, pos, promotion = nil)
|
7
|
+
if move.split('-').length == 2
|
8
|
+
@square = move
|
9
|
+
else
|
10
|
+
@san = move
|
11
|
+
end
|
12
|
+
|
13
|
+
if pos.is_a? String
|
14
|
+
@board = ChessRB::Position.new pos
|
15
|
+
else
|
16
|
+
@board = pos
|
17
|
+
end
|
18
|
+
|
19
|
+
@promotion = promotion
|
20
|
+
|
21
|
+
@square = ChessRB::Notation.algebraic_to_square(self) if @square.nil?
|
22
|
+
|
23
|
+
squares = @square.split('-')
|
24
|
+
@from = squares[0]
|
25
|
+
@to = squares[1]
|
26
|
+
|
27
|
+
@san = ChessRB::Notation.square_to_algebraic(self) if @san.nil?
|
28
|
+
|
29
|
+
@valid = valid?
|
30
|
+
end
|
31
|
+
|
32
|
+
# TODO
|
33
|
+
# Returns true if move is a legal move in the given position, false otherwise.
|
34
|
+
def valid?
|
35
|
+
return @valid if !@valid.nil?
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns true if move represents a queen-side castle, false otherwise.
|
40
|
+
def queen_castle?
|
41
|
+
|
42
|
+
return valid? && ChessRB::Piece.new(@board.piece_on(@to)).type == 'k' &&
|
43
|
+
(from_file - to_file).abs == 3
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns true if move represents a king-side castle, false otherwise.
|
47
|
+
def king_castle?
|
48
|
+
return valid? && ChessRB::Piece.new(@board.piece_on(@to)).type == 'k' &&
|
49
|
+
(from_file - to_file).abs == 2
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns true if move results in a capture, false otherwise.
|
53
|
+
def capture?
|
54
|
+
return valid? && @board.piece_on(@to) != 0
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the rank of a given square
|
58
|
+
def self.rank(square)
|
59
|
+
return square[1].to_i
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns rank of this move's @to square
|
63
|
+
def to_rank
|
64
|
+
return self.rank(@to)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns rank of this move's @from square
|
68
|
+
def from_rank
|
69
|
+
return self.rank(@from)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the file of a given square as a number (e.g., a = 1, b = 2, ...)
|
73
|
+
def self.file(square)
|
74
|
+
return FILE_TO_NUM.index(square[0])
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns file of this move's @to square
|
78
|
+
def to_file
|
79
|
+
return self.file(@to)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns file of this move's @from square
|
83
|
+
def from_file
|
84
|
+
return self.file(@from)
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class ChessRB::Notation
|
2
|
+
def self.square_to_algebraic(move)
|
3
|
+
board = move.board
|
4
|
+
piece = ChessRB::Piece.new(board.piece_on(move.from))
|
5
|
+
san = ""
|
6
|
+
|
7
|
+
raise ArgumentError.new "Invalid move and/or position" if !move.valid? ||
|
8
|
+
!board.valid?
|
9
|
+
|
10
|
+
|
11
|
+
if move.queen_castle?
|
12
|
+
san = "O-O-O"
|
13
|
+
elsif move.king_castle?
|
14
|
+
san = "O-O"
|
15
|
+
else
|
16
|
+
if piece.type == 'p'
|
17
|
+
if move.capture?
|
18
|
+
san = file_to_char(move.from_file)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
san += piece.type.upcase
|
22
|
+
# test ambiguities
|
23
|
+
# file
|
24
|
+
# rank
|
25
|
+
# both
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
if move.capture?
|
30
|
+
san += "x"
|
31
|
+
end
|
32
|
+
|
33
|
+
san += move.to
|
34
|
+
|
35
|
+
san += "=#{move.promotion}" if move.promotion
|
36
|
+
|
37
|
+
=begin
|
38
|
+
board.make_move(move)
|
39
|
+
if (board.check?)
|
40
|
+
san += board.mate? ? "#" : "+"
|
41
|
+
end
|
42
|
+
board.undo_move(move)
|
43
|
+
=end
|
44
|
+
|
45
|
+
return san
|
46
|
+
end
|
47
|
+
|
48
|
+
# TODO
|
49
|
+
def self.algebraic_to_square(move)
|
50
|
+
return move.square
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class ChessRB::Piece
|
2
|
+
WP = 1; WN = 2; WLB = 3; WDB = 4; WR = 5; WQ = 6; WK = 7
|
3
|
+
BP = 11; BN = 12; BLB = 13; BDB = 14; BR = 15; BQ = 16; BK = 17
|
4
|
+
|
5
|
+
attr_accessor :code
|
6
|
+
|
7
|
+
def initialize(code)
|
8
|
+
@code = code
|
9
|
+
end
|
10
|
+
|
11
|
+
def type
|
12
|
+
self.to_desc[-1, 1]
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_desc
|
16
|
+
return ChessRB::Piece.constants.select{
|
17
|
+
|v| ChessRB::Piece.const_get(v) == @code }[0].to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s(p, d)
|
21
|
+
case @code
|
22
|
+
when WP
|
23
|
+
d ? "♟" : "♙"
|
24
|
+
when WN
|
25
|
+
d ? "♞" : "♘"
|
26
|
+
when WLB
|
27
|
+
d ? "♝" : "♗"
|
28
|
+
when WDB
|
29
|
+
d ? "♝" : "♗"
|
30
|
+
when WR
|
31
|
+
d ? "♜" : "♖"
|
32
|
+
when WQ
|
33
|
+
d ? "♛" : "♕"
|
34
|
+
when WK
|
35
|
+
d ? "♚" : "♔"
|
36
|
+
when BP
|
37
|
+
d ? "♙" : "♟"
|
38
|
+
when BN
|
39
|
+
d ? "♘" : "♞"
|
40
|
+
when BLB
|
41
|
+
d ? "♗" : "♝"
|
42
|
+
when BDB
|
43
|
+
d ? "♗" : "♝"
|
44
|
+
when BR
|
45
|
+
d ? "♖" : "♜"
|
46
|
+
when BQ
|
47
|
+
d ? "♕" : "♛"
|
48
|
+
when BK
|
49
|
+
d ? "♔" : "♚"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class ChessRB::Position
|
2
|
+
attr_accessor :fen
|
3
|
+
|
4
|
+
def initialize(fen)
|
5
|
+
@fen = fen
|
6
|
+
@fen_components = fen.split(' ')
|
7
|
+
@board = fen_to_board(fen)
|
8
|
+
end
|
9
|
+
|
10
|
+
# TODO
|
11
|
+
def valid?
|
12
|
+
return true
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the piece code on the given square
|
16
|
+
def piece_on(square)
|
17
|
+
file = ChessRB::Move.file(square)
|
18
|
+
rank = ChessRB::Move.rank(square)
|
19
|
+
return @board[8 - rank][file - 1]
|
20
|
+
end
|
21
|
+
|
22
|
+
# TODO
|
23
|
+
def check?
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO
|
28
|
+
def mate?
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s(dark_background = true)
|
33
|
+
str = ""
|
34
|
+
board.each_with_index do |r, i|
|
35
|
+
str += (8 - i).to_s + "║"
|
36
|
+
r.each do |s|
|
37
|
+
str += " "
|
38
|
+
if s == 0
|
39
|
+
str += "…"
|
40
|
+
else
|
41
|
+
str += ChessRB::Piece.code_to_s(s, dark_background)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
str += "\n"
|
45
|
+
end
|
46
|
+
str += " ╚════════════════\n A B C D E F G H"
|
47
|
+
return str
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def fen_to_board(f)
|
53
|
+
board = Array.new(8) {Array.new(8,0)}
|
54
|
+
rows = f.split(' ')[0].split('/')
|
55
|
+
rows.each_with_index do |r, i|
|
56
|
+
j = 0
|
57
|
+
r.each_char do |c|
|
58
|
+
if c.to_i != 0
|
59
|
+
j += c.to_i
|
60
|
+
else
|
61
|
+
color = /[[:upper:]]/.match(c) ? 'W' : 'B'
|
62
|
+
if c.upcase == 'B'
|
63
|
+
c = i + j % 2 == 0 ? 'DB' : 'LB'
|
64
|
+
end
|
65
|
+
board[i][j] = ChessRB::Piece.const_get(color + c.upcase)
|
66
|
+
j += 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
return board
|
71
|
+
end
|
72
|
+
end
|
data/lib/chess_rb.rb
ADDED
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chess_rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sabar Dasgupta
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Chess functions written in Ruby
|
14
|
+
email: sabar.dasgupta@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/chess_rb.rb
|
20
|
+
- lib/chess_rb/move.rb
|
21
|
+
- lib/chess_rb/notation.rb
|
22
|
+
- lib/chess_rb/piece.rb
|
23
|
+
- lib/chess_rb/position.rb
|
24
|
+
homepage: http://rubygems.org/gems/chess_rb
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 2.2.2
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Ruby chess library
|
48
|
+
test_files: []
|