Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- from Sprites import * #Pygame is imported here
- '''
- This first section initiates pygame and sets up the chess board
- '''
- pygame.init() #I
- debugging = 0 #A special mode that has tools for me to debug the GUI
- spriteOffset = 10 #Offset so the sprite is centered in the box, the sprite is 60x60 and the box is 80x80
- boxWidth = 80 #Width of a box on the chess board
- turn = 0 #Keeps track of whose turn it is
- selectedPiece = None #Keeps track of which piece is selected
- repeat = 1 #Checks if the loop should continue
- #Set board size and board image
- boardSize = width, height = 640, 640
- bg = pygame.image.load("otherSprites/board.png")
- bgrect = bg.get_rect()
- #Create the window with the size above
- screen = pygame.display.set_mode(boardSize)
- #Make sprite groups for black and white pieces and highlight boxes
- bpieces = pygame.sprite.Group()
- wpieces = pygame.sprite.Group()
- highlights = pygame.sprite.Group()
- dbHighlights = pygame.sprite.Group()
- #Add the rooks into the board
- for i in [0, 7]:
- bpieces.add(bRook(i*boxWidth + spriteOffset, 0*boxWidth + spriteOffset))
- wpieces.add(wRook(i*boxWidth + spriteOffset, 7*boxWidth + spriteOffset))
- #Add the knights into the board
- for i in [1, 6]:
- bpieces.add(bKnight(i*boxWidth + spriteOffset, 0*boxWidth + spriteOffset))
- wpieces.add(wKnight(i*boxWidth + spriteOffset, 7*boxWidth + spriteOffset))
- #Add the bishops into the board
- for i in [2, 5]:
- bpieces.add(bBishop(i*boxWidth + spriteOffset, 0*boxWidth + spriteOffset))
- wpieces.add(wBishop(i*boxWidth + spriteOffset, 7*boxWidth + spriteOffset))
- #Add the kings and queens into the board
- bpieces.add(bKing(3*boxWidth + spriteOffset, 0*boxWidth + spriteOffset))
- wpieces.add(wKing(3*boxWidth + spriteOffset, 7*boxWidth + spriteOffset))
- bpieces.add(bQueen(4*boxWidth + spriteOffset, 0*boxWidth + spriteOffset))
- wpieces.add(wQueen(4*boxWidth + spriteOffset, 7*boxWidth + spriteOffset))
- #Add the pawns into the board
- for i in range(8):
- bpieces.add(bPawn(i*boxWidth + spriteOffset, 1*boxWidth + spriteOffset))
- wpieces.add(wPawn(i*boxWidth + spriteOffset, 6*boxWidth + spriteOffset))
- '''
- This next section defines some functions that will be used in the game
- '''
- #Get the sprite at a certain coordinate, can specify a sprite group
- def getAt(x, y, group = None):
- if group:
- for s in group.sprites():
- if s.rect.x == x and s.rect.y == y:
- return s
- return None
- allSprites = pygame.sprite.Group()
- allSprites.add(wpieces.sprites())
- allSprites.add(bpieces.sprites())
- for s in allSprites.sprites():
- if s.rect.x == x and s.rect.y == y:
- allSprites.empty()
- return s
- return None
- #Highlights squares at certain coordinates
- def highlightSquare(pos):
- if debugging: print("Hightlighting", pos)
- h = highlight(pos[0], pos[1])
- highlights.add(h)
- #Return True if the coordinates are on the board
- def onBoard(x, y):
- if x > 0 and y > 0 and x < 8*boxWidth and y < 8*boxWidth:
- return True
- return False
- #Return a list of possible moves for a bishop
- def getMovesBishop(s):
- moves = [] #Possible moves will be added here
- #Remember current x and y of the piece
- xCurr = s.rect.x
- yCurr = s.rect.y
- color = s.groups()[0].sprites() #Get color of currect piece
- #Checking diagonally in all directions
- for sign in [(-1, -1), (-1, 1), (1, -1), (1, 1)]:
- x = xCurr + sign[0]*boxWidth
- y = yCurr + sign[1]*boxWidth
- while onBoard(x, y):
- hit = getAt(x, y)
- if hit and hit in color: break #If the hit object is the same color you cannot move there
- moves.append((x, y))
- if hit: break #If the hit object is the opposite color you can capture it
- x += sign[0]*boxWidth
- y += sign[1]*boxWidth
- return moves
- #Return a list of possible moves for a plack pawn
- def getMovesbPawn(s):
- moves = []
- currX = s.rect.x
- currY = s.rect.y
- color = s.groups()[0].sprites()
- x = currX
- y = currY + boxWidth
- hit1 = getAt(x, y)
- if onBoard(x, y) and not hit1:
- moves.append((x, y))
- #Can move 2 spaces on first move
- y += boxWidth
- hit2 = getAt(x, y)
- if not s.moved and not hit1 and not hit2:
- moves.append((x, y))
- #Check diagonals for captures
- diags = [(s.rect.x + boxWidth, s.rect.y + boxWidth), (s.rect.x - boxWidth, s.rect.y + boxWidth)]
- for m in diags:
- hit = getAt(m[0], m[1])
- if onBoard(m[0], m[1]) and hit and hit not in color:
- moves.append(m)
- return moves
- #Return a list of moves for a white pawn
- def getMoveswPawn(s):
- moves = []
- currX = s.rect.x
- currY = s.rect.y
- color = s.groups()[0].sprites()
- x = currX
- y = currY - boxWidth
- hit1 = getAt(x, y)
- if onBoard(x, y) and not hit1:
- moves.append((x, y))
- #Can move 2 spaces on first move
- y -= boxWidth
- hit2 = getAt(x, y)
- if not s.moved and not hit1 and not hit2:
- moves.append((x, y))
- #Check diagonals for captures
- diags = [(s.rect.x + boxWidth, s.rect.y - boxWidth), (s.rect.x - boxWidth, s.rect.y - boxWidth)]
- for m in diags:
- hit = getAt(m[0], m[1])
- if onBoard(m[0], m[1]) and hit and hit not in color:
- moves.append(m)
- return moves
- #Return a list of moves for a rook
- def getMovesRook(s):
- moves = [] #Possible moves will be added here
- #Remember current x and y of the piece
- xCurr = s.rect.x
- yCurr = s.rect.y
- color = s.groups()[0].sprites() #Get color of currect piece
- #Checking row and column of peice
- for sign in [(-1, 0), (0, -1), (1, 0), (0, 1)]:
- x = xCurr + sign[0]*boxWidth
- y = yCurr + sign[1]*boxWidth
- while onBoard(x, y):
- hit = getAt(x, y)
- if hit and hit in color: break #If the hit object is the same color you cannot move there
- moves.append((x, y))
- if hit: break #If the hit object is the opposite color you can capture it
- x += sign[0]*boxWidth
- y += sign[1]*boxWidth
- return moves
- #Return a list of moves for a queen
- def getMovesQueen(s):
- moves = []
- #A queen's moves is a combination of a rook's and bishop's
- for m in getMovesRook(s):
- moves.append(m)
- for m in getMovesBishop(s):
- moves.append(m)
- return moves
- #Return a list of moves for a knight
- def getMovesKnight(s):
- moves = [] #Possible moves will be added here
- #Remember current x and y of the piece
- xCurr = s.rect.x
- yCurr = s.rect.y
- color = s.groups()[0].sprites() #Get color of currect piece
- #Checking in L shapes all around, like a knight does
- for sign in [(2, 1), (1, 2), (-2, 1), (1, -2), (2, -1), (-1, 2), (-1, -2), (-2, -1)]:
- x = xCurr + sign[0]*boxWidth
- y = yCurr + sign[1]*boxWidth
- if onBoard(x, y):
- hit = getAt(x, y)
- if hit and hit in color: continue #If the hit object is the same color you cannot move there
- moves.append((x, y))
- return moves
- #Return a list of moves for the black king
- #Note: While this function allows the king to move into check, it will later be checked and will alert the players if the move puts the king in check
- def getMovesKing(s):
- moves = []
- xCurr = s.rect.x
- yCurr = s.rect.y
- color = s.groups()[0].sprites()
- for sign in [(1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)]:
- x = xCurr + sign[0]*boxWidth
- y = yCurr + sign[1]*boxWidth
- if onBoard(x, y):
- hit = getAt(x, y)
- if hit and hit in color: continue
- moves.append((x, y))
- return moves
- def getMoves(s):
- if isinstance(s, (bBishop, wBishop)):
- #if debugging: print("Getting Bishop Moves")
- return getMovesBishop(s)
- if isinstance(s, bPawn):
- #if debugging: print("Getting bPawn Moves")
- return getMovesbPawn(s)
- if isinstance(s, wPawn):
- #if debugging: print("Getting wPawn Moves")
- return getMoveswPawn(s)
- if isinstance(s, (bRook, wRook)):
- #if debugging: print("Getting Rook Moves")
- return getMovesRook(s)
- if isinstance(s, (bQueen, wQueen)):
- #if debugging: print("Getting Queen Moves")
- return getMovesQueen(s)
- if isinstance(s, (bKnight, wKnight)):
- #if debugging: print("Getting Knight Moves")
- return getMovesKnight(s)
- if isinstance(s, (bKing, wKing)):
- #if debugging: print("Getting King Moves")
- return getMovesKing(s)
- def move(s, x, y, reverse = False):
- #The current group of pieces
- g = s.groups()[0]
- #Get the color which isn't currently its turn
- if g == bpieces:
- otherg = wpieces
- else:
- otherg = bpieces
- hit = getAt(x, y, otherg)
- #if a piece is moved onto, kill it (remove it from being displayed)
- if hit:
- hit.kill()
- #Save the old coords of the piece being moved in case the move is going to be reversed
- xOld = s.rect.x
- yOld = s.rect.y
- s.rect.x = x
- s.rect.y = y
- #See if the move puts the player in check
- if g == bpieces:
- isCheck = checkOnBlack()
- else:
- isCheck = checkOnWhite()
- #If the player is in check, reverse the move because they cannot end the move in check
- if isCheck or reverse: #Or the move is marked to be reversed
- s.rect.x = xOld
- s.rect.y = yOld
- if hit: otherg.add(hit) #add the previously "killed" piece back
- if isCheck:
- if not reverse: print("Check")
- return 0
- return 1
- else:
- s.moved = 1
- return 1
- #Return True if black is in check
- #Note: This is only called after black moves because it is fine for black to start the move in check, just not end the move
- def checkOnBlack():
- for s in wpieces.sprites():
- for m in getMoves(s):
- hit = getAt(m[0], m[1], bpieces)
- if isinstance(hit, bKing):
- if debugging: print("Check on Black")
- return True
- return False
- #Return True if white is in check
- def checkOnWhite():
- for s in bpieces.sprites():
- for m in getMoves(s):
- hit = getAt(m[0], m[1], wpieces)
- if isinstance(hit, wKing):
- if debugging: print("Check on White")
- return True
- return False
- #Returns true if checkmate
- def isCheckmate(color):
- for s in color.sprites():
- for m in getMoves(s):
- if move(s, m[0], m[1], True):
- if debugging: print("Not checkmate")
- return False
- print("Checkmate")
- return True
- '''
- This next section runs the game
- '''
- while 1:
- for event in pygame.event.get():
- #Terminate the program on close
- if event.type == pygame.QUIT: sys.exit()
- #If I am debugging I want to see which box is getting clicked on
- if debugging:
- if event.type == pygame.MOUSEBUTTONDOWN:
- print("MOUSEBUTTONDOWN")
- pos = pygame.mouse.get_pos()
- x = (pos[0] // boxWidth) * boxWidth
- y = (pos[1] // boxWidth) * boxWidth
- dbHighlights.add(dbhighlight(x, y))
- #Output the coordinate position of the mouse in terms of boxes on the chess board
- print("Mouse at (", x//boxWidth, ",", y//boxWidth, ")")
- #Display the type of piece clicked on
- hit = getAt(x + spriteOffset, y + spriteOffset)
- print(hit)
- if event.type == pygame.MOUSEBUTTONUP:
- print("MOUSEBUTTONUP")
- dbHighlights.empty()
- if repeat:
- #When the mouse is clicked down
- if event.type == pygame.MOUSEBUTTONDOWN:
- #Get which color is player
- if turn%2 == 0:
- player = wpieces
- otherPlayer = bpieces
- else:
- player = bpieces
- otherPlayer = wpieces
- #Get the mouse position
- pos = pygame.mouse.get_pos()
- x = (pos[0] // boxWidth) * boxWidth
- y = (pos[1] // boxWidth) * boxWidth
- #Look only if whoever's turn it is has selected a piece
- #ex: if it is white's turn, only allow white pieces to be selectable
- hit = getAt(x + spriteOffset, y + spriteOffset, player)
- selectedPiece = hit
- #if a piece of the appropriate color was selected show it's possible moves
- if hit:
- highlights.add(highlightCurr(x + spriteOffset, y + spriteOffset))
- moves = getMoves(hit)
- if moves:
- for m in moves:
- highlightSquare(m)
- #Look where the mouse was un-clicked and see if that is a valid move
- if event.type == pygame.MOUSEBUTTONUP and selectedPiece:
- pos = pygame.mouse.get_pos()
- x = (pos[0] // boxWidth) * boxWidth
- y = (pos[1] // boxWidth) * boxWidth
- hit = getAt(x + spriteOffset, y + spriteOffset, highlights)
- if isinstance(hit, highlight):
- turn += move(selectedPiece, x + spriteOffset, y + spriteOffset)
- highlights.empty()
- #Check for checkmate
- if isCheckmate(otherPlayer):
- otherPlayer.add(checkmate())
- repeat = 0
- screen.blit(bg, bgrect) #Redraw the background (the board)
- bpieces.draw(screen)
- wpieces.draw(screen)
- highlights.draw(screen)
- if debugging: dbHighlights.draw(screen)
- pygame.display.update() #Update the whole screen
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement