-
Notifications
You must be signed in to change notification settings - Fork 0
/
chess_game.py
160 lines (118 loc) · 5.34 KB
/
chess_game.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import copy
import utils
import input_parser
import chess_board
import chess_moves as cm
import chess_validator as validator
class ChessGame(object):
column_names = utils.COLUMN_NAMES
line_names = utils.LINE_NAMES
player = 'white'
def __init__(self):
self.board = chess_board.ChessBoard()
self.player = 'white'
def run(self, play_generator = None):
stay_in_game = True
while(stay_in_game):
self.board.print_board()
stay_in_game = self.read_user_move(play_generator)
def is_match(self):
return len(self.board.king_w)>0 and len(self.board.king_b)>0
def restart(self):
self.__init__()
print "New Game!"
def hit_endgame(self):
if not self.board.Rules.can_opponent_keep_playing(self.board,self.player):
opponent = 'black' if (self.player == 'white') else 'white'
if self.board.Rules.is_king_under_attack(self.board,opponent):
print "Game over\n FATALITY (check-mate), %s wins! "%self.player
else:
print "Game over\n FATALITY (stalemate), no one wins!! "
return True
return False
def read_user_move(self, play_generator = None):
print "%s player's turn." % self.player
if play_generator is None:
try:
new_move = raw_input("Please enter a new move: (type 'q' to quit the game) \n")
except EOFError:
print "Quitting"
return False
else:
try:
new_move = play_generator.next()
except StopIteration:
new_move = 'q'
return self.parse_user_move(new_move)
def has_quit(self, input_move):
return input_move == "q"
def parse_user_move(self, input_move):
# TODO: Handle draws (50+ moves without exchange, or same state repeated 3 times)
input_move = input_move.strip()
if self.has_quit(input_move):
return False
if len(input_move)>1 and cm.is_check(input_move):
input_move = input_move[:-1]
if not validator.is_user_move_valid(input_move):
return True
promotion,input_move,promoted_to = cm.is_promotion(input_move)
move_to_col,move_to_line,col_filter,line_filter = input_parser.parse_coordinates(input_move)
parallel_board = copy.deepcopy(self.board)
accepted_move = self.move_piece_to(input_move, move_to_col, move_to_line, col_filter, line_filter)
if promotion:
self.board.promote( move_to_col, move_to_line, self.player, promoted_to )
if self.board.Rules.is_king_under_attack(self.board,self.player):
print "Cannot leave %s player in check!"%self.player
accepted_move = False
self.board = parallel_board
if accepted_move:
self.print_move(input_move, move_to_col, move_to_line)
if self.is_match() and self.hit_endgame():
return False
else:
self.switch_player()
if cm.is_special_case(input_move):
self.restart()
return True
def switch_player(self):
self.player = 'black' if (self.player == 'white') else 'white'
return
def move_piece_to(self, input_move, move_to_col, move_to_line, col_filter = None, line_filter = None):
if cm.is_castling(input_move):
if cm.is_short_castling(input_move):
return self.board.castler(self.player,'short')
else:
return self.board.castler(self.player,'long')
kind = input_parser.input_to_kind(input_move)
if kind is None:
return False
if input_parser.piece_eats(input_move):
return self.board.piece_eater(kind, move_to_col,move_to_line,self.player, orig_col_filter = col_filter, orig_line_filter = line_filter)
else:
return self.board.piece_mover(kind, move_to_col,move_to_line,self.player, orig_col_filter = col_filter, orig_line_filter = line_filter)
def print_move(self, input_move, move_to_col, move_to_line):
out_str = ""
if cm.is_short_castling(input_move):
out_str = "Short castling for %s" % self.player
elif cm.is_long_castling(input_move):
out_str = "long castling for %s" % self.player
elif cm.is_pawn(input_move):
out_str = "Move %s pawn" % self.player
elif cm.is_bishop(input_move):
out_str = "Move %s bishop" % self.player
elif cm.is_knight(input_move):
out_str = "Move %s knight" % self.player
elif cm.is_rook(input_move):
out_str = "Move %s rook" % self.player
elif cm.is_king(input_move):
out_str = "Move %s king" % self.player
elif cm.is_queen(input_move):
out_str = "Move %s queen" % self.player
else:
out_str = "not supported move. Merry Xmas"
if not cm.is_castling(input_move):
if input_parser.piece_eats(input_move):
out_str = out_str + " and capture piece at (%s,%s)" % (move_to_col,move_to_line)
else:
out_str = out_str + " to (%s,%s)" % (move_to_col, move_to_line)
print("Your move is : " + input_move + '. ' + out_str)