You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
doushou/JungleChess1.0.PY

850 lines
39 KiB

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)