chess_game 0.0.11

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 843385b83bf123c7fc2b76d4612eebba1593b383
4
+ data.tar.gz: 8b448e09cd5eae1c95530a4cc350bbaa09f6c371
5
+ SHA512:
6
+ metadata.gz: eebdb0014b9af53abc0969af0a4d6a7467f3b3c590f73bb104098f6385c7f240ed42d4602121d2342454c7dfc89bdc4690ebefb1ee0b17fd404c37e7daf3c265
7
+ data.tar.gz: 9af5375d92e601c8e96619bb072517fa0c5f8ab0bb23cb445662bacab54751b9e6e94e7a92fb570051f6b9aa1beb20b0de5bfa40bc32458d561029a2f0acdeb4
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+ ruby "2.0.0"
3
+ gem 'rake'
4
+ gem 'rspec'
5
+ gem 'colorize'
6
+ gem 'activesupport'
7
+ gem 'pry'
8
+ gem 'pry-debugger'
data/Gemfile.lock ADDED
@@ -0,0 +1,58 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (4.1.6)
5
+ i18n (~> 0.6, >= 0.6.9)
6
+ json (~> 1.7, >= 1.7.7)
7
+ minitest (~> 5.1)
8
+ thread_safe (~> 0.1)
9
+ tzinfo (~> 1.1)
10
+ coderay (1.1.0)
11
+ colorize (0.7.3)
12
+ columnize (0.8.9)
13
+ debugger (1.6.8)
14
+ columnize (>= 0.3.1)
15
+ debugger-linecache (~> 1.2.0)
16
+ debugger-ruby_core_source (~> 1.3.5)
17
+ debugger-linecache (1.2.0)
18
+ debugger-ruby_core_source (1.3.5)
19
+ diff-lcs (1.2.5)
20
+ i18n (0.6.11)
21
+ json (1.8.1)
22
+ method_source (0.8.2)
23
+ minitest (5.4.2)
24
+ pry (0.10.1)
25
+ coderay (~> 1.1.0)
26
+ method_source (~> 0.8.1)
27
+ slop (~> 3.4)
28
+ pry-debugger (0.2.3)
29
+ debugger (~> 1.3)
30
+ pry (>= 0.9.10, < 0.11.0)
31
+ rake (10.3.2)
32
+ rspec (3.1.0)
33
+ rspec-core (~> 3.1.0)
34
+ rspec-expectations (~> 3.1.0)
35
+ rspec-mocks (~> 3.1.0)
36
+ rspec-core (3.1.7)
37
+ rspec-support (~> 3.1.0)
38
+ rspec-expectations (3.1.2)
39
+ diff-lcs (>= 1.2.0, < 2.0)
40
+ rspec-support (~> 3.1.0)
41
+ rspec-mocks (3.1.3)
42
+ rspec-support (~> 3.1.0)
43
+ rspec-support (3.1.2)
44
+ slop (3.6.0)
45
+ thread_safe (0.3.4)
46
+ tzinfo (1.2.2)
47
+ thread_safe (~> 0.1)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ activesupport
54
+ colorize
55
+ pry
56
+ pry-debugger
57
+ rake
58
+ rspec
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ Command Line Chess
2
+ ==================
3
+
4
+ Play command line chess! Start the game by running "$ ruby lib/chess.rb" from the root directory.
5
+
6
+ You can save the game by typing "save" instead of a move.
7
+
8
+ You can load a game by typing "load" instead of a move.
9
+
10
+ Quit the game by typing "exit" or "quit".
11
+
12
+ Make moves by entering the two squares you want to move a piece from and to in the form '[file][rank] [file][rank]'. For example, to move a starting position pawn as the white palayer, type "D2 D3" or "d2 d3"
13
+
14
+ Castle by moving the King to its final position after castling.
15
+
16
+ Web App
17
+ -------
18
+ This libray is used in the Web App https://github.com/Hawkeye000/sinatra-chess.
19
+
20
+ See this in use at http://hawkeye-chess.herokuapp.com/
21
+
22
+ Dependencies
23
+ ------------
24
+ See Gemfile.
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ Dir.glob('tasks/**/*.rake').each(&method(:import))
data/bin/chess ADDED
@@ -0,0 +1,3 @@
1
+ #!/user/bin/env ruby
2
+ require 'chess'
3
+ Chess.play
data/chess-0.0.11.gem ADDED
Binary file
data/chess.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'chess/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'chess_game'
7
+ spec.version = '0.0.11'
8
+ spec.date = '2014-10-26'
9
+ spec.authors = ["Benjamin Pearce"]
10
+ spec.email = ["hawk.git@bcpearce.com"]
11
+ spec.summary = "Play chess using the command line."
12
+ spec.description = "Contain libraries for setting up and playing games of chess,\
13
+ making and validating moves, and evaluating victory conditionspec."
14
+ spec.homepage = "https://github.com/bcpearce/command-line-chess"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.3'
23
+ spec.add_development_dependency 'rake', '10.3.2'
24
+ spec.add_development_dependency 'rspec', '~> 3.1'
25
+
26
+ spec.add_runtime_dependency 'colorize', '~> 0.7.3'
27
+
28
+
29
+ end
data/game.dat ADDED
Binary file
@@ -0,0 +1,28 @@
1
+ require_relative 'piece.rb'
2
+
3
+ class Bishop < Piece
4
+
5
+ WHITE_BISHOP_ICON = "\u2657"
6
+ BLACK_BISHOP_ICON = "\u265D"
7
+
8
+ def initialize(color = "white", location = "A1")
9
+ case color.downcase
10
+ when "white"
11
+ @icon = WHITE_BISHOP_ICON
12
+ when "black"
13
+ @icon = BLACK_BISHOP_ICON
14
+ end
15
+ super
16
+ end
17
+
18
+ def valid_move?(new_loc, board)
19
+ x, y = new_loc - @location
20
+ if x.abs == y.abs
21
+ else
22
+ board.move_status = "Bishops cannot make that move."
23
+ return false
24
+ end
25
+ super
26
+ end
27
+
28
+ end
@@ -0,0 +1,170 @@
1
+ Dir[File.dirname(__FILE__) + '/*'].each { |file| require file }
2
+ require 'colorize'
3
+
4
+ class Board
5
+
6
+ attr_accessor :move_status
7
+
8
+ def initialize
9
+ @board = Hash.new
10
+ ("A".."H").each do |letter|
11
+ ("1".."8").each do |number|
12
+ loc = "#{letter}#{number}"
13
+ piece =
14
+ if number == "7"
15
+ Pawn.new("black", loc)
16
+ elsif loc == "A8" || loc == "H8"
17
+ Rook.new("black", loc)
18
+ elsif loc == "B8" || loc == "G8"
19
+ Knight.new("black", loc)
20
+ elsif loc == "C8" || loc == "F8"
21
+ Bishop.new("black", loc)
22
+ elsif loc == "D8"
23
+ Queen.new("black", loc)
24
+ elsif loc == "E8"
25
+ King.new("black", loc)
26
+
27
+ elsif number == "2"
28
+ Pawn.new("white", loc)
29
+ elsif loc == "A1" || loc == "H1"
30
+ Rook.new("white", loc)
31
+ elsif loc == "B1" || loc == "G1"
32
+ Knight.new("white", loc)
33
+ elsif loc == "C1" || loc == "F1"
34
+ Bishop.new("white", loc)
35
+ elsif loc == "D1"
36
+ Queen.new("white", loc)
37
+ elsif loc == "E1"
38
+ King.new("white", loc)
39
+ else
40
+ " "
41
+ end
42
+ @board[loc] = piece
43
+ end
44
+ end
45
+ end
46
+
47
+ def set_piece(piece)
48
+ @board[piece.location] = piece
49
+ end
50
+
51
+ def rv_piece(location)
52
+ @board[location] = " " unless @board[location].nil?
53
+ end
54
+
55
+ def board
56
+ @board
57
+ end
58
+
59
+ def [](string)
60
+ @board[string]
61
+ end
62
+
63
+ def each(&block)
64
+ @board.each(&block)
65
+ end
66
+
67
+ def clear
68
+ @board.each { |square, piece| @board[square] = " " }
69
+ end
70
+
71
+ def piece_to_promote?
72
+ @board.each_value do |piece|
73
+ if piece.is_a?(Piece)
74
+ if piece.can_promote?
75
+ return piece
76
+ end
77
+ end
78
+ end
79
+ return nil
80
+ end
81
+
82
+ def promote(loc, new_piece)
83
+ piece = board[loc]
84
+ new_piece = Kernel.const_get(new_piece.capitalize)
85
+ if piece.can_promote?
86
+ if new_piece == Queen || new_piece == Rook \
87
+ || new_piece == Bishop || new_piece == Knight
88
+ promoted = new_piece.new(piece.color, loc)
89
+ promoted.moves = piece.moves
90
+ self.rv_piece(loc)
91
+ self.set_piece(promoted)
92
+ end
93
+ else
94
+ nil
95
+ end
96
+ end
97
+
98
+ def save_board
99
+ @saved_board = Marshal.load(Marshal.dump(@board))
100
+ end
101
+
102
+ def move(loc_1, loc_2)
103
+ return nil if loc_1.nil? || loc_2.nil?
104
+ piece = @board[loc_1]
105
+ self.save_board
106
+
107
+ if piece.move(loc_2, self)
108
+ @board[loc_1] = " "
109
+ old_piece = @board[loc_2]
110
+ self.set_piece(piece)
111
+ rv_piece(self.passed_piece)
112
+ castle_complement(piece, self)
113
+ self.clear_passable(piece.color)
114
+ return loc_2
115
+ else
116
+ return nil
117
+ end
118
+
119
+ end
120
+
121
+ def clear_passable(color)
122
+ @board.each_value { |piece| piece.passable = false if piece.color != color }
123
+ end
124
+
125
+ def passed_piece
126
+ @board.each_value { |piece| return piece.location if piece.passed? && piece.is_a?(Pawn) }
127
+ end
128
+
129
+ def restore_saved_board
130
+ self.clear
131
+ @board = Marshal.load(Marshal.dump(@saved_board))
132
+ end
133
+
134
+ def undo_last_move
135
+ self.restore_saved_board
136
+ end
137
+
138
+ def to_a
139
+ @board.to_a
140
+ end
141
+
142
+ def display
143
+ puts " " + ("A".."H").to_a.join(" ")
144
+ ("1".."8").to_a.reverse.each do |row|
145
+ print row + " "
146
+ ("A".."H").each do |col|
147
+ background =
148
+ if (col.ord + row.to_i).even?
149
+ :black
150
+ else
151
+ :red
152
+ end
153
+ print (@board["#{col}#{row}"].to_s + " ").colorize(:background => background)
154
+ end
155
+ print " #{row}\n"
156
+ end
157
+ puts " " + ("A".."H").to_a.join(" ")
158
+ end
159
+
160
+ def on_board?(loc)
161
+ !@board[loc].nil?
162
+ end
163
+
164
+ def piece_between?(loc_1, loc_2)
165
+ return false if loc_1 == loc_2
166
+ return false if self[loc_1].is_a?(Knight)
167
+ squares_between(loc_1, loc_2).any? { |square| @board[square] != " " }
168
+ end
169
+
170
+ end
data/lib/chess/game.rb ADDED
@@ -0,0 +1,73 @@
1
+ require_relative "board.rb"
2
+ require_relative "player.rb"
3
+
4
+ class Game
5
+
6
+ def initialize
7
+ @board = Board.new
8
+ @white_player = Player.new("white")
9
+ @black_player = Player.new("black")
10
+ @turn = @white_player
11
+ @opponent = @black_player
12
+ @movelist = []
13
+ end
14
+
15
+ def movelist
16
+ @movelist
17
+ end
18
+
19
+ def save(file_name)
20
+ File.open(file_name, 'wb+') do |file|
21
+ Marshal.dump(self, file)
22
+ end
23
+ end
24
+
25
+ def self.load(file_name)
26
+ File.open(file_name) do |file|
27
+ Marshal.load(file)
28
+ end
29
+ end
30
+
31
+ def move(loc_1, loc_2)
32
+ if @board[loc_1].color == @turn.color
33
+ if @turn.move(loc_1, loc_2, @board)
34
+ @turn, @opponent = @opponent, @turn
35
+ @movelist << "#{@board[loc_2].icon} #{loc_1} #{loc_2}"
36
+ end
37
+ else
38
+ nil
39
+ end
40
+ end
41
+
42
+ def board
43
+ @board.board
44
+ end
45
+
46
+ def white_player
47
+ @white_player
48
+ end
49
+
50
+ def black_player
51
+ @black_player
52
+ end
53
+
54
+ def board
55
+ @board
56
+ end
57
+
58
+ def turn
59
+ @turn
60
+ end
61
+
62
+ def opponent
63
+ @opponent
64
+ end
65
+
66
+ def turn=(turn)
67
+ @turn = turn
68
+ end
69
+
70
+ def opponent=(opponent)
71
+ @opponent = opponent
72
+ end
73
+ end
data/lib/chess/king.rb ADDED
@@ -0,0 +1,101 @@
1
+ require_relative 'piece.rb'
2
+
3
+ class King < Piece
4
+
5
+ WHITE_KING_ICON = "\u2654"
6
+ BLACK_KING_ICON = "\u265A"
7
+
8
+ def initialize(color = "white", location = "A1")
9
+ case color.downcase
10
+ when "white"
11
+ @icon = WHITE_KING_ICON
12
+ when "black"
13
+ @icon = BLACK_KING_ICON
14
+ end
15
+ super
16
+ end
17
+
18
+ def valid_move?(new_loc, board)
19
+ x, y = new_loc - @location
20
+ if x.abs <= 1 && y.abs <= 1
21
+ elsif check_castle(self, board, x, y) && !self.check?(board)
22
+ else
23
+ board.move_status = "Kings cannot make that move."
24
+ return false
25
+ end
26
+ super(new_loc, board)
27
+ end
28
+
29
+ def check?(board)
30
+ board.each do |loc, piece|
31
+ if piece.opponent?(self) && piece.valid_move?(@location, board)
32
+ return loc, @location
33
+ end
34
+ end
35
+ return false
36
+ end
37
+
38
+ def checkmate?(board)
39
+ # the king must be in check to be in checkmate
40
+ unless self.check?(board)
41
+ return false
42
+ end
43
+
44
+ kings_men = []
45
+ squares = []
46
+
47
+ # check all possible moves and see if the king is still in check
48
+ board.board.keys.each do |loc_1|
49
+ board.board.keys.each do |loc_2|
50
+ if board[loc_1].friend?(self)
51
+ still_in_check = self.will_be_in_check?(loc_1, loc_2, board)
52
+ if still_in_check.nil?
53
+ next
54
+ elsif !still_in_check
55
+ return false
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ return true
62
+ end
63
+
64
+ def stalemate?(board)
65
+ # the king must be in check to be in checkmate
66
+ if self.check?(board)
67
+ return false
68
+ end
69
+
70
+ kings_men = []
71
+ squares = []
72
+
73
+ # check all possible moves and see if the king is put in check
74
+ board.board.keys.each do |loc_1|
75
+ board.board.keys.each do |loc_2|
76
+ if board[loc_1].friend?(self)
77
+ still_in_check = self.will_be_in_check?(loc_1, loc_2, board)
78
+ if still_in_check.nil?
79
+ next
80
+ elsif still_in_check == false
81
+ return false
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ return true
88
+ end
89
+
90
+ def will_be_in_check?(loc_1, loc_2, board)
91
+ test_board = Marshal.load(Marshal.dump(board))
92
+ test_king = test_board[@location]
93
+ if test_board.move(loc_1, loc_2)
94
+ check = test_king.check?(test_board)
95
+ return check
96
+ else
97
+ return nil
98
+ end
99
+ end
100
+
101
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'piece.rb'
2
+
3
+ class Knight < Piece
4
+
5
+ WHITE_KNIGHT_ICON = "\u2658"
6
+ BLACK_KNIGHT_ICON = "\u265E"
7
+
8
+ def initialize(color = "white", location = "A1")
9
+ case color.downcase
10
+ when "white"
11
+ @icon = WHITE_KNIGHT_ICON
12
+ when "black"
13
+ @icon = BLACK_KNIGHT_ICON
14
+ end
15
+ super
16
+ end
17
+
18
+ def valid_move?(new_loc, board)
19
+ x, y = new_loc - @location
20
+ if (x.abs == 2 && y.abs == 1) || (x.abs == 1 && y.abs == 2)
21
+ else
22
+ board.move_status = "Knights cannot make that move."
23
+ return false
24
+ end
25
+ super
26
+ end
27
+
28
+ end