1from .lutils.attack import getAttacks, piecesAttackingCord 2from .const import NB_OF_CASES 3from .lutils.ldata import PIECE_VALUES 4from .Cord import Cord 5from pychess.Utils.const import KING 6 7 8# This file contains algorithm helping the users to choose the right decisions 9# The first algorithm gives to the user all the pieces attacked and not protected by the foe 10class DecisionSupportAlgorithm: 11 12 def __init__(self): 13 self.local_game = False 14 self.activationEnabled = False 15 16 # to avoid calculating once more the coordinates, we save them 17 self.coordinate_in_danger = [] 18 19 def enableDisableAlgo(self, enable_algorithm): 20 self.activationEnabled = enable_algorithm 21 22 def set_foe_as_bot(self): 23 self.local_game = True 24 25 def calculate_coordinate_in_danger(self, board, mycolor, newTurn=True): 26 '''this function should be used for applying the algorithm''' 27 if not newTurn: 28 return self.coordinate_in_danger 29 30 self.coordinate_in_danger = [] 31 32 self.coordinate_in_danger = self.__apply_algorithm(board, mycolor, self.__not_protected) 33 self.coordinate_in_danger += self.__apply_algorithm(board, mycolor, self.__attacked_and_not_protected) 34 35 return self.coordinate_in_danger 36 37 def __apply_algorithm(self, board, mycolor, algorithm): 38 """returns the list of coordinate in danger for player playing with mycolor pieces 39 according to the algorithm used 40 args : board of type Board, coordinate of type Cord, algorithm : function taking two arguments 41 board, mycolor and the current coordinate we are looking 42 43 WARNING : The king is currently excluded of the calculus => it is never considered as in danger""" 44 coordinate_in_danger = [] 45 46 if self.local_game and self.activationEnabled: 47 # TODO: tests 48 for i in range(NB_OF_CASES): 49 c = Cord(i) 50 number, letter = c.cords 51 piece = board.data[letter][number] 52 if piece is not None and piece.piece is not KING: 53 if piece.color == mycolor: 54 coordinate_in_color = algorithm(board, mycolor, c) 55 if coordinate_in_color is not None: 56 coordinate_in_danger.append(coordinate_in_color) 57 58 return coordinate_in_danger 59 60 def __not_protected(self, board, mycolor, coordinate): 61 """returns the coord with the color yellow if the coord is not protected, None if it is 62 args : board of type Board, coordinate of type Cord, mycolor of value BLACK or WHITE 63 which is the color of the player who will play the next move""" 64 65 c_colored = None 66 attacks = getAttacks(board.board, coordinate.cord, 1 - mycolor) 67 defense = getAttacks(board.board, coordinate.cord, mycolor) 68 69 # if one of the piece is not protected but not attacked, danger 70 # means that towers are highlighted at the start of the game 71 if attacks == 0 and defense == 0: 72 c_colored = Cord(coordinate.cord, color="Y") 73 74 return c_colored 75 76 def __attacked_and_not_protected(self, board, mycolor, coordinate): 77 """returns the coord with the color red if the coord is not protected and attacked, None if it is not 78 args : board of type Board, cord of type Cord, mycolor of value BLACK or WHITE 79 which is the color of the player who will play the next move""" 80 81 pieces_attacking = piecesAttackingCord(board.board, coordinate.cord, 1 - mycolor) 82 defense = getAttacks(board.board, coordinate.cord, mycolor) 83 84 c_colored = None 85 86 number, letter = coordinate.cords 87 piece = board.data[letter][number] 88 89 if len(pieces_attacking) != 0: 90 # if one of the piece is not protected and attacked, very dangerous 91 if defense == 0: 92 c_colored = Cord(coordinate.cord, color="R") 93 else: 94 # if one of the piece attacking is weaker than piece attacked, very dangerous 95 96 # in this part we find the weakest ennemy pieces attacking our piece 97 piece_attacking = pieces_attacking[0] 98 min_value = PIECE_VALUES[piece_attacking] 99 for piece_found in pieces_attacking: 100 if PIECE_VALUES[piece_found] <= min_value: 101 min_value = PIECE_VALUES[piece_found] 102 piece_attacking = piece_found 103 104 # then we compare it to the value of the piece 105 # currently, we consider trades as not dangerous, this behaviour could be changed 106 if PIECE_VALUES[piece_attacking] < PIECE_VALUES[piece.piece]: 107 c_colored = Cord(coordinate.cord, color="R") 108 109 return c_colored 110