## My first PY project | Chess Game

For the discussion of Perl, Python, Ruby, and PHP and other interpreted languages.

### My first PY project | Chess Game

Hello everybody ...
Since this is my first post, I'll introduce myself briefly. I'm Hell ClaN, Egypt, 17, started learning VB about a year ago as a hobby and made some simple app.s . Just started to git into hacking, programming, web designing, etc, couple of months ago. Kept reading on HTS since 3 months but I've just registered.
---------
I've recently finished my first program in PY. It's a chess game involving board grid and all the game rules. It just needs a GUI, so I decided to learn pyQt to do that. But till now the game is drawn in text with a label for each piece. The code is in python 3. I don't know what are the differences between 2 and 3, so maybe you should edit it if you have python 2. I tried to make my code clear as much as possible, but if you find something ambiguous, just tell and I'll explain. So, here is the code :

*** Got to explain that the plot is a list of 64 characters representing a 8x8 board. Each list item hold whether an object "piece" or None.

Code: Select all

### ~~ My Chess v 1.0 - 2011 ~~ ###
###----------------------------------------------------------------------------------------------------------------------###

# Here goes our imports ...
from math import fabs
import sys
from time import sleep

# Here goes our vars ...
global plot
global turn_is_white
global white_pieces
global cap_white_pieces
global black_pieces
global cap_black_pieces

# Here goes our functions ...
def get_position(position_of_piece):   # Changes the Letter/Number co-ordinates to index in Plot
alpha_list = ['a','b','c','d','e','f','g','h']
position = ((int(position_of_piece[1]) - 1) * 8) + alpha_list.index(position_of_piece[0])
del alpha_list
return position

def get_alpha_num(plot_index):   # Changes index in Plot to Letter/Number co-ordinates
a = plot_index % 8
n = int(plot_index / 8)
alpha_list = ['a','b','c','d','e','f','g','h']
num_list = ['1','2','3','4','5','6','7','8']
return alpha_list[a] + num_list[n]

def get_num(position_of_piece):   # Gets the index of the row (zero-based)
position = get_position(position_of_piece)
num = int((position - (position % 8)) / 8)
return num

def get_alpha(position_of_piece):   # Gets the index of column (zero-based)
position = get_position(position_of_piece)
alpha = position % 8
return alpha

def get_piece_type(position_of_piece):   # Gets the attribute "Type" from the piece object on plot in (position_of_piece)
position = get_position(position_of_piece)
return plot[position].type

def get_piece_color(position_of_piece):  # Gets the attribute "Color" from the piece object on plot in (position_of_piece)
position = get_position(position_of_piece)
return plot[position].color

def check_input(input_command):   # Checks that the input is understandable to the program. Return False if it's not
x = input_command.split(' ')  # the input will be like this : (A3 move D4)
if len(x) != 3:
return False
else:
x0 = x[0]; x1 = x[1]; x2 = x[2]
alpha_list = ['a','b','c','d','e','f','g','h']
num_list = ['1','2','3','4','5','6','7','8']
com_list = ['move','capture','castle']
if alpha_list.count(x0[0].lower()) != 1 or num_list.count(x0[1]) != 1 :
return False
elif com_list.count(x1.lower()) != 1 :
return False
elif alpha_list.count(x2[0].lower()) != 1 or num_list.count(x2[1]) != 1 :
return False
else :
return True

def is_line(point_1, point_2):   # Returns True if the two points are ends of a straight line
if point_1 == point_2 :
return False
elif get_alpha(point_1) == get_alpha(point_2):
return True
elif get_num(point_1) == get_num(point_2):
return True
elif fabs((get_num(point_1) - get_num(point_2))) == fabs((get_alpha(point_1) - get_alpha(point_2))):
return True
else :
return False

def get_line_prop(point_1, point_2):   # Gets a list of line properties
prop = []
# Property [0] : Get orientation of the line ...
if get_alpha(point_1) == get_alpha(point_2) :
prop.append('v')
elif get_num(point_1) == get_num(point_2) :
prop.append('h')
else :
prop.append('d')
# Property [1] : Get direction of line ...
ddd = ''
if get_num(point_1) < get_num(point_2) :
ddd = 'u'
elif get_num(point_1) > get_num(point_2) :
ddd = 'd'
if get_alpha(point_1) < get_alpha(point_2) :
ddd = ddd + 'r'
elif get_alpha(point_1) > get_alpha(point_2) :
ddd = ddd + 'l'
prop.append(ddd)
# Property [2] : Get length of the line ...
if prop[0] == 'v' :
prop.append(int(fabs(get_num(point_1) - get_num(point_2))))
else :
prop.append(int(fabs(get_alpha(point_1) - get_alpha(point_2))))
return prop

def distance_is_clear(current_position, target_position):   # Returns True if the line between two points is clear
x = 0                                                   # Note: the end points are excluded
d = get_line_prop(current_position, target_position)[1] # i.e. if a piece is at target_position, but way is clear, ruturn True
l = get_line_prop(current_position, target_position)[2]
for i in range(1, int(l)):
if d.count('r') == 1 :
x = x + 1
elif d.count('l') == 1 :
x = x - 1
if d.count('u') == 1 :
x = x + 8
elif d.count('d') == 1 :
x = x - 8
if plot[get_position(current_position) + x] != None :
return False
return True

def move_is_possible(current_position, target_position):   # Makes sure that the piece can make a move to location
if plot[get_position(current_position)] == None :
return False
p = get_line_prop(current_position, target_position)
d = distance_is_clear(current_position, target_position)
l = is_line(current_position, target_position)
pType = get_piece_type(current_position)
if (get_piece_color(current_position) == 'white')!= turn_is_white :
return False
elif plot[get_position(target_position)] != None:
return False
else:
if pType == 'pawn':
if (turn_is_white == False and p[1] != 'd') or (turn_is_white == True and p[1] != 'u'):
return False
elif ((turn_is_white == False and get_num(current_position) == 6) or
(turn_is_white == True and get_num(current_position) == 1)) and p[2] > 2 :
return False
elif ((turn_is_white == False and get_num(current_position) != 6) or
(turn_is_white == True and get_num(current_position) != 1)) and p[2] != 1 :
return False
elif d == False:
return False
elif l == False :
return False
else :
return True
elif pType == 'rook':
if d == False :
return False
elif l == False :
return False
elif p[0] == 'd' :
return False
else :
return True
elif pType == 'bishop':
if d == False :
return False
elif l == False :
return False
elif p[0] != 'd' :
return False
else :
return True
elif pType == 'queen' :
if d == False :
return False
elif l == False :
return False
else :
return True
elif pType == 'king' :
if d == False :
return False
elif l == False :
return False
elif p[2] != 1 :
return False
else :
return True
elif pType == 'knight' :
if (fabs(get_num(current_position) - get_num(target_position)) == 2 and
fabs(get_alpha(current_position) - get_alpha(target_position)) == 1) == False and (fabs(get_num(current_position) - get_num(target_position)) == 1 and
fabs(get_alpha(current_position) - get_alpha(target_position)) == 2) == False :
return False
else :
return True

def capture_is_possible(current_position, target_position):   # Makes sure a piece can capture another at location
p = get_line_prop(current_position, target_position)
d = distance_is_clear(current_position, target_position)
pType = get_piece_type(current_position)
l = is_line(current_position, target_position)
if (get_piece_color(current_position) == 'white') != turn_is_white :
return False
elif plot[get_position(target_position)] == None:
return False
elif (get_piece_color(target_position) == 'white') == turn_is_white :
return False
else:
if pType == 'pawn':
if (turn_is_white == False and ['dr','dl'].count(p[1]) != 1) or (turn_is_white == True and ['ur','ul'].count(p[1]) != 1):
return False
elif l == False :
return False
elif p[2] != 1 :
return False
elif d == False:
return False
else :
return True
elif pType == 'rook':
if d == False :
return False
elif l == False :
return False
elif p[0] == 'd' :
return False
else :
return True
elif pType == 'bishop':
if d == False :
return False
elif l == False :
return False
elif p[0] != 'd' :
return False
else :
return True
elif pType == 'queen' :
if d == False :
return False
elif l == False :
return False
else :
return True
elif pType == 'king' :
if d == False :
return False
elif l == False :
return False
elif p[2] != 1 :
return False
else :
return True
elif pType == 'knight' :
if (fabs(get_num(current_position) - get_num(target_position)) == 2 and
fabs(get_alpha(current_position) - get_alpha(target_position)) == 1) == False and (fabs(get_num(current_position) - get_num(target_position)) == 1 and
fabs(get_alpha(current_position) - get_alpha(target_position)) == 2) == False :
return False
else :
return True

def move_capture(current_position, target_position):   # Makes the move/capture after program makes sure the move/capture is leagal
if get_piece_type(current_position) == 'king' or get_piece_type(current_position) == 'rook' :
plot[get_position(current_position)].has_moved = True
if plot[get_position(target_position)] != None :
if turn_is_white == True:
cap_black_pieces.append(black_pieces.pop(black_pieces.index(plot[get_position(target_position)])))
else :
cap_white_pieces.append(white_pieces.pop(white_pieces.index(plot[get_position(target_position)])))
plot[get_position(target_position)] = plot[get_position(current_position)]
plot[get_position(current_position)] = None

def castle_is_possible(current_position, target_position):  # Checks if castling is possible
if plot[get_position(current_position)] == None :
return False
elif get_piece_type(current_position) != 'king' :
return False
elif plot[get_position(current_position)].has_moved == True :
return False
elif (get_piece_color(current_position) == 'white') != turn_is_white :
return False
elif is_line(current_position, target_position) == False:
return False
elif get_line_prop(current_position, target_position)[0] != 'h':
return False
elif get_line_prop(current_position, target_position)[2] != 2 :
return False
else :
if get_line_prop(current_position, target_position)[1] == 'r' :
if turn_is_white == False :
x = 'h8'
else :
x = 'h1'
else :
if turn_is_white == False :
x = 'a8'
else :
x = 'a1'
if distance_is_clear(current_position, x) == False:
return False
elif plot[get_position(x)] != 'rook' :
return False
elif plot[get_position(x)].has_moved == True :
return False
else :
return True

def castle(current_position, target_position):   # Makes a castle move
k = plot[get_position(current_position)]
move_capture(current_position, target_position)
if get_line_prop(current_position, target_position)[1] == 'r' :
plot[plot.index(k) - 1] = plot[get_position(x)]
else :
plot[plot.index(k) + 1] = plot[get_position(x)]
plot[get_position(x)] = None

def player_is_checked():   # Returns True if the player with the current turn is checked
if turn_is_white == False:
x = get_alpha_num(plot.index(b_king))
for white_piece in white_pieces:
if capture_is_possible(get_alpha_num(white_piece.location()), x) == True:
return True
return False
else :
x = get_alpha_num(plot.index(w_king))
for black_piece in black_pieces:
if capture_is_possible(get_alpha_num(black_piece.location()), x) == True:
return True
return False

def player_willbe_checked(current_position, target_position, command):   # Makes a mock test, whether after the move the king will be checked or not
p = []
p.extend(plot)
t = plot[get_position(target_position)]
check = False
if command == 'm' or command == 'c' :
move_capture(current_position, target_position)
elif command == 's' :
castle(current_position, target_position)
if player_is_checked() == True :
check = True
while len(plot) != 0 :
plot.remove(plot[0])
plot.extend(p)
if t != None :
if turn_is_white == True :
black_pieces.append(cap_black_pieces.pop(cap_black_pieces.index(t)))
else :
white_pieces.append(cap_white_pieces.pop(cap_white_pieces.index(t)))
return check

def player_is_stalemated():   # Checks if the player is stalemated
if player_is_checked() == True :
return False
else :
dirs = [8, 9, 1, -7, -8, -9, -1, 7]
if turn_is_white == True :
if white_pieces != [w_king] :
return False
else :
for i in dirs :
if player_willbe_checked(w_king.location(), w_king.location() + i, 'm') != True :
return False
return True
else :
if black_pieces != [b_king] :
return False
else :
for i in dirs :
if player_willbe_checked(b_king.location(), b_king.location() + i, 'm') != True :
return False
return True

def player_is_mated():   # Checks if the player is mated
if player_is_checked != True :
return False
g = get_alpha_num
# Check that king can't make any move ...
# if he can, return False ...
dirs = [8, 9, 1, -7, -8, -9, -1, 7]
if turn_is_white == True :
for i in dirs :
if player_willbe_checked(w_king.location(), w_king.location() + i, 'm') != True :
return False
else :
for i in dirs :
if player_willbe_checked(b_king.location(), b_king.location() + i, 'm') != True :
return False
# Assign a variable to the piece ...
# which is checking the king ...
thret = []
if turn_is_white == True :
for bbb in black_pieces :
turn_is_white = False
if captuer_is_possible(g(bbb.location()), g(w_king.location())) == True :
threat.append(bbb)
turn_is_white == True
else :
for www in black_pieces :
turn_is_white = True
if captuer_is_possible(g(www.location()), g(b_king.location())) == True :
threat.append(www)
turn_is_white == False
# Check that no piece can capture the one ...
# that has checked the king ...
if len(threat) == 1 :
if turn_is_white == True :
for w in white_pieces :
if capture_is_possible(g(w.location()), g(threat[0].location())) == True :
if player_willbe_checked(g(w.location()), g(threat[0].location()), 'c') == False :
return False
else :
for b in black_pieces :
if capture_is_possible(g(b.location()), g(threat[0].location())) == True :
if player_willbe_checked(g(b.location()), g(threat[0].location()), 'c') == False :
return False
# Check that no piece can intercept ...
# the way between the king and piece ...
# that has checked the king ...
if len(threat) == 1 :
dist = []
x = 0
d = get_line_prop(current_position, target_position)[1]
l = get_line_prop(current_position, target_position)[2]
for i in range(1, int(l)):
if d.count('r') == 1 :
x = x + 1
elif d.count('l') == 1 :
x = x - 1
if d.count('u') == 1 :
x = x + 8
elif d.count('d') == 1 :
x = x - 8
dist.append(g(plot[get_position(current_position) + x]))
if turn_is_white == True :
for ww in white_pieces :
for loc in dist :
if move_is_possible(g(ww.location()), loc) == True :
if player_willbe_checked(g(ww.location()), loc, 'm') == False :
return False
else :
for bb in white_pieces :
for loc in dist :
if move_is_possible(g(bb.location()), loc) == True :
if player_willbe_checked(g(bb.location()), loc, 'm') == False :
return False
return True

def pl(location):  # A function to get the label of a piece on Plot to draw it on the board
if plot[get_position(location)] == None :
return '   '
else :
return plot[get_position(location)].label

# Here goes our classes ...
class piece():   # Main class of all pieces ...
def __init__(self, c, t):
self.color = c
self.type = t
self.label = c[0] + t[0:2]   # Label is conssisting of 3 letters, Color, and first two of the Type; i.e. wpa
if t == 'king' or t == 'rook':
self.has_moved = False
def location(self):   # A method to return the location of piece in a Plot-Index format
return plot.index(self)

# Start game ...
while True:
# This is the programe loop. When break out of it, excec stops.
# When loop, a new game is started and variables are initialized.

print('New Game !!')
turn_is_white = True

b_king = piece('black','king') ; w_king = piece('white','king')
b_queen1 = piece('black', 'queen') ; w_queen1 = piece('white', 'queen')
b_bishop1 = piece('black', 'bishop') ; w_bishop1 = piece('white', 'bishop')
b_bishop2 = piece('black', 'bishop') ; w_bishop2 = piece('white', 'bishop')
b_knight1 = piece('black', 'knight') ; w_knight1 = piece('white', 'knight')
b_knight2 = piece('black', 'knight') ; w_knight2 = piece('white', 'knight')
b_rook1 = piece('black', 'rook') ; w_rook1 = piece('white', 'rook')
b_rook2 = piece('black', 'rook') ; w_rook2 = piece('white', 'rook')
b_pawn1 = piece('black', 'pawn') ; w_pawn1 = piece('white', 'pawn')
b_pawn2 = piece('black', 'pawn') ; w_pawn2 = piece('white', 'pawn')
b_pawn3 = piece('black', 'pawn') ; w_pawn3 = piece('white', 'pawn')
b_pawn4 = piece('black', 'pawn') ; w_pawn4 = piece('white', 'pawn')
b_pawn5 = piece('black', 'pawn') ; w_pawn5 = piece('white', 'pawn')
b_pawn6 = piece('black', 'pawn') ; w_pawn6 = piece('white', 'pawn')
b_pawn7 = piece('black', 'pawn') ; w_pawn7 = piece('white', 'pawn')
b_pawn8 = piece('black', 'pawn') ; w_pawn8 = piece('white', 'pawn')

plot = [w_rook1,w_knight1,w_bishop1,w_queen1,w_king,w_bishop2,w_knight2,w_rook2,
w_pawn1,w_pawn2,w_pawn3,w_pawn4,w_pawn5,w_pawn6,w_pawn7,w_pawn8,
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
b_pawn1,b_pawn2,b_pawn3,b_pawn4,b_pawn5,b_pawn6,b_pawn7,b_pawn8,
b_rook1,b_knight1,b_bishop1,b_queen1,b_king,b_bishop2,b_knight2,b_rook2]

white_pieces = [w_rook1,w_knight1,w_bishop1,w_queen1,w_king,w_bishop2,w_knight2,w_rook2,
w_pawn1,w_pawn2,w_pawn3,w_pawn4,w_pawn5,w_pawn6,w_pawn7,w_pawn8]

black_pieces = [b_pawn1,b_pawn2,b_pawn3,b_pawn4,b_pawn5,b_pawn6,b_pawn7,b_pawn8,
b_rook1,b_knight1,b_bishop1,b_queen1,b_king,b_bishop2,b_knight2,b_rook2]

cap_white_pieces = []; cap_black_pieces = []

while True:
# Game actions go here ...

print (' ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗')
print ('8║'+pl('a8')+'║'+pl('b8')+'║'+pl('c8')+'║'+pl('d8')+'║'+pl('e8')+'║'+pl('f8')+'║'+pl('g8')+'║'+pl('h8')+'║')
print (' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣')
print ('7║'+pl('a7')+'║'+pl('b7')+'║'+pl('c7')+'║'+pl('d7')+'║'+pl('e7')+'║'+pl('f7')+'║'+pl('g7')+'║'+pl('h7')+'║')
print (' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣')
print ('6║'+pl('a6')+'║'+pl('b6')+'║'+pl('c6')+'║'+pl('d6')+'║'+pl('e6')+'║'+pl('f6')+'║'+pl('g6')+'║'+pl('h6')+'║')
print (' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣')
print ('5║'+pl('a5')+'║'+pl('b5')+'║'+pl('c5')+'║'+pl('d5')+'║'+pl('e5')+'║'+pl('f5')+'║'+pl('g5')+'║'+pl('h5')+'║')
print (' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣')
print ('4║'+pl('a4')+'║'+pl('b4')+'║'+pl('c4')+'║'+pl('d4')+'║'+pl('e4')+'║'+pl('f4')+'║'+pl('g4')+'║'+pl('h4')+'║')
print (' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣')
print ('3║'+pl('a3')+'║'+pl('b3')+'║'+pl('c3')+'║'+pl('d3')+'║'+pl('e3')+'║'+pl('f3')+'║'+pl('g3')+'║'+pl('h3')+'║')
print (' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣')
print ('2║'+pl('a2')+'║'+pl('b2')+'║'+pl('c2')+'║'+pl('d2')+'║'+pl('e2')+'║'+pl('f2')+'║'+pl('g2')+'║'+pl('h2')+'║')
print (' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣')
print ('1║'+pl('a1')+'║'+pl('b1')+'║'+pl('c1')+'║'+pl('d1')+'║'+pl('e1')+'║'+pl('f1')+'║'+pl('g1')+'║'+pl('h1')+'║')
print (' ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝')
print ('   A   B   C   D   E   F   G   H')

_pass_ = False
if player_is_stalemated() == True :
print ("Stalemate !! It's a draw")
x = input ('Play Again ??!')
if x.lower() == 'y' :
break
else :
sys.exit()
elif player_is_mated() == True :
if turn_is_white == True :
print('Black Wins !!')
else :
print('White Wins !!')
x = input ('Play Again ??!')
if x.lower() == 'y' :
break
else :
sys.exit()
elif player_is_checked() == True :
print('Check')
if turn_is_white == True :
print("White's Turn ...")
else :
print("Black's Turn ...")
inp = input('>> ')
if check_input(inp) == False :
print('wrong input')
_pass_ = True
pass
else :
inp = inp.split(' ')
l1 = inp[0]
l2 = inp[2]
if inp[1] == 'move' :
if move_is_possible(l1, l2) == False :
print("move isn't possible")
_pass_ = True
pass
elif player_willbe_checked(l1, l2, 'm') == True :
print("move isn't possible; king may be captured")
_pass_ = True
pass
else :
move_capture(l1, l2)
elif inp[1] == 'capture' :
if capture_is_possible(l1, l2) == False :
print("capture isn't possible")
_pass_ = True
pass
elif player_willbe_checked(l1, l2, 'c') == True :
print("capture isn't possible; king may be captured")
_pass_ = True
pass
else :
move_capture(l1, l2)
elif inp[1] == 'castle' :
if castle_is_possible(l1, l2) == False :
print("castle isn't possible")
_pass_ = True
pass
elif player_willbe_checked(l1, l2, 's') == True :
print("castle isn't possible; king may be captured")
_pass_ = True
pass
else :
castle(l1, l2)
if _pass_ == False :
turn_is_white = not turn_is_white   # Changes the turn to the other player ...

_____________________________________

So, please test it and comment. Post me Bug-reports if found.
I'm willing to learn pyQt soon and post the new graphical-user-interface edition.
Thanks for all ...
Hell ClaN
New User

Posts: 2
Joined: Sun Sep 11, 2011 4:06 am
Blog: View Blog (0)