|
|
|
|
@ -0,0 +1,849 @@
|
|
|
|
|
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)
|
|
|
|
|
|