Level Up Coding

Coding tutorials and news. The developer homepage gitconnected.com && skilled.dev && levelup.dev

Follow publication

Making Chess in Python

--

I will first describe what’s happening and then show the code afterward.

This is a large project that me and a friend in school conducted. This is pretty funny because we had plans on doing this over several months and 7 days later we have the entire thing completed. I must say, this would not have been possible if it weren’t for the help of my friend Edwin. Firstly we abstracted the entire game since this is a very complex game to code and we decided that I would be responsible for the interface(what the user can see) while Edwin was responsible for the actual behaviour of each piece. They both have their own forms of difficulties to make and we did have to co-ordinate a lot so it wasn’t like we didn’t help each other make each other’s parts eg. i did teach him a bit of list comprehension to speed up his code while he exposed my pretty stupid mistake of doing column row instead of row column.

This code is everything that I wrote alongside some of the dictionary and methods above it. First we create the window object which is the window that comes up when we run the chess game on. We set the dimensions to 800x800 which is the tuple argument which we passed into it. We specifically chose 800 x 800 because the images for the chess pieces that we hard were all 100x100 which meant it would fit perfectly if the board was 800x800.

The main thing that makes my program work are these node objects and they are just the containers which hold the chess pieces(they are simulated as the tiles of the chess board in this case. They have their attributes which are their row, column,x,y co-ordinates. We need these separately because all these nodes are going to be stored in a 8x8 2d list so if we call it we would need to call it using its row and col numbers while if we were drawing it onto the screen we need its x,y pixel values(we could just do row*100 but that would risk us forgetting to add that 1 time in the entire code and watching the entire thing break).

The draw function is used to used to draw the tile onto the screen(so the black and white pattern) while the setup method is used to draw any images onto the screen if we had a piece on the screen at that position. You draw onto the screen using blit.

Draw grid draws the boundaries to the grid(so the black horizontal and vertical lines that separate the tiles) and draw grid and make grid is creating the 2d list which are going to use to access all the nodes later. Update display is used to update the screen every-time the tick. I think to avoid the CPU being overloaded, we chose to run the program at 20fps which is ofc completely unreasonable for chess but we didn’t want too much delay.

When the user clicks on the screen, we need to figure out what tile they have clicked on which is what find_node does. Display_potential_moves is a function edwin made but it just takes a list of potential moves and for those moves, changes the colour of the tile so that it stands out.

Do_move is used to acc make the swap on the screen but swapping the values on my dictionary, when the screen updates, this change will be visible on the screen.

remove_highlight is used because it is hard to remove the highlights for specific tiles so we decided to just to redraw the black colours for all the tiles instead.

The main function then contains a lot fo standard logic which I would hope you would have a grasp on if you know pygame. I will attach a video here too just incase you don’t

import pygame

import time

import sys

board = [[' ' for i in range(8)] for i in range(8)]

## Creates a chess piece class that shows what team a piece is on, what type of piece it is and whether or not it can be killed by another selected piece.
class Piece:
def __init__(self, team, type, image, killable=False):
self.team = team
self.type = type
self.killable = killable
self.image = image


## Creates instances of chess pieces, so far we got: pawn, king, rook and bishop
## The first parameter defines what team its on and the second, what type of piece it is
bp = Piece('b', 'p', 'b_pawn.png')
wp = Piece('w', 'p', 'w_pawn.png')
bk = Piece('b', 'k', 'b_king.png')
wk = Piece('w', 'k', 'w_king.png')
br = Piece('b', 'r', 'b_rook.png')
wr = Piece('w', 'r', 'w_rook.png')
bb = Piece('b', 'b', 'b_bishop.png')
wb = Piece('w', 'b', 'w_bishop.png')
bq = Piece('b', 'q', 'b_queen.png')
wq = Piece('w', 'q', 'w_queen.png')
bkn = Piece('b', 'kn', 'b_knight.png')
wkn = Piece('w', 'kn', 'w_knight.png')


starting_order = {(0, 0): pygame.image.load(br.image), (1, 0): pygame.image.load(bkn.image),
(2, 0): pygame.image.load(bb.image), (3, 0): pygame.image.load(bk.image),
(4, 0): pygame.image.load(bq.image), (5, 0): pygame.image.load(bb.image),
(6, 0): pygame.image.load(bkn.image), (7, 0): pygame.image.load(br.image),
(0, 1): pygame.image.load(bp.image), (1, 1): pygame.image.load(bp.image),
(2, 1): pygame.image.load(bp.image), (3, 1): pygame.image.load(bp.image),
(4, 1): pygame.image.load(bp.image), (5, 1): pygame.image.load(bp.image),
(6, 1): pygame.image.load(bp.image), (7, 1): pygame.image.load(bp.image),

(0, 2): None, (1, 2): None, (2, 2): None, (3, 2): None,
(4, 2): None, (5, 2): None, (6, 2): None, (7, 2): None,
(0, 3): None, (1, 3): None, (2, 3): None, (3, 3): None,
(4, 3): None, (5, 3): None, (6, 3): None, (7, 3): None,
(0, 4): None, (1, 4): None, (2, 4): None, (3, 4): None,
(4, 4): None, (5, 4): None, (6, 4): None, (7, 4): None,
(0, 5): None, (1, 5): None, (2, 5): None, (3, 5): None,
(4, 5): None, (5, 5): None, (6, 5): None, (7, 5): None,

(0, 6): pygame.image.load(wp.image), (1, 6): pygame.image.load(wp.image),
(2, 6): pygame.image.load(wp.image), (3, 6): pygame.image.load(wp.image),
(4, 6): pygame.image.load(wp.image), (5, 6): pygame.image.load(wp.image),
(6, 6): pygame.image.load(wp.image), (7, 6): pygame.image.load(wp.image),
(0, 7): pygame.image.load(wr.image), (1, 7): pygame.image.load(wkn.image),
(2, 7): pygame.image.load(wb.image), (3, 7): pygame.image.load(wk.image),
(4, 7): pygame.image.load(wq.image), (5, 7): pygame.image.load(wb.image),
(6, 7): pygame.image.load(wkn.image), (7, 7): pygame.image.load(wr.image),}


def create_board(board):
board[0] = [Piece('b', 'r', 'b_rook.png'), Piece('b', 'kn', 'b_knight.png'), Piece('b', 'b', 'b_bishop.png'), \
Piece('b', 'q', 'b_queen.png'), Piece('b', 'k', 'b_king.png'), Piece('b', 'b', 'b_bishop.png'), \
Piece('b', 'kn', 'b_knight.png'), Piece('b', 'r', 'b_rook.png')]

board[7] = [Piece('w', 'r', 'w_rook.png'), Piece('w', 'kn', 'w_knight.png'), Piece('w', 'b', 'w_bishop.png'), \
Piece('w', 'q', 'w_queen.png'), Piece('w', 'k', 'w_king.png'), Piece('w', 'b', 'w_bishop.png'), \
Piece('w', 'kn', 'w_knight.png'), Piece('w', 'r', 'w_rook.png')]

for i in range(8):
board[1][i] = Piece('b', 'p', 'b_pawn.png')
board[6][i] = Piece('w', 'p', 'w_pawn.png')
return board


## returns the input if the input is within the boundaries of the board
def on_board(position):
if position[0] > -1 and position[1] > -1 and position[0] < 8 and position[1] < 8:
return True


## returns a string that places the rows and columns of the board in a readable manner
def convert_to_readable(board):
output = ''

for i in board:
for j in i:
try:
output += j.team + j.type + ', '
except:
output += j + ', '
output += '\n'
return output


## resets "x's" and killable pieces
def deselect():
for row in range(len(board)):
for column in range(len(board[0])):
if board[row][column] == 'x ':
board[row][column] = ' '
else:
try:
board[row][column].killable = False
except:
pass
return convert_to_readable(board)


## Takes in board as argument then returns 2d array containing positions of valid moves
def highlight(board):
highlighted = []
for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j] == 'x ':
highlighted.append((i, j))
else:
try:
if board[i][j].killable:
highlighted.append((i, j))
except:
pass
return highlighted

def check_team(moves, index):
row, col = index
if moves%2 == 0:
if board[row][col].team == 'w':
return True
else:
if board[row][col].team == 'b':
return True

## This takes in a piece object and its index then runs then checks where that piece can move using separately defined functions for each type of piece.
def select_moves(piece, index, moves):
if check_team(moves, index):
if piece.type == 'p':
if piece.team == 'b':
return highlight(pawn_moves_b(index))
else:
return highlight(pawn_moves_w(index))

if piece.type == 'k':
return highlight(king_moves(index))

if piece.type == 'r':
return highlight(rook_moves(index))

if piece.type == 'b':
return highlight(bishop_moves(index))

if piece.type == 'q':
return highlight(queen_moves(index))

if piece.type == 'kn':
return highlight(knight_moves(index))


## Basically, check black and white pawns separately and checks the square above them. If its free that space gets an "x" and if it is occupied by a piece of the opposite team then that piece becomes killable.
def pawn_moves_b(index):
if index[0] == 1:
if board[index[0] + 2][index[1]] == ' ' and board[index[0] + 1][index[1]] == ' ':
board[index[0] + 2][index[1]] = 'x '
bottom3 = [[index[0] + 1, index[1] + i] for i in range(-1, 2)]

for positions in bottom3:
if on_board(positions):
if bottom3.index(positions) % 2 == 0:
try:
if board[positions[0]][positions[1]].team != 'b':
board[positions[0]][positions[1]].killable = True
except:
pass
else:
if board[positions[0]][positions[1]] == ' ':
board[positions[0]][positions[1]] = 'x '
return board

def pawn_moves_w(index):
if index[0] == 6:
if board[index[0] - 2][index[1]] == ' ' and board[index[0] - 1][index[1]] == ' ':
board[index[0] - 2][index[1]] = 'x '
top3 = [[index[0] - 1, index[1] + i] for i in range(-1, 2)]

for positions in top3:
if on_board(positions):
if top3.index(positions) % 2 == 0:
try:
if board[positions[0]][positions[1]].team != 'w':
board[positions[0]][positions[1]].killable = True
except:
pass
else:
if board[positions[0]][positions[1]] == ' ':
board[positions[0]][positions[1]] = 'x '
return board


## This just checks a 3x3 tile surrounding the king. Empty spots get an "x" and pieces of the opposite team become killable.
def king_moves(index):
for y in range(3):
for x in range(3):
if on_board((index[0] - 1 + y, index[1] - 1 + x)):
if board[index[0] - 1 + y][index[1] - 1 + x] == ' ':
board[index[0] - 1 + y][index[1] - 1 + x] = 'x '
else:
if board[index[0] - 1 + y][index[1] - 1 + x].team != board[index[0]][index[1]].team:
board[index[0] - 1 + y][index[1] - 1 + x].killable = True
return board


## This creates 4 lists for up, down, left and right and checks all those spaces for pieces of the opposite team. The list comprehension is pretty long so if you don't get it just msg me.
def rook_moves(index):
cross = [[[index[0] + i, index[1]] for i in range(1, 8 - index[0])],
[[index[0] - i, index[1]] for i in range(1, index[0] + 1)],
[[index[0], index[1] + i] for i in range(1, 8 - index[1])],
[[index[0], index[1] - i] for i in range(1, index[1] + 1)]]

for direction in cross:
for positions in direction:
if on_board(positions):
if board[positions[0]][positions[1]] == ' ':
board[positions[0]][positions[1]] = 'x '
else:
if board[positions[0]][positions[1]].team != board[index[0]][index[1]].team:
board[positions[0]][positions[1]].killable = True
break
return board


## Same as the rook but this time it creates 4 lists for the diagonal directions and so the list comprehension is a little bit trickier.
def bishop_moves(index):
diagonals = [[[index[0] + i, index[1] + i] for i in range(1, 8)],
[[index[0] + i, index[1] - i] for i in range(1, 8)],
[[index[0] - i, index[1] + i] for i in range(1, 8)],
[[index[0] - i, index[1] - i] for i in range(1, 8)]]

for direction in diagonals:
for positions in direction:
if on_board(positions):
if board[positions[0]][positions[1]] == ' ':
board[positions[0]][positions[1]] = 'x '
else:
if board[positions[0]][positions[1]].team != board[index[0]][index[1]].team:
board[positions[0]][positions[1]].killable = True
break
return board


## applies the rook moves to the board then the bishop moves because a queen is basically a rook and bishop in the same position.
def queen_moves(index):
board = rook_moves(index)
board = bishop_moves(index)
return board


## Checks a 5x5 grid around the piece and uses pythagoras to see if if a move is valid. Valid moves will be a distance of sqrt(5) from centre
def knight_moves(index):
for i in range(-2, 3):
for j in range(-2, 3):
if i ** 2 + j ** 2 == 5:
if on_board((index[0] + i, index[1] + j)):
if board[index[0] + i][index[1] + j] == ' ':
board[index[0] + i][index[1] + j] = 'x '
else:
if board[index[0] + i][index[1] + j].team != board[index[0]][index[1]].team:
board[index[0] + i][index[1] + j].killable = True
return board


WIDTH = 800

WIN = pygame.display.set_mode((WIDTH, WIDTH))

""" This is creating the window that we are playing on, it takes a tuple argument which is the dimensions of the window so in this case 800 x 800px
"""

pygame.display.set_caption("Chess")
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
YELLOW = (204, 204, 0)
BLUE = (50, 255, 255)
BLACK = (0, 0, 0)


class Node:
def __init__(self, row, col, width):
self.row = row
self.col = col
self.x = int(row * width)
self.y = int(col * width)
self.colour = WHITE
self.occupied = None

def draw(self, WIN):
pygame.draw.rect(WIN, self.colour, (self.x, self.y, WIDTH / 8, WIDTH / 8))

def setup(self, WIN):
if starting_order[(self.row, self.col)]:
if starting_order[(self.row, self.col)] == None:
pass
else:
WIN.blit(starting_order[(self.row, self.col)], (self.x, self.y))

"""
For now it is drawing a rectangle but eventually we are going to need it
to use blit to draw the chess pieces instead
"""


def make_grid(rows, width):
grid = []
gap = WIDTH // rows
print(gap)
for i in range(rows):
grid.append([])
for j in range(rows):
node = Node(j, i, gap)
grid[i].append(node)
if (i+j)%2 ==1:
grid[i][j].colour = GREY
return grid
"""
This is creating the nodes thats are on the board(so the chess tiles)
I've put them into a 2d array which is identical to the dimesions of the chessboard
"""


def draw_grid(win, rows, width):
gap = width // 8
for i in range(rows):
pygame.draw.line(win, BLACK, (0, i * gap), (width, i * gap))
for j in range(rows):
pygame.draw.line(win, BLACK, (j * gap, 0), (j * gap, width))

"""
The nodes are all white so this we need to draw the grey lines that separate all the chess tiles
from each other and that is what this function does"""


def update_display(win, grid, rows, width):
for row in grid:
for spot in row:
spot.draw(win)
spot.setup(win)
draw_grid(win, rows, width)
pygame.display.update()


def Find_Node(pos, WIDTH):
interval = WIDTH / 8
y, x = pos
rows = y // interval
columns = x // interval
return int(rows), int(columns)


def display_potential_moves(positions, grid):
for i in positions:
x, y = i
grid[x][y].colour = BLUE
"""
Displays all the potential moves
"""


def Do_Move(OriginalPos, FinalPosition, WIN):
starting_order[FinalPosition] = starting_order[OriginalPos]
starting_order[OriginalPos] = None


def remove_highlight(grid):
for i in range(len(grid)):
for j in range(len(grid[0])):
if (i+j)%2 == 0:
grid[i][j].colour = WHITE
else:
grid[i][j].colour = GREY
return grid
"""this takes in 2 co-ordinate parameters which you can get as the position of the piece and then the position of the node it is moving to
you can get those co-ordinates using my old function for swap"""

create_board(board)


def main(WIN, WIDTH):
moves = 0
selected = False
piece_to_move=[]
grid = make_grid(8, WIDTH)
while True:
pygame.time.delay(50) ##stops cpu dying
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

"""This quits the program if the player closes the window"""

if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
y, x = Find_Node(pos, WIDTH)
if selected == False:
try:
possible = select_moves((board[x][y]), (x,y), moves)
for positions in possible:
row, col = positions
grid[row][col].colour = BLUE
piece_to_move = x,y
selected = True
except:
piece_to_move = []
print('Can\'t select')
#print(piece_to_move)

else:
try:
if board[x][y].killable == True:
row, col = piece_to_move ## coords of original piece
board[x][y] = board[row][col]
board[row][col] = ' '
deselect()
remove_highlight(grid)
Do_Move((col, row), (y, x), WIN)
moves += 1
print(convert_to_readable(board))
else:
deselect()
remove_highlight(grid)
selected = False
print("Deselected")
except:
if board[x][y] == 'x ':
row, col = piece_to_move
board[x][y] = board[row][col]
board[row][col] = ' '
deselect()
remove_highlight(grid)
Do_Move((col, row), (y, x), WIN)
moves += 1
print(convert_to_readable(board))
else:
deselect()
remove_highlight(grid)
selected = False
print("Invalid move")
selected = False

update_display(WIN, grid, 8, WIDTH)


main(WIN, WIDTH)

If I were to explain the entirety of the code, this would take hours on hours to write so I am going to explain the functions and any complex concepts which may be in them and leave you to solve out the rest.

Code Explanation:

We used pygame to write this program since it can easily give us the interface and I have experience from my A* algorithm on how to make a grid so most of the grid is just recycled code from that.

board = [['  ' for i in range(8)] for i in range(8)]

## Creates a chess piece class that shows what team a piece is on, what type of piece it is and whether or not it can be killed by another selected piece.
class Piece:
def __init__(self, team, type, image, killable=False):
self.team = team
self.type = type
self.killable = killable
self.image = image


## Creates instances of chess pieces, so far we got: pawn, king, rook and bishop
## The first parameter defines what team its on and the second, what type of piece it is
bp = Piece('b', 'p', 'b_pawn.png')
wp = Piece('w', 'p', 'w_pawn.png')
bk = Piece('b', 'k', 'b_king.png')
wk = Piece('w', 'k', 'w_king.png')
br = Piece('b', 'r', 'b_rook.png')
wr = Piece('w', 'r', 'w_rook.png')
bb = Piece('b', 'b', 'b_bishop.png')
wb = Piece('w', 'b', 'w_bishop.png')
bq = Piece('b', 'q', 'b_queen.png')
wq = Piece('w', 'q', 'w_queen.png')
bkn = Piece('b', 'kn', 'b_knight.png')
wkn = Piece('w', 'kn', 'w_knight.png')


starting_order = {(0, 0): pygame.image.load(br.image), (1, 0): pygame.image.load(bkn.image),
(2, 0): pygame.image.load(bb.image), (3, 0): pygame.image.load(bk.image),
(4, 0): pygame.image.load(bq.image), (5, 0): pygame.image.load(bb.image),
(6, 0): pygame.image.load(bkn.image), (7, 0): pygame.image.load(br.image),
(0, 1): pygame.image.load(bp.image), (1, 1): pygame.image.load(bp.image),
(2, 1): pygame.image.load(bp.image), (3, 1): pygame.image.load(bp.image),
(4, 1): pygame.image.load(bp.image), (5, 1): pygame.image.load(bp.image),
(6, 1): pygame.image.load(bp.image), (7, 1): pygame.image.load(bp.image),

(0, 2): None, (1, 2): None, (2, 2): None, (3, 2): None,
(4, 2): None, (5, 2): None, (6, 2): None, (7, 2): None,
(0, 3): None, (1, 3): None, (2, 3): None, (3, 3): None,
(4, 3): None, (5, 3): None, (6, 3): None, (7, 3): None,
(0, 4): None, (1, 4): None, (2, 4): None, (3, 4): None,
(4, 4): None, (5, 4): None, (6, 4): None, (7, 4): None,
(0, 5): None, (1, 5): None, (2, 5): None, (3, 5): None,
(4, 5): None, (5, 5): None, (6, 5): None, (7, 5): None,

(0, 6): pygame.image.load(wp.image), (1, 6): pygame.image.load(wp.image),
(2, 6): pygame.image.load(wp.image), (3, 6): pygame.image.load(wp.image),
(4, 6): pygame.image.load(wp.image), (5, 6): pygame.image.load(wp.image),
(6, 6): pygame.image.load(wp.image), (7, 6): pygame.image.load(wp.image),
(0, 7): pygame.image.load(wr.image), (1, 7): pygame.image.load(wkn.image),
(2, 7): pygame.image.load(wb.image), (3, 7): pygame.image.load(wk.image),
(4, 7): pygame.image.load(wq.image), (5, 7): pygame.image.load(wb.image),
(6, 7): pygame.image.load(wkn.image), (7, 7): pygame.image.load(wr.image),}


def create_board(board):
board[0] = [Piece('b', 'r', 'b_rook.png'), Piece('b', 'kn', 'b_knight.png'), Piece('b', 'b', 'b_bishop.png'), \
Piece('b', 'q', 'b_queen.png'), Piece('b', 'k', 'b_king.png'), Piece('b', 'b', 'b_bishop.png'), \
Piece('b', 'kn', 'b_knight.png'), Piece('b', 'r', 'b_rook.png')]

board[7] = [Piece('w', 'r', 'w_rook.png'), Piece('w', 'kn', 'w_knight.png'), Piece('w', 'b', 'w_bishop.png'), \
Piece('w', 'q', 'w_queen.png'), Piece('w', 'k', 'w_king.png'), Piece('w', 'b', 'w_bishop.png'), \
Piece('w', 'kn', 'w_knight.png'), Piece('w', 'r', 'w_rook.png')]

for i in range(8):
board[1][i] = Piece('b', 'p', 'b_pawn.png')
board[6][i] = Piece('w', 'p', 'w_pawn.png')
return board

Except from the starting order dict, all of this was edwins code and all of it used for the move calculations. Theoretically you could have done this with only one of either a dictionary or a 2d list like he has done but since we both needed access to an array for our parts while we were coding and we couldn’t share a python script, we made our own versions. Edwin makes a class for the pieces since it is easier to manage and at the bottom he is setting up his 2d list so all the pieces are in their starting positions. In my dictionary, I hard wrote all the positions automatically since I needed to put the name of each of the individual image files into the load. pygame.image.load() is going to load an image onto the python file and then we only need to draw the image onto the screen. It is better this way than loading the image and then drawing because it means we only need to load the image once for the entire program and then just translate this image onto new positions on the screen.

The rest of edwins code is pretty self-explanatory and is just choosing the correct positions that each piece can move to and then putting those ‘legal’ tiles on the chessboard for us to use on the interface as a way of highlighting the board.

WIDTH = 800

WIN = pygame.display.set_mode((WIDTH, WIDTH))

""" This is creating the window that we are playing on, it takes a tuple argument which is the dimensions of the window so in this case 800 x 800px
"""

pygame.display.set_caption("Chess")
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
YELLOW = (204, 204, 0)
BLUE = (50, 255, 255)
BLACK = (0, 0, 0)


class Node:
def __init__(self, row, col, width):
self.row = row
self.col = col
self.x = int(row * width)
self.y = int(col * width)
self.colour = WHITE
self.occupied = None

def draw(self, WIN):
pygame.draw.rect(WIN, self.colour, (self.x, self.y, WIDTH / 8, WIDTH / 8))

def setup(self, WIN):
if starting_order[(self.row, self.col)]:
if starting_order[(self.row, self.col)] == None:
pass
else:
WIN.blit(starting_order[(self.row, self.col)], (self.x, self.y))

"""
For now it is drawing a rectangle but eventually we are going to need it
to use blit to draw the chess pieces instead
"""


def make_grid(rows, width):
grid = []
gap = WIDTH // rows
print(gap)
for i in range(rows):
grid.append([])
for j in range(rows):
node = Node(j, i, gap)
grid[i].append(node)
if (i+j)%2 ==1:
grid[i][j].colour = GREY
return grid
"""
This is creating the nodes thats are on the board(so the chess tiles)
I've put them into a 2d array which is identical to the dimesions of the chessboard
"""


def draw_grid(win, rows, width):
gap = width // 8
for i in range(rows):
pygame.draw.line(win, BLACK, (0, i * gap), (width, i * gap))
for j in range(rows):
pygame.draw.line(win, BLACK, (j * gap, 0), (j * gap, width))

"""
The nodes are all white so this we need to draw the grey lines that separate all the chess tiles
from each other and that is what this function does"""


def update_display(win, grid, rows, width):
for row in grid:
for spot in row:
spot.draw(win)
spot.setup(win)
draw_grid(win, rows, width)
pygame.display.update()


def Find_Node(pos, WIDTH):
interval = WIDTH / 8
y, x = pos
rows = y // interval
columns = x // interval
return int(rows), int(columns)


def display_potential_moves(positions, grid):
for i in positions:
x, y = i
grid[x][y].colour = BLUE
"""
Displays all the potential moves
"""


def Do_Move(OriginalPos, FinalPosition, WIN):
starting_order[FinalPosition] = starting_order[OriginalPos]
starting_order[OriginalPos] = None


def remove_highlight(grid):
for i in range(len(grid)):
for j in range(len(grid[0])):
if (i+j)%2 == 0:
grid[i][j].colour = WHITE
else:
grid[i][j].colour = GREY
return grid
"""this takes in 2 co-ordinate parameters which you can get as the position of the piece and then the position of the node it is moving to
you can get those co-ordinates using my old function for swap"""

create_board(board)


def main(WIN, WIDTH):
moves = 0
selected = False
piece_to_move=[]
grid = make_grid(8, WIDTH)
while True:
pygame.time.delay(50) ##stops cpu dying
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

"""This quits the program if the player closes the window"""

if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
y, x = Find_Node(pos, WIDTH)
if selected == False:
try:
possible = select_moves((board[x][y]), (x,y), moves)
for positions in possible:
row, col = positions
grid[row][col].colour = BLUE
piece_to_move = x,y
selected = True
except:
piece_to_move = []
print('Can\'t select')
#print(piece_to_move)

else:
try:
if board[x][y].killable == True:
row, col = piece_to_move ## coords of original piece
board[x][y] = board[row][col]
board[row][col] = ' '
deselect()
remove_highlight(grid)
Do_Move((col, row), (y, x), WIN)
moves += 1
print(convert_to_readable(board))
else:
deselect()
remove_highlight(grid)
selected = False
print("Deselected")
except:
if board[x][y] == 'x ':
row, col = piece_to_move
board[x][y] = board[row][col]
board[row][col] = ' '
deselect()
remove_highlight(grid)
Do_Move((col, row), (y, x), WIN)
moves += 1
print(convert_to_readable(board))
else:
deselect()
remove_highlight(grid)
selected = False
print("Invalid move")
selected = False

update_display(WIN, grid, 8, WIDTH)


main(WIN, WIDTH)

--

--

Responses (6)