diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..32dfc6e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +images/* +*.png \ No newline at end of file diff --git a/__pycache__/player.cpython-311.pyc b/__pycache__/player.cpython-311.pyc new file mode 100644 index 0000000..4f3e237 Binary files /dev/null and b/__pycache__/player.cpython-311.pyc differ diff --git a/player.py b/player.py index 16ddefa..30ca4c3 100644 --- a/player.py +++ b/player.py @@ -17,7 +17,7 @@ def get_neighbors(p, q): class Piece: - def get_piece_info(self): + def get_piece_info(self, myisupper): class_to_letter = { "Bee": "Q", "Beetle": "B", @@ -26,10 +26,52 @@ class Piece: "Ant": "A", } letter = class_to_letter[self.__class__.__name__] - if not self.team: + if not myisupper: letter = letter.lower() return [letter, self.p, self.q] + def validate_jumps(self, board): + valid_jumps = self.get_valid_jumps(board) + validated_jumps = [] + + for jump in valid_jumps: + if not self.does_jump_split_hive(jump, board): + validated_jumps.append(jump) + return validated_jumps + + def does_jump_split_hive(self, jump, board): + board_copy = {p: {q: board[p][q] for q in board[p]} for p in board} + + # Simulate the move + board_copy[self.p][self.q] = None # Remove the piece from its current position + new_p, new_q = jump + board_copy[new_p][new_q] = self # Place the piece in the new position + + # Get all remaining pieces on the board + remaining_pieces = [ + piece for row in board_copy.values() for piece in row.values() if piece + ] + + # Start BFS from a random piece + start_piece = remaining_pieces[0] + visited = set() + queue = deque([start_piece]) + + while queue: + current_piece = queue.popleft() + visited.add(current_piece) + + # Get all neighbors of the current piece + for neighbor_p, neighbor_q in get_neighbors( + current_piece.p, current_piece.q + ): + neighbor_piece = board_copy.get(neighbor_p, {}).get(neighbor_q) + if neighbor_piece and neighbor_piece not in visited: + queue.append(neighbor_piece) + + # Check if all pieces are connected + return len(visited) != len(remaining_pieces) + def get_valid_jumps() -> list: raise NotImplementedError @@ -153,6 +195,7 @@ class Player(Base.Board): self, myIsUpper, size, myPieces, rivalPieces ) # do not change this line self.playerName = playerName + self.myIsUpper = myIsUpper self.algorithmName = "just roll the dice, eh?" def getAllEmptyCells(self): @@ -221,6 +264,37 @@ class Player(Base.Board): unplaced_pieces.append(piece_class(None, None, True)) return unplaced_pieces + def get_valid_placements(self, translated_board, piece_to_place): + valid_placements = [] + + if not translated_board: + # If the board is empty, the piece can be placed anywhere. + # For example, return the center of the board or any other arbitrary position. + return [(3, 6)] + + for p, row in translated_board.items(): + for q, piece in row.items(): + if piece and piece.team == self.myIsUpper: + # Check all neighbors of the piece + for neighbor_p, neighbor_q in get_neighbors(p, q): + if ( + neighbor_p, + neighbor_q, + ) in translated_board and not translated_board[neighbor_p][ + neighbor_q + ]: + # Check if the position is only adjacent to friendly pieces + if all( + not translated_board.get(adj_p, {}).get(adj_q) + or translated_board[adj_p][adj_q].team == self.myIsUpper + for adj_p, adj_q in get_neighbors( + neighbor_p, neighbor_q + ) + ): + valid_placements.append((neighbor_p, neighbor_q)) + + return valid_placements + def move(self): translated_board, total_pieces_count, _ = self.translate_board(self.board) @@ -230,7 +304,7 @@ class Player(Base.Board): if total_pieces_count == 0: piece_to_place = choose_random_piece(self.get_unplaced_pieces()) return ( - piece_to_place.get_piece_info()[:1] + [None, None, 3, 6] + piece_to_place.get_piece_info(self.myIsUpper)[:1] + [None, None, 3, 6] if piece_to_place else [] ) @@ -243,45 +317,49 @@ class Player(Base.Board): random_position = choose_random_piece(adjacent_positions) piece_to_place = choose_random_piece(self.get_unplaced_pieces()) return ( - piece_to_place.get_piece_info()[:1] + piece_to_place.get_piece_info(self.myIsUpper)[:1] + [None, None, *random_position] if piece_to_place else [] ) - elif self.queen_placed or total_pieces_count >= 8: + else: move_or_place = random.choice(["move", "place"]) - if move_or_place == "move": + if move_or_place == "move" and self.queen_placed: + print(translated_board) movable_pieces = [ - p - for p in translated_board.values() - if p.get_valid_jumps(translated_board) + piece + for row in translated_board.values() + for piece in row.values() + if piece and piece.validate_jumps(piece, translated_board) ] chosen_piece = choose_random_piece(movable_pieces) if chosen_piece: new_p, new_q = random.choice( - chosen_piece.get_valid_jumps(translated_board) + chosen_piece.validate_jumps(chosen_piece, translated_board) ) - return chosen_piece.get_piece_info() + [new_p, new_q] + return chosen_piece.get_piece_info(self.myIsUpper) + [new_p, new_q] else: piece_to_place = choose_random_piece(self.get_unplaced_pieces()) if piece_to_place: valid_placements = self.get_valid_placements( translated_board, piece_to_place ) + print(piece_to_place, valid_placements) new_p, new_q = ( random.choice(valid_placements) if valid_placements else (None, None) ) - return piece_to_place.get_piece_info()[:1] + [ + return piece_to_place.get_piece_info(self.myIsUpper)[:1] + [ None, None, new_p, new_q, ] - - return [] # uncase of the inability to do anything, return empty list + return ( + [] + ) # uncase of the inability to do anything, return empty list tho this wont ever run def updatePlayers(move, activePlayer, passivePlayer):