from json import load import pygame as p import sys import server import os import json import socket from time import process_time # WIDTH = 512 #448 # HEIGHT = 512 #572 BOARD_WIDTH = 729 # 9*81 = 729 BOARD_HEIGHT = 567 # 7*81 = 567 # DIMENSION = 8 DIMENSION_ROW = 7 DIMENSION_COL = 9 SQUARE_SIZE = 81 #BOARD_HEIGHT // DIMENSION WINORLOSE = -1 IMAGES = {} def loadImages(): pieces = ['bF','bE','bH','bW','bO','bM','bL','rF','rE','rH','rW','rO','rM','rL','trap','den','grass','water'] for piece in pieces: IMAGES[piece] = p.transform.scale(p.image.load("images/" + piece + ".png"), (SQUARE_SIZE, SQUARE_SIZE)) class GameState: def __init__(self): self.board = [ ["--","--","rE","--","--","--","bM","--","--"], ["--","rH","--","--","--","--","--","bF","--"], ["--","--","rW","--","--","--","bO","--","--"], ["--","--","rL","--","--","--","bL","--","--"], ["--","--","rO","--","--","--","bW","--","--"], ["--","rF","--","--","--","--","--","bH","--"], ["--","--","rM","--","--","--","bE","--","--"], ] self.moveFunctions = {"M": self.getRatMoves, "L": self.getJumpMoves, "F": self.getFoxMoves, "E": self.getNormalMoves, "O": self.getNormalMoves, "W": self.getNormalMoves, "H": self.getHawkMoves} self.animal_strengths = { "M": 1, "H": 2, "F": 3, "W": 4, "O": 5,"L": 6, "E": 7 } self.red_to_move = True self.move_log = [] # type: list self.red_trap_locations = [(2,0), (4,0), (3, 1)] self.black_trap_locations = [(2,8), (4,8), (3, 7)] self.den_invaded = False self.draw = False def makeMove(self, move): self.board[move.start_row][move.start_col] = "--" self.board[move.end_row][move.end_col] = move.piece_moved self.move_log.append(move) # log the move so we can undo it later self.red_to_move = not self.red_to_move # switch players def undoMove(self): if len(self.move_log) != 0: # make sure that there is a move to undo move = self.move_log.pop() self.board[move.start_row][move.start_col] = move.piece_moved self.board[move.end_row][move.end_col] = move.piece_captured self.red_to_move = not self.red_to_move # swap players self.den_invaded = False self.draw = False def inTrap(self,end_row,end_col): if end_row in [2,4] and end_col in [0,8]: return True elif end_row in [3] and end_col in [1,7]: return True else: return False def getAllPossibleMoves(self): moves = [] for row in range(len(self.board)): for col in range(len(self.board[row])): turn = self.board[row][col][0] if (turn == "r" and self.red_to_move) or (turn == "b" and not self.red_to_move): piece = self.board[row][col][1] self.moveFunctions[piece](row, col, moves) # calls appropriate move function based on piece type return moves #TODO: def getValidMoves(self): global WINORLOSE """ All valid moves. """ #moves = [] moves = self.getAllPossibleMoves() if len(moves) == 0: if self.red_to_move: WINORLOSE = 1 print("BLUE WINS") elif not self.red_to_move: WINORLOSE = 0 print("RED WINS") else: self.den_invaded = False self.draw = False return moves def inWater(self,row,col): if row in [1,2,4,5]: if col in [3,4,5]: return True return False def jumpConditions(self,row,col,end_row,end_col,jump_row,jump_col,enemy_color): if jump_row != 0 and self.board[end_row + (2 * jump_row)][end_col][0] in ['-',enemy_color]: if self.board[end_row + (1 * jump_row)][end_col][1] not in ['M']: #No Mouse on the way if self.board[end_row + (2 * jump_row)][end_col][0] in ['-']: #Available space return True elif self.canAttack(row,col,end_row + (2 * jump_row) ,end_col): #Enemy check on end square jump return True elif jump_col != 0 and self.board[end_row][end_col + (2 * jump_col)][0] in ['-',enemy_color]: if self.board[end_row][end_col++ (1 * jump_col)][1] not in ['M']: #No Mouse on the way if self.board[end_row][end_col + (2 * jump_col)][0] in ['-']: #Available space return True elif self.canAttack(row, col, end_row , end_col+ (2 * jump_col)): #Enemy check on end square jump return True else: return False ''' def jumpConditions(self,col,row,end_col,end_row,jump_col,jump_row,enemy_color): if jump_row != 0 and self.board[end_row + (3 * jump_row)][end_col][0] in ['-',enemy_color]: if self.board[end_row + (2 * jump_row)][end_col][1] not in ['M'] and self.board[end_row + (1 * jump_row)][end_col][1] not in ['M']: #No Mouse on the way if self.board[end_row + (3 * jump_row)][end_col][0] in ['-']: #Available space return True elif self.canAttack(row,col,end_row + (3 * jump_row) ,end_col): #Enemy check on end square jump return True elif jump_col != 0 and self.board[end_row][end_col + (2 * jump_col)][0] in ['-',enemy_color]: if self.board[end_row][end_col++ (1 * jump_col)][1] not in ['M']: #No Mouse on the way if self.board[end_row][end_col + (2 * jump_col)][0] in ['-']: #Available space return True elif self.canAttack(row, col, end_row , end_col+ (2 * jump_col)): #Enemy check on end square jump return True else: return False ''' def moveNotOwnDen(self,row_end,col_end,enemy_color): if enemy_color == 'b' and row_end == 3 and col_end == 0: return False elif enemy_color == 'r' and row_end == 3 and col_end == 8: return False else: return True def enemyConquerDen(self): if self.board[3][8][0] == "r" or self.board[3][0][0] == "b": self.den_invaded = True return True else: return False def canAttack(self, own_row, own_col, row_end, col_end): """ Determines if player can attack opponent's piece Args: own_row (int): Player's piece row own_col (int): Player's piece column row_end (int): Opponent's piece row col_end (int): Opponent's piece column Returns: boolean: Returns 'True' if it's possible to attack the opponent's piece or 'False' if it's an invalid move. """ own_piece = self.board[own_row][own_col] target_piece = self.board[row_end][col_end] # Traps attacks and protection if target_piece[0] == 'b' and (row_end,col_end) in self.red_trap_locations: # black player vulnerable by enemy traps return True if target_piece[0] == 'r' and (row_end,col_end) in self.black_trap_locations: # red player vulnerable by enemy traps return True # Elephant cannot attack rat if own_piece[1] == 'E' and target_piece[1] == 'M': return False # Hawk cannot attack rat in water if own_piece[1] == 'H' and target_piece[1] == 'M' and self.inWater(row_end, col_end): return False # Rat attacks if own_piece[1] == 'M': if self.inWater(own_row, own_col) and self.inWater(row_end, col_end): # Rat can attack another rat in the water return True elif self.inWater(own_row, own_col) and not self.inWater(row_end, col_end): # Rat cannot attack from inside the water return False elif not self.inWater(own_row, own_col) and self.inWater(row_end, col_end): # Rat cannot attack target inside the water from land return False elif target_piece[1] == 'E': # Regular rat attack against elephant return True elif self.animal_strengths[target_piece[1]] <= self.animal_strengths[own_piece[1]]: # Rat can attack rat return True elif self.animal_strengths[target_piece[1]] <= self.animal_strengths[own_piece[1]]: # Regular animal battle return True def getRatMoves(self, row, col, moves): directions = ((-1, 0), (0, -1), (1, 0), (0, 1)) # up, left, down, right enemy_color = "b" if self.red_to_move else "r" for direction in directions: for i in range(1, 2): end_row = row + direction[0] * 1 end_col = col + direction[1] * 1 if 0 <= end_row <= 6 and 0 <= end_col <= 8: # check for possible moves only in boundaries of the board end_piece = self.board[end_row][end_col] if end_piece == "--" and self.moveNotOwnDen(end_row,end_col,enemy_color): # empty space is valid and not own DEN moves.append(Move((row, col), (end_row, end_col), self.board)) elif end_piece[0] == enemy_color and self.canAttack(row, col, end_row, end_col): # capture enemy piece, if the enemy is weaker or trapped moves.append(Move((row, col), (end_row, end_col), self.board)) else: # friendly piece break else: # off board break def getNormalMoves(self, row, col, moves): directions = ((-1, 0), (0, -1), (1, 0), (0, 1)) # up, left, down, right enemy_color = "b" if self.red_to_move else "r" for direction in directions: for i in range(1, 2): end_row = row + direction[0] * 1 end_col = col + direction[1] * 1 if 0 <= end_row <= 6 and 0 <= end_col <= 8: # check for possible moves only in boundaries of the board end_piece = self.board[end_row][end_col] if end_piece == "--" and not self.inWater(end_row,end_col) and self.moveNotOwnDen(end_row,end_col,enemy_color): # empty space is valid and Not in Water moves.append(Move((row, col), (end_row, end_col), self.board)) elif end_piece[0] == enemy_color and not self.inWater(end_row,end_col) and self.canAttack(row, col, end_row, end_col): # capture enemy piece, if the enemy is weaker or trapped moves.append(Move((row, col), (end_row, end_col), self.board)) break else: # friendly piece break else: # off board break def getFoxMoves(self, row, col, moves): directions = ((-1, 0), (0, -1), (1, 0), (0, 1), (1, 1), (1, -1), (-1, 1), (-1, -1)) # up, left, down, right enemy_color = "b" if self.red_to_move else "r" for direction in directions: for i in range(1, 2): end_row = row + direction[0] * 1 end_col = col + direction[1] * 1 if 0 <= end_row <= 6 and 0 <= end_col <= 8: # check for possible moves only in boundaries of the board end_piece = self.board[end_row][end_col] if end_piece == "--" and not self.inWater(end_row,end_col) and self.moveNotOwnDen(end_row,end_col,enemy_color): # empty space is valid and Not in Water moves.append(Move((row, col), (end_row, end_col), self.board)) elif end_piece[0] == enemy_color and not self.inWater(end_row,end_col) and self.canAttack(row, col, end_row, end_col): # capture enemy piece, if the enemy is weaker or trapped moves.append(Move((row, col), (end_row, end_col), self.board)) break else: # friendly piece break else: # off board break def getHawkMoves(self, row, col, moves): directions = ((-1, 0), (0, -1), (1, 0), (0, 1)) # up, left, down, right self_color = "r" if self.red_to_move else "b" enemy_color = "b" if self.red_to_move else "r" for direction in directions: for i in range(1, 9): end_row = row + direction[0] * i end_col = col + direction[1] * i if 0 <= end_row <= 6 and 0 <= end_col <= 8: # check for possible moves only in boundaries of the board end_piece = self.board[end_row][end_col] if end_piece == "--" and self.inTrap(end_row,end_col) and self.moveNotOwnDen(end_row,end_col,enemy_color): # enter the trap and not overheading moves.append(Move((row, col), (end_row, end_col), self.board)) break elif not self.red_to_move and end_piece == "--" and self.inTrap(row, col) and end_row == 3 and end_col == 0: moves.append(Move((row, col), (end_row, end_col), self.board)) break elif self.red_to_move and end_piece == "--" and self.inTrap(row, col) and end_row == 3 and end_col == 8: moves.append(Move((row, col), (end_row, end_col), self.board)) break if end_piece == "--" and not self.inWater(end_row,end_col) and self.moveNotOwnDen(end_row,end_col,enemy_color): # empty space is valid and Not in Water moves.append(Move((row, col), (end_row, end_col), self.board)) elif end_piece == "--" and self.inWater(end_row,end_col) and self.moveNotOwnDen(end_row,end_col,enemy_color): # empty space is valid and Not in Water continue elif end_piece[0] == enemy_color and self.canAttack(row, col, end_row, end_col): # capture enemy piece, if the enemy is weaker or trapped moves.append(Move((row, col), (end_row, end_col), self.board)) break else: # friendly piece break else: # off board break """ for i in range(1,9): end_row = row + direction[0] * i end_col = col + direction[1] * i if 0 <= end_row <= 6 and 0 <= end_col <= 8: # check for possible moves only in boundaries of the board end_piece = self.board[end_row][end_col] # if self.inTrap(row,col) and self.moveNotOwnDen(end_row,end_col,enemy_color): # break if end_piece == "--" and self.moveNotOwnDen(end_row,end_col,enemy_color) and not self.inWater(end_row,end_col): moves.append(Move((row, col), (end_row, end_col), self.board)) elif end_piece == "--" and self.inTrap(end_row,end_col) : # enter the trap without other options on the very way moves.append(Move((row, col), (end_row, end_col), self.board)) break elif self.inWater(end_row,end_col) and end_piece != "--": #if the piece,namely the mouse, is in water, it can not attack the piece on grass. break elif end_piece[0] == enemy_color and self.canAttack(row, col, end_row, end_col): # capture enemy piece, if the enemy is weaker or trapped moves.append(Move((row, col), (end_row, end_col), self.board)) break elif end_piece[0] == enemy_color: break elif end_piece == "--" and self.inTrap(row,col) and self.moveNotOwnDen(end_row,end_col,enemy_color): moves.append(Move((row, col), (end_row, end_col), self.board)) break elif end_piece[0]== self_color: # encounter self pieces break elif end_piece == "--" and self.inWater(end_row,end_col): continue """ ''' if end_piece[0]== self_color : break if not self.moveNotOwnDen(end_row,end_col,enemy_color): moves.append(Move((row, col), (end_row, end_col), self.board)) break elif end_piece == "--" and self.moveNotOwnDen(end_row,end_col,enemy_color) and not self.inWater(end_row,end_col) and self.inTrap(end_row,end_col): moves.append(Move((row, col), (end_row, end_col), self.board)) break elif end_piece == "--" and self.moveNotOwnDen(end_row,end_col,enemy_color) and not self.inWater(end_row,end_col): # empty space is valid and not own DEN moves.append(Move((row, col), (end_row, end_col), self.board)) elif end_piece != "--" and self.inWater(end_row,end_col): break elif end_piece[0] == enemy_color and self.canAttack(row, col, end_row, end_col): # capture enemy piece, if the enemy is weaker or trapped moves.append(Move((row, col), (end_row, end_col), self.board)) break elif end_piece[0] == enemy_color: break elif self.inTrap(row, col) and self.moveNotOwnDen(end_row,end_col,enemy_color): moves.append(Move((row, col), (end_row, end_col), self.board)) break elif end_piece == "--" and self.inWater(end_row,end_col): continue ''' def getJumpMoves(self, row, col, moves): directions = ((-1, 0), (0, -1), (1, 0), (0, 1)) # up, left, down, right enemy_color = "b" if self.red_to_move else "r" for direction in directions: for i in range(1, 2): end_row = row + direction[0] * 1 end_col = col + direction[1] * 1 if 0 <= end_row <= 6 and 0 <= end_col <= 8: # check for possible moves only in boundaries of the board end_piece = self.board[end_row][end_col] if end_piece == "--" and not self.inWater(end_row,end_col) and self.moveNotOwnDen(end_row,end_col,enemy_color): # empty space is valid and Not in Water moves.append(Move((row, col), (end_row, end_col), self.board)) elif end_piece == "--" and self.inWater(end_row,end_col): jump_row = end_row - row #Vertical jump jump_col = end_col - col #Horizontal jump if jump_row != 0 and self.jumpConditions(row,col,end_row,end_col,jump_row,jump_col,enemy_color): moves.append(Move((row, col), (end_row+(2*jump_row), end_col), self.board)) elif jump_col != 0 and self.jumpConditions(row,col,end_row,end_col,jump_row,jump_col,enemy_color): moves.append(Move((row, col), (end_row, end_col+(3*jump_col)), self.board)) elif end_piece[0] == enemy_color and not self.inWater(end_row,end_col) and self.canAttack(row, col, end_row, end_col): # capture enemy piece moves.append(Move((row, col), (end_row, end_col), self.board)) break ''' if jump_row != 0 and self.jumpConditions(row,col,end_row,end_col,jump_row,jump_col,enemy_color): moves.append(Move((row, col), (end_row+(3*jump_row), end_col), self.board)) elif jump_col != 0 and self.jumpConditions(row,col,end_row,end_col,jump_row,jump_col,enemy_color): moves.append(Move((row, col), (end_row, end_col+(2*jump_col)), self.board)) elif end_piece[0] == enemy_color and not self.inWater(end_row,end_col) and self.canAttack(row, col, end_row, end_col): # capture enemy piece moves.append(Move((row, col), (end_row, end_col), self.board)) break ''' else: # friendly piece break else: # off board break class Move: # in chess, fields on the board are described by two symbols, one of them being number between 1-8 (which is corresponding to rows) # and the second one being a letter between a-f (corresponding to columns), in order to use this notation we need to map our [row][col] coordinates # to match the ones used in the original chess game # ranks_to_rows = {"7": 6, "6": 5, "5": 4, # "4": 3, "3": 2, "2": 1, "1": 0} # files_to_cols = {"a": 0, "b": 1, "c": 2, "d": 3, # "e": 4, "f": 5, "g": 6, "h": 7,"i":8,"k":9} # rows_to_ranks = {v: k for k, v in ranks_to_rows.items()} # cols_to_files = {v: k for k, v in files_to_cols.items()} def __init__(self, start_square, end_square, board): self.start_row = start_square[0] self.start_col = start_square[1] self.end_row = end_square[0] self.end_col = end_square[1] self.piece_moved = board[self.start_row][self.start_col] self.piece_captured = board[self.end_row][self.end_col] self.is_capture = self.piece_captured != "--" self.moveID = self.start_row * 1000 + self.start_col * 100 + self.end_row * 10 + self.end_col def __eq__(self, other): """ Overriding the equals method. """ if isinstance(other, Move): return self.moveID == other.moveID return False # def getRankFile(self, row, col): # return self.cols_to_files[col] + self.rows_to_ranks[row] # def __str__(self): # end_square = self.getRankFile(self.end_row, self.end_col) # move_string = self.piece_moved[1] # if self.is_capture: # move_string += "x" # return move_string + end_square def main(player1,player2,depth_p1,depth_p2): p.init() screen = p.display.set_mode((BOARD_WIDTH, BOARD_HEIGHT)) clock = p.time.Clock() game_state = GameState() valid_moves = game_state.getValidMoves() move_made = False # flag variable for when a move is made animate = False # flag variable for when we should animate a move loadImages() # do this only once before while loop running = True square_selected = () # no square is selected initially, this will keep track of the last click of the user (tuple(row,col)) player_clicks = [] # this will keep track of player clicks (two tuples) game_over = False move_undone = False move_log_font = p.font.SysFont("Arial", 14, False, False) player_one = player1 # True for Human, False for AI player_two = player2 # True for Human, False for AI player_won = 0 while running: human_turn = (game_state.red_to_move and player_one) or (not game_state.red_to_move and player_two) for e in p.event.get(): if e.type == p.QUIT: p.quit() sys.exit() # mouse handler elif e.type == p.MOUSEBUTTONDOWN: if not game_over: location = p.mouse.get_pos() # (x, y) location of the mouse col = location[0] // SQUARE_SIZE row = location[1] // SQUARE_SIZE if square_selected == (row, col) or col > 8: # user clicked the same square twice square_selected = () # deselect player_clicks = [] # clear clicks else: square_selected = (row, col) player_clicks.append(square_selected) # append for both 1st and 2nd click if len(player_clicks) == 2 and human_turn: # after 2nd click move = Move(player_clicks[0], player_clicks[1], game_state.board) for i in range(len(valid_moves)): if move == valid_moves[i]: game_state.makeMove(valid_moves[i]) move_made = True animate = True square_selected = () # reset user clicks player_clicks = [] if not move_made: player_clicks = [square_selected] # key handler elif e.type == p.KEYDOWN: if e.key == p.K_z: # undo when 'z' is pressed game_state.undoMove() move_made = True animate = False game_over = False move_undone = True if e.key == p.K_q: print("\nEND GAME statistics:") log_perfomance(process_time(), process_time(), 0,0 , 1,depth_p1,depth_p2,player_won) exit() if e.key == p.K_r: # reset the game when 'r' is pressed game_state = GameState() valid_moves = game_state.getValidMoves() square_selected = () player_clicks = [] move_made = False animate = False game_over = False move_undone = True if move_made: if animate: animateMove(game_state.move_log[-1], screen, game_state.board, clock) valid_moves = game_state.getValidMoves() move_made = False animate = False move_undone = False #drawBoard(screen) board = game_state.board global colors colors = [p.Color("white"), p.Color("gray")] for row in range(DIMENSION_ROW): for column in range(DIMENSION_COL): p.draw.rect(screen, p.Color(25,65,25), p.Rect(column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) screen.blit(IMAGES['grass'], p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE -3, SQUARE_SIZE - 3)) # grass image # p.draw.rect(screen, p.Color(90,150,75), p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3, SQUARE_SIZE - 3)) if row in [1,2,4,5]: #WATER if column in [3,4,5]: # p.draw.rect(screen, p.Color(5,120,230),p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3,SQUARE_SIZE - 3)) screen.blit(IMAGES['water'], p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE -3, SQUARE_SIZE - 3)) if row in [2,4]: #TRAP if column in [0,8]: #p.draw.rect(screen, p.Color(255,105,60),p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3,SQUARE_SIZE - 3)) screen.blit(IMAGES['trap'], p.Rect(column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) if row in [3]: #TRAP if column in [1,7]: #p.draw.rect(screen, p.Color(255,105,60),p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3,SQUARE_SIZE - 3)) screen.blit(IMAGES['trap'], p.Rect(column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) if row in [3]: #DEN if column in [0,8]: #p.draw.rect(screen, p.Color(50,180,50),p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3,SQUARE_SIZE - 3)) screen.blit(IMAGES['den'], p.Rect(column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) #highlightSquares(screen, game_state, valid_moves, square_selected) if (len(game_state.move_log)) > 0: last_move = game_state.move_log[-1] s = p.Surface((SQUARE_SIZE, SQUARE_SIZE)) s.set_alpha(100) s.fill(p.Color('green')) screen.blit(s, (last_move.end_col * SQUARE_SIZE, last_move.end_row * SQUARE_SIZE)) if square_selected != (): row, col = square_selected if game_state.board[row][col][0] == ('r' if game_state.red_to_move else 'b'): # square_selected is a piece that can be moved # highlight selected square s = p.Surface((SQUARE_SIZE, SQUARE_SIZE)) s.set_alpha(100) # transparency value 0 -> transparent, 255 -> opaque s.fill(p.Color('blue')) screen.blit(s, (col * SQUARE_SIZE, row * SQUARE_SIZE)) # highlight moves from that square s.fill(p.Color('yellow')) for move in valid_moves: if move.start_row == row and move.start_col == col: screen.blit(s, (move.end_col * SQUARE_SIZE, move.end_row * SQUARE_SIZE)) # drawPieces(screen, game_state.board) for row in range(DIMENSION_ROW): for column in range(DIMENSION_COL): piece = board[row][column] if piece != "--": screen.blit(IMAGES[piece], p.Rect(column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) # print(IMAGES[piece]) #TODO: if WINORLOSE == 1: drawEndGameText(screen, "BlUE wins") player_won = 2 elif WINORLOSE == 0: drawEndGameText(screen, "Red wins") player_won = 1 if game_state.enemyConquerDen(): game_over = True if game_state.red_to_move: # drawEndGameText(screen, "Black wins") text = "Blue wins" font = p.font.SysFont("Helvetica", 32, True, False) text_object = font.render(text, False, p.Color("gray")) text_location = p.Rect(0, 0, BOARD_WIDTH, BOARD_HEIGHT).move(BOARD_WIDTH / 2 - text_object.get_width() / 2, BOARD_HEIGHT / 2 - text_object.get_height() / 2) screen.blit(text_object, text_location) text_object = font.render(text, False, p.Color('black')) screen.blit(text_object, text_location.move(2, 2)) player_won=2 else: # drawEndGameText(screen, "Red wins") text = "Red wins" font = p.font.SysFont("Helvetica", 32, True, False) text_object = font.render(text, False, p.Color("gray")) text_location = p.Rect(0, 0, BOARD_WIDTH, BOARD_HEIGHT).move(BOARD_WIDTH / 2 - text_object.get_width() / 2, BOARD_HEIGHT / 2 - text_object.get_height() / 2) screen.blit(text_object, text_location) text_object = font.render(text, False, p.Color('black')) screen.blit(text_object, text_location.move(2, 2)) player_won=1 p.display.flip() def log_perfomance(t_start,t_stop,player,move,gameover,depth_p1=4,depth_p2=4,player_won=0): delta_t = 0 delta_t = t_stop - t_start if gameover == 1: if player_won == 2: print("BLACK WINS") elif player_won == 1: print("RED WINS") else: print("DRAW!") def drawBoard(screen): global colors colors = [p.Color("white"), p.Color("Navy Blue")] for row in range(DIMENSION_ROW): for column in range(DIMENSION_COL): p.draw.rect(screen, p.Color(25, 65, 25), p.Rect( column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) screen.blit(IMAGES['grass'], p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3, SQUARE_SIZE - 3)) # grass image # p.draw.rect(screen, p.Color(90,150,75), p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3, SQUARE_SIZE - 3)) if row in [1,2,4,5]: # WATER if column in [3,4,5]: # p.draw.rect(screen, p.Color(5,120,230),p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3,SQUARE_SIZE - 3)) screen.blit(IMAGES['water'], p.Rect( (column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3, SQUARE_SIZE - 3)) if row in [2, 4]: # TRAP if column in [0, 8]: #p.draw.rect(screen, p.Color(255,105,60),p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3,SQUARE_SIZE - 3)) screen.blit(IMAGES['trap'], p.Rect( column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) if row in [3]: # TRAP if column in [1,7]: #p.draw.rect(screen, p.Color(255,105,60),p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3,SQUARE_SIZE - 3)) screen.blit(IMAGES['trap'], p.Rect( column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) if row in [3]: # DEN if column in [0,8]: #p.draw.rect(screen, p.Color(50,180,50),p.Rect((column * SQUARE_SIZE) + 3, (row * SQUARE_SIZE) + 3, SQUARE_SIZE - 3,SQUARE_SIZE - 3)) screen.blit(IMAGES['den'], p.Rect( column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) def drawPieces(screen, board): for row in range(DIMENSION_ROW): for column in range(DIMENSION_COL): piece = board[row][column] if piece != "--": screen.blit(IMAGES[piece], p.Rect( column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) def drawEndGameText(screen, text): font = p.font.SysFont("Helvetica", 32, True, False) text_object = font.render(text, False, p.Color("gray")) text_location = p.Rect(0, 0, BOARD_WIDTH, BOARD_HEIGHT).move(BOARD_WIDTH / 2 - text_object.get_width() / 2, BOARD_HEIGHT / 2 - text_object.get_height() / 2) screen.blit(text_object, text_location) text_object = font.render(text, False, p.Color('black')) screen.blit(text_object, text_location.move(2, 2)) def animateMove(move, screen, board, clock): global colors d_row = move.end_row - move.start_row d_col = move.end_col - move.start_col frames_per_square = 10 # frames to move one square frame_count = (abs(d_row) + abs(d_col)) * frames_per_square for frame in range(frame_count + 1): row, col = (move.start_row + d_row * frame / frame_count, move.start_col + d_col * frame / frame_count) drawBoard(screen) drawPieces(screen, board) # erase the piece moved from its ending square color = colors[(move.end_row + move.end_col) % 2] end_square = p.Rect(move.end_col * SQUARE_SIZE, move.end_row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE) p.draw.rect(screen, color, end_square) # draw captured piece onto rectangle if move.piece_captured != '--': screen.blit(IMAGES[move.piece_captured], end_square) # draw moving piece screen.blit(IMAGES[move.piece_moved], p.Rect( col * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)) p.display.flip() clock.tick(60) class Button: def __init__(self, image, position, callback=None): self.image = image self.rect = image.get_rect(topleft=position) self.callback = callback def on_click(self, event): if event.button == 1: if self.rect.collidepoint(event.pos): self.callback(self) def draw(self, surf): p.draw.rect(surf, self.color_menu[self.menu_active], self.rect, 0) msg = self.font.render(self.main, 1, (0, 0, 0)) surf.blit(msg, msg.get_rect(center = self.rect.center)) if self.draw_menu: for i, text in enumerate(self.options): rect = self.rect.copy() rect.y += (i+1) * self.rect.height p.draw.rect(surf, self.color_option[1 if i == self.active_option else 0], rect, 0) msg = self.font.render(text, 1, (0, 0, 0)) surf.blit(msg, msg.get_rect(center = rect.center)) if __name__ == "__main__": click = False p.init() mainClock = p.time.Clock() SCREEN_WIDTH = 900 SCREEN_HEIGHT = 480 # load main screen screen = p.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) p.display.set_caption("AnimalChess by Z and JJ") bg_img = p.transform.scale(p.image.load("images/bg.png"),(SCREEN_WIDTH,SCREEN_HEIGHT)) # load button images hvh_img = p.transform.scale(p.image.load("images/button_hvh.png"),(360,60)) # #create button instances button_1 = Button(hvh_img, (SCREEN_WIDTH/3-50, SCREEN_HEIGHT/3*2)) COLOR_INACTIVE = (255, 128, 0) COLOR_ACTIVE = (255, 208, 0) COLOR_LIST_INACTIVE = (0, 143, 90) COLOR_LIST_ACTIVE = (3, 252, 140) # game music p.mixer.init() # music = p.mixer.Sound('music/主菜单背景.mp3') p.mixer.music.load('music/主菜单背景.mp3') p.mixer.music.play(-1,0.0) # music.set_volume(0.70) # music.play() p.display.flip() p1, p2 = False, False run = True while run: mainClock.tick(60) # screen.blit(bg_img, (0, 0)) mode=0 event_list = p.event.get() for event in event_list: if event.type == p.QUIT: p.quit() sys.exit() if event.type == p.KEYDOWN: if event.key == p.K_ESCAPE: p.quit() sys.exit() if event.type == p.MOUSEBUTTONDOWN: if event.button == 1: if button_1.rect.collidepoint(p.mouse.get_pos()): # print("Over button 1!") p1, p2 = True, True depth1, depth2 = None, None run = False mode=1 screen.blit(bg_img, (0, 0)) # Loads background image screen.blit(button_1.image, button_1.rect) # Loads button 1 on screen p.display.flip() p.mixer.music.stop() mainClock.tick(60) # Loads main menu print("Loading... ") # depth_p1,depth_p2 = levelgame(mode) main(p1, p2, depth1, depth2) print("Initialing game...") # main(player1,player2,depth_p1,depth_p2)