Skip to content

Commit d580e35

Browse files
committed
Fixed gui, various game validation tweaks
1 parent 4f150ec commit d580e35

28 files changed

+57
-101
lines changed

chesslib/board.py

Lines changed: 23 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# -*- encoding: utf-8 -*-
22
from itertools import groupby
3+
from copy import deepcopy
34

45
import pieces
56
import re
67

78
class ChessError(Exception): pass
89
class InvalidCoord(ChessError): pass
10+
class InvalidColor(ChessError): pass
911
class InvalidMove(ChessError): pass
1012
class Check(ChessError): pass
1113
class CheckMate(ChessError): pass
@@ -65,12 +67,13 @@ def __getitem__(self, coord):
6567
except KeyError:
6668
return None
6769

68-
def check_for_check_after_move(self, p):
70+
def save_to_file(self): pass
71+
72+
def is_in_check_after_move(self, p1, p2):
6973
# Create a temporary board
70-
p1,p2 = p
71-
tmp = Board(self.export())
74+
tmp = deepcopy(self)
7275
tmp._do_move(p1,p2)
73-
return self.is_in_check(self[p1].color)
76+
return tmp.is_in_check(self[p1].color)
7477

7578
def move(self, p1, p2):
7679
p1, p2 = p1.upper(), p2.upper()
@@ -84,46 +87,20 @@ def move(self, p1, p2):
8487
possible_moves = piece.possible_moves(p1)
8588
# 0. Check if p2 is in the possible moves
8689
if p2 not in possible_moves:
87-
raise InvalidMove
90+
raise InvalidMove
8891

8992
# If enemy has any moves look for check
9093
if self.all_possible_moves(enemy):
91-
filter(self.check_for_check_after_move, map(lambda p2: (p1,p2), possible_moves))
94+
if self.is_in_check_after_move(p1,p2):
95+
raise Check
9296

9397
if not possible_moves and self.is_in_check(piece.color):
94-
raise CheckMate
98+
raise CheckMate
9599
elif not possible_moves:
96-
raise Draw
100+
raise Draw
97101
else:
98-
self._do_move(p1,p2)
99-
self._finish_move(piece, dest, p1,p2)
100-
101-
'''
102-
# 1. Filter possible moves: remove the ones that will make you in check
103-
# if no possible moves and not in check -- Draw
104-
# if no possible moves and in check -- Checkmate
105-
if enemy_moves:
106-
# Save current state
107-
temporary_board = Board(self.export())
108-
109-
if p2 in piece.possible_moves(p1):
110-
_do_move(p1, p2)
111-
elif not piece.possible_moves(p1):
112-
raise CheckMate(enemy + " wins!")
113-
114-
if is_in_check(piece.get_color()):
115-
# Restore table
116-
table = current_table
117-
raise Check
118-
119-
_finish_move(piece,dest,p1,p2)
120-
121-
elif p2 in piece.possible_moves(p1):
122-
_do_move(p1, p2)
123-
_finish_move(piece,dest,p1,p2)
124-
elif not piece.possible_moves(p1):
125-
raise Draw
126-
'''
102+
self._do_move(p1,p2)
103+
self._finish_move(piece, dest, p1,p2)
127104

128105
def get_enemy(self, color):
129106
if color == "white": return "black"
@@ -186,17 +163,18 @@ def occupied(self, color):
186163
if(color not in ("black", "white")): raise InvalidColor
187164

188165
for coord in self:
189-
if self[coord].color == color: result.append(coord)
166+
if self[coord].color == color:
167+
result.append(coord)
190168
return result
191169

192170
def is_king(self, piece):
193-
return isinstance(piece, pieces.King)
194-
171+
return isinstance(piece, pieces.King)
172+
195173

196174
def get_king_position(self, color):
197-
for pos in self.keys():
198-
if self.is_king(self[pos]) and self[pos].color == color:
199-
return pos
175+
for pos in self.keys():
176+
if self.is_king(self[pos]) and self[pos].color == color:
177+
return pos
200178

201179
def get_king(self, color):
202180
if(color not in ("black", "white")): raise InvalidColor
@@ -209,7 +187,7 @@ def is_in_check(self, color):
209187
return king in map(self.__getitem__, self.all_possible_moves(enemy))
210188

211189
def letter_notation(self,coord):
212-
if not self.is_in_bounds(coord): raise InvalidCoord
190+
if not self.is_in_bounds(coord): return
213191
try:
214192
return self.axis_y[coord[1]] + str(self.axis_x[coord[0]])
215193
except IndexError:
@@ -242,6 +220,7 @@ def load(self, fen):
242220
'''
243221
Import state from FEN notation
244222
'''
223+
self.clear()
245224
# Split data
246225
fen = fen.split(' ')
247226
# Expand blanks

chesslib/boardgui.py

Lines changed: 24 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import board as chessboard
1+
import board
22
import pieces
33
import Tkinter as tk
44
from PIL import Image, ImageTk
55

66
class BoardGUI(tk.Frame):
7-
def __init__(self, parent, rows=8, columns=8, size=32, color1="white", color2="grey"):
7+
def __init__(self, parent, chessboard, rows=8, columns=8, size=32, color1="white", color2="grey"):
88
''' size is the size of a square, in pixels '''
99

10+
self.chessboard = chessboard
1011
self.rows = rows
1112
self.columns = columns
1213
self.size = size
@@ -27,28 +28,18 @@ def __init__(self, parent, rows=8, columns=8, size=32, color1="white", color2="g
2728
width=canvas_width, height=canvas_height, background="grey")
2829
self.canvas.pack(side="top", fill="both", expand=True, padx=2, pady=2)
2930

30-
# this binding will cause a refresh if the user interactively
31-
# changes the window size
32-
self.canvas.bind("<Configure>", self.refresh)
3331
self.canvas.bind("<Button-1>", self.click)
3432

3533
self.button_quit = tk.Button(self, text="New", fg="black", command=self.reset)
3634
self.button_quit.pack(side=tk.LEFT)
37-
self.button_save = tk.Button(self, text="Save", fg="black", command=chessboard.save_to_file)
35+
self.button_save = tk.Button(self, text="Save", fg="black", command=self.chessboard.save_to_file)
3836
self.button_save.pack(side=tk.LEFT)
3937

4038
self.label_status = tk.Label(self, text=" White's turn ", fg="black")
4139
self.label_status.pack(side=tk.LEFT)
4240
self.button_quit = tk.Button(self, text="Quit", fg="black", command=self.close)
4341
self.button_quit.pack(side=tk.RIGHT)
4442

45-
46-
#self.button_load = tk.Button(self, text="Load", fg="black")
47-
#self.button_load.pack(side=tk.RIGHT)
48-
49-
#self.button_save = tk.Button(self, text="Save", fg="black")
50-
#self.button_save.pack(side=tk.RIGHT)
51-
5243
def close(self):
5344
self.parent.destroy()
5445

@@ -58,30 +49,21 @@ def click(self, event):
5849
row = 7-(event.y / row_pix)
5950
# self.label_status["text"] = "%s, %s, %s, %s" % (event.x, event.y, col, row)
6051
self.selected = (row, col)
61-
pos = chessboard.letter_notation(self.selected)
62-
piece = chessboard.get(pos)
63-
if piece is not None and (piece.color == chessboard.player_turn):
52+
pos = self.chessboard.letter_notation(self.selected)
53+
piece = self.chessboard[pos]
54+
if piece is not None and (piece.color == self.chessboard.player_turn):
6455
self.selected_piece = (piece, pos)
65-
self.hilighted = map(chessboard.number_notation, (chessboard.get(pos).possible_moves(pos)))
56+
self.hilighted = map(self.chessboard.number_notation, (self.chessboard[pos].possible_moves(pos)))
6657

6758
if self.selected_piece and ((piece is None) or\
6859
(piece.color != self.selected_piece[0].color)):
6960
# making a move
7061
try:
71-
chessboard.move(self.selected_piece[1], pos)
72-
except chessboard.Check:
73-
self.label_status["text"] = " You are in check!"
74-
except chessboard.CheckMate:
75-
self.label_status["text"] = " Check!"
76-
except chessboard.InvalidMove:
77-
self.label_status["text"] = " Invalid move!"
78-
except chessboard.Draw:
79-
self.label_status["text"] = " Draw!"
80-
except Exception as e:
62+
self.chessboard.move(self.selected_piece[1], pos)
63+
except board.ChessError as e:
8164
self.label_status["text"] = e.__class__.__name__
8265
else:
83-
self.label_status["text"] = " " + self.selected_piece[0].get_color().capitalize() +": "+ self.selected_piece[1]+pos
84-
66+
self.label_status["text"] = " " + self.selected_piece[0].color.capitalize() +": "+ self.selected_piece[1]+pos
8567

8668
self.selected_piece = None
8769
self.hilighted = None
@@ -104,7 +86,7 @@ def placepiece(self, name, row, column):
10486
self.canvas.coords(name, x0, y0)
10587

10688
def refresh(self, event={}):
107-
'''Redraw the board, possibly in response to window being resized'''
89+
'''Redraw the board'''
10890
try:
10991
self.xsize = int((event.width-1) / self.columns)
11092
self.ysize = int((event.height-1) / self.rows)
@@ -135,35 +117,31 @@ def refresh(self, event={}):
135117

136118
def draw_pieces(self):
137119
self.canvas.delete("piece")
138-
for x in range(0,len(chessboard.table)):
139-
for y in range(0,len(chessboard.table[x])):
140-
piece = chessboard.table[x][y]
141-
if piece is not None:
142-
filename = "img/%s%s.png" % (piece.color, piece.abbriviation)
143-
piecename = "%s%s%s" % (piece.abbriviation, x, y)
120+
for coord, piece in self.chessboard.iteritems():
121+
x,y = self.chessboard.number_notation(coord)
122+
if piece is not None:
123+
filename = "img/%s%s.png" % (piece.color, piece.abbriviation.lower())
124+
piecename = "%s%s%s" % (piece.abbriviation, x, y)
144125

145-
if(filename not in self.icons):
146-
self.icons[filename] = ImageTk.PhotoImage(file=filename, width=32, height=32)
126+
if(filename not in self.icons):
127+
self.icons[filename] = ImageTk.PhotoImage(file=filename, width=32, height=32)
147128

148-
self.addpiece(piecename, self.icons[filename], x, y)
149-
self.placepiece(piecename, x, y)
150-
#print chessboard.unicode_representation()
129+
self.addpiece(piecename, self.icons[filename], x, y)
130+
self.placepiece(piecename, x, y)
151131

152132
def reset(self):
153-
chessboard.init()
133+
self.chessboard.load(board.FEN_STARTING)
154134
self.refresh()
155135
self.draw_pieces()
156136
self.refresh()
157137

158-
def display():
138+
def display(chessboard):
159139
root = tk.Tk()
160140
root.title("Simply Chess")
161-
b= BoardGUI(root)
141+
b= BoardGUI(root, chessboard)
162142
b.pack(side="top", fill="both", expand="false", padx=4, pady=4)
163143
b.draw_pieces()
164-
#b.placepiece("bishop", 6, 6)
165144

166-
#b.addpiece("player2", player2, 3,5)
167145
root.resizable(0,0)
168146
root.mainloop()
169147

chesslib/pieces.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ def possible_moves(self, position, orthogonal, diagonal, distance):
6464
for step in range(1, distance+1):
6565
if collision: break
6666
dest = from_[0]+step*x, from_[1]+step*y
67-
if dest not in board.occupied('white') + board.occupied('black'):
67+
if self.board.letter_notation(dest) not in board.occupied('white') + board.occupied('black'):
6868
legal_moves.append(dest)
69-
elif dest in board.occupied(piece.color):
69+
elif self.board.letter_notation(dest) in board.occupied(piece.color):
7070
collision = True
7171
else:
7272
legal_moves.append(dest)
@@ -101,18 +101,18 @@ def possible_moves(self, position):
101101
forward = from_[0] + direction, from_[1]
102102

103103
# Can we move forward?
104-
if forward not in blocked:
104+
if board.letter_notation(forward) not in blocked:
105105
legal_moves.append(forward)
106106
if from_[0] == homerow:
107107
# If pawn in starting position we can do a double move
108-
double_forward = forward[0] + direction, forward[1]
109-
if double_forward not in blocked:
108+
double_forward = (forward[0] + direction, forward[1])
109+
if board.letter_notation(double_forward) not in blocked:
110110
legal_moves.append(double_forward)
111111

112112
# Attacking
113113
for a in range(-1, 2, 2):
114114
attack = from_[0] + direction, from_[1] + a
115-
if attack in board.occupied(enemy):
115+
if board.letter_notation(attack) in board.occupied(enemy):
116116
legal_moves.append(attack)
117117

118118
# TODO: En passant
@@ -132,7 +132,7 @@ def possible_moves(self,position):
132132

133133
for x,y in deltas:
134134
dest = from_[0]+x, from_[1]+y
135-
if(dest not in board.occupied(piece.color)):
135+
if(board.letter_notation(dest) not in board.occupied(piece.color)):
136136
legal_moves.append(dest)
137137

138138
legal_moves = filter(board.is_in_bounds, legal_moves)

game.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66

77
if os.path.exists("state.fen"):
88
with open("state.fen") as save:
9-
board.init()
10-
board.load(save.read())
9+
b = board.Board(save.read())
1110
else:
12-
board.init()
13-
boardgui.display()
11+
b = board.Board()
12+
boardgui.display(b)
1413

1514
## Text Mode
1615

img/0b.png

-1.02 KB
Binary file not shown.

img/0k.png

-1.17 KB
Binary file not shown.

img/0n.png

-1.01 KB
Binary file not shown.

img/0p.png

-686 Bytes
Binary file not shown.

img/0q.png

-1.56 KB
Binary file not shown.

img/0r.png

-691 Bytes
Binary file not shown.

img/1b.png

-692 Bytes
Binary file not shown.

img/1k.png

-1.22 KB
Binary file not shown.

img/1n.png

-822 Bytes
Binary file not shown.

img/1p.png

-432 Bytes
Binary file not shown.

img/1q.png

-1.03 KB
Binary file not shown.

img/1r.png

-547 Bytes
Binary file not shown.

img/blackb.png

-357 Bytes
Loading

img/blackk.png

42 Bytes
Loading

img/blackn.png

-209 Bytes
Loading

img/blackp.png

-254 Bytes
Loading

img/blackq.png

-541 Bytes
Loading

img/blackr.png

-144 Bytes
Loading

img/whiteb.png

357 Bytes
Loading

img/whitek.png

-42 Bytes
Loading

img/whiten.png

209 Bytes
Loading

img/whitep.png

254 Bytes
Loading

img/whiteq.png

541 Bytes
Loading

img/whiter.png

144 Bytes
Loading

0 commit comments

Comments
 (0)