Compare commits
No commits in common. 'code1' and 'master' have entirely different histories.
Binary file not shown.
@ -1,849 +0,0 @@
|
||||
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)
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
# 斗兽棋
|
||||
## 内容:
|
||||
1.单机版
|
||||
2.网络版
|
||||
3.AI版
|
||||
|
||||
## 主要模块:
|
||||
1.前端(图形化,音效,动画效果)
|
||||
2.游戏规则:
|
||||
移动规则(点击动物,显示可以移动的范围)
|
||||
动物战斗力强弱判断(正常情况,陷入陷阱的情况)
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
import socket
|
||||
|
||||
|
||||
class Client:
|
||||
def __init__(self):
|
||||
# ipv4 TCP
|
||||
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
def connect(self, server_ip, server_port):
|
||||
self.client.connect((server_ip, server_port))
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
print("please input:")
|
||||
message = input()
|
||||
self.client.sendall(message.encode())
|
||||
response = self.client.recv(1024)
|
||||
print(response.decode())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
client = Client()
|
||||
client.connect('127.0.0.1', 50005)
|
||||
client.run()
|
||||
Loading…
Reference in new issue