Skip to content
Snippets Groups Projects
Commit 2471335a authored by Xuan Trinh's avatar Xuan Trinh
Browse files

attempt to clean up the code , add type hinting + make use of global variable....

attempt to clean up the code , add type hinting + make use of global variable. XUAN TRINH 1:30PM 28 mar 2021
parent 714a9746
No related branches found
No related tags found
No related merge requests found
...@@ -9,5 +9,12 @@ ...@@ -9,5 +9,12 @@
</list> </list>
</option> </option>
</inspection_tool> </inspection_tool>
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers">
<list>
<option value="tuple.*" />
</list>
</option>
</inspection_tool>
</profile> </profile>
</component> </component>
\ No newline at end of file
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
...@@ -5,15 +5,15 @@ Project Part A: Searching ...@@ -5,15 +5,15 @@ Project Part A: Searching
This script contains the entry point to the program (the code in This script contains the entry point to the program (the code in
`__main__.py` calls `main()`). Your solution starts here! `__main__.py` calls `main()`). Your solution starts here!
""" """
import sys import sys
import json import json
from search.search_algo import *
from search.search_algorithm import *
def main(): def main():
# define global variable # define global variable
global upperDictPieces, lowerDictPieces, targetDict, setBlocks global upperPiecesDict, lowerPiecesDict, targetsDict, setBlocks
try: try:
with open(sys.argv[1]) as file: with open(sys.argv[1]) as file:
data = json.load(file) data = json.load(file)
...@@ -22,27 +22,19 @@ def main(): ...@@ -22,27 +22,19 @@ def main():
sys.exit(1) sys.exit(1)
parse_input(data) parse_input(data)
# So basically it is heavily implied to treat the game as a state-based search problem.
# We are also told in question 3 of the design report to discuss the time and space
# requirements, and the connection with the branching factor and search tree depth.
# In question 2 we are told to comment on any heuristics we use.
# Considering all of the above, I propose that we use the heuristic of "tiles to closest target"
# This is greedy, but it's a lot faster than trying to path optimally.
# And for search algorithm choice let's try starting with depth-first search, depth limit 1, 2 or 3
# Not sure which is best at the moment, looking ahead is good but looking too far ahead costs too much time
# We'll use a dictionary to track current targets
# ALGORITHM GOES HERE
# Add starting targets # Add starting targets
for piece in upperDictPieces: for piece in upperPiecesDict:
find_target(piece) find_target(piece)
# keep moving until all the piece met its target # keep moving until all the piece met its target
while targetDict: while targetsDict:
input() input()
upperDictPieces = update_state(upperDictPieces, lowerDictPieces, setBlocks, targetDict) take_turn()
targetDict = check_if_piece_hit_target(upperDictPieces, lowerDictPieces, targetDict) make_board()
print_board(board)
file.close()
print_board(make_board(lowerDictPieces,upperDictPieces,setBlocks))
def parse_input(data): def parse_input(data):
""" """
...@@ -56,7 +48,7 @@ def parse_input(data): ...@@ -56,7 +48,7 @@ def parse_input(data):
# We can put the code to read the file NOT in the try/except statement because # We can put the code to read the file NOT in the try/except statement because
# if the file couldn't be read the process would end anyway # if the file couldn't be read the process would end anyway
global upperDictPieces, lowerDictPieces, setBlocks global upperPiecesDict, lowerPiecesDict, setBlocks, positionHistory
initialPiecesUpper = data["upper"] initialPiecesUpper = data["upper"]
initialPiecesLower = data["lower"] initialPiecesLower = data["lower"]
initialBlocks = data["block"] initialBlocks = data["block"]
...@@ -75,8 +67,8 @@ def parse_input(data): ...@@ -75,8 +67,8 @@ def parse_input(data):
else: else:
nums = nums + 1 nums = nums + 1
keyWrite = "S" + str(nums) keyWrite = "S" + str(nums)
upperDictPieces[keyWrite] = (piece[ROW], piece[COLUMN]) upperPiecesDict[keyWrite] = (piece[F_ROW], piece[F_COLUMN])
visit_record[keyWrite] = {} positionHistory[keyWrite] = {}
# parse the Lower player's token # parse the Lower player's token
nump, numr, nums = 0, 0, 0 nump, numr, nums = 0, 0, 0
...@@ -90,18 +82,11 @@ def parse_input(data): ...@@ -90,18 +82,11 @@ def parse_input(data):
else: else:
nums = nums + 1 nums = nums + 1
keyWrite = "s" + str(nums) keyWrite = "s" + str(nums)
lowerDictPieces[keyWrite] = (piece[ROW], piece[COLUMN]) lowerPiecesDict[keyWrite] = (piece[F_ROW], piece[F_COLUMN])
# parse the block object # parse the block object
for block in initialBlocks: for block in initialBlocks:
setBlocks.add((block[ROW], block[COLUMN])) setBlocks.add((block[F_ROW], block[F_COLUMN]))
# Situation 1: If you plan the route ahead without knowing any other piece route, # Situation 1: If you plan the route ahead without knowing any other piece route,
# there will be a crash at tile N as both R and S try to take a straight line # there will be a crash at tile N as both R and S try to take a straight line
......
...@@ -306,7 +306,8 @@ def distance_between(Upper_token, Lower_token): ...@@ -306,7 +306,8 @@ def distance_between(Upper_token, Lower_token):
under section: double coordinates for doublewidth under section: double coordinates for doublewidth
-> ->
""" """
dx = abs(Upper_token[0] - Lower_token[0])
dy = abs(Upper_token[1] - Lower_token[1]) dx = abs(Upper_token[1] - Lower_token[1])
dy = abs(Upper_token[0] - Lower_token[0])
result = dx + max(0, (dy - dx) / 2) result = dx + max(0, (dy - dx) / 2)
return result return result
...@@ -30,6 +30,7 @@ visit_record = {} ...@@ -30,6 +30,7 @@ visit_record = {}
def make_board(lowerPieces, upperPieces, setBlocks): def make_board(lowerPieces, upperPieces, setBlocks):
""" """
done
create a board of the current game -> can do a position look up. create a board of the current game -> can do a position look up.
:param upperPieces: dictionary contain all the upper piece and its location :param upperPieces: dictionary contain all the upper piece and its location
:param lowerPieces: dictionary contain all the lower piece and its location :param lowerPieces: dictionary contain all the lower piece and its location
...@@ -50,6 +51,7 @@ def make_board(lowerPieces, upperPieces, setBlocks): ...@@ -50,6 +51,7 @@ def make_board(lowerPieces, upperPieces, setBlocks):
def get_stronger_piece(piece_type): def get_stronger_piece(piece_type):
""" """
done
Stronger piece is base on the type, even if the piece are from a player. Stronger piece is base on the type, even if the piece are from a player.
:param piece_type: the type of the piece that we are interested :param piece_type: the type of the piece that we are interested
:return: the type of the piece that stronger than the input piece :return: the type of the piece that stronger than the input piece
...@@ -63,6 +65,7 @@ def get_stronger_piece(piece_type): ...@@ -63,6 +65,7 @@ def get_stronger_piece(piece_type):
def add_slide_action(upperDict, piece, board): def add_slide_action(upperDict, piece, board):
""" """
done
add all the valid slide action to a list add all the valid slide action to a list
:param board: dictionary contain all piece and block :param board: dictionary contain all piece and block
:param upperDict: contain detail about upper piece :param upperDict: contain detail about upper piece
...@@ -94,6 +97,7 @@ def add_slide_action(upperDict, piece, board): ...@@ -94,6 +97,7 @@ def add_slide_action(upperDict, piece, board):
def add_if_valid(position_list, piece, new_position, piece_position, board): def add_if_valid(position_list, piece, new_position, piece_position, board):
""" """
done
check if the move is valid. check if the move is valid.
:param position_list: list contain all added slide action from this turn :param position_list: list contain all added slide action from this turn
:param piece: the interested upper piece :param piece: the interested upper piece
...@@ -123,6 +127,7 @@ def add_if_valid(position_list, piece, new_position, piece_position, board): ...@@ -123,6 +127,7 @@ def add_if_valid(position_list, piece, new_position, piece_position, board):
def make_priority_list_of_action(upperDict, piece, targetDict, board): def make_priority_list_of_action(upperDict, piece, targetDict, board):
""" """
done
compile all possible action this piece can under go. compile all possible action this piece can under go.
sort them base on the result distance relative to the piece's target sort them base on the result distance relative to the piece's target
:param upperDict: use to read the position of the piece :param upperDict: use to read the position of the piece
...@@ -152,6 +157,7 @@ def make_priority_list_of_action(upperDict, piece, targetDict, board): ...@@ -152,6 +157,7 @@ def make_priority_list_of_action(upperDict, piece, targetDict, board):
def update_state(upperPieces, lowerPieces, setBlocks, targetDict): def update_state(upperPieces, lowerPieces, setBlocks, targetDict):
""" """
done
move the piece in a way that bring all piece closer to its target move the piece in a way that bring all piece closer to its target
# currently only in away that is work for one piece. # currently only in away that is work for one piece.
:param upperPieces: dictionary contain all the upper piece :param upperPieces: dictionary contain all the upper piece
...@@ -175,6 +181,7 @@ def update_state(upperPieces, lowerPieces, setBlocks, targetDict): ...@@ -175,6 +181,7 @@ def update_state(upperPieces, lowerPieces, setBlocks, targetDict):
def choose_optimal_combination(possible_action, upperPieces, board, targetDict): def choose_optimal_combination(possible_action, upperPieces, board, targetDict):
""" """
done
prioritise action lead a piece directly to its target. prioritise action lead a piece directly to its target.
else choose a combination that does not cause collision between upper piece else choose a combination that does not cause collision between upper piece
...@@ -238,6 +245,12 @@ def choose_optimal_combination(possible_action, upperPieces, board, targetDict): ...@@ -238,6 +245,12 @@ def choose_optimal_combination(possible_action, upperPieces, board, targetDict):
def decrease_appeal(position, piece): def decrease_appeal(position, piece):
"""
done
:param position:
:param piece:
:return:
"""
global visit_record global visit_record
if position not in visit_record[piece].keys(): if position not in visit_record[piece].keys():
...@@ -249,6 +262,7 @@ def decrease_appeal(position, piece): ...@@ -249,6 +262,7 @@ def decrease_appeal(position, piece):
def check_if_piece_hit_target(upperPieces, lowerPieces, targetDict): def check_if_piece_hit_target(upperPieces, lowerPieces, targetDict):
""" """
done
remove the target from the target dictionary if the upper piece is at its target location remove the target from the target dictionary if the upper piece is at its target location
:param upperPiece: contain all upper piece :param upperPiece: contain all upper piece
:param targetDict: map upper piece to its lower target :param targetDict: map upper piece to its lower target
...@@ -281,6 +295,7 @@ def check_if_piece_hit_target(upperPieces, lowerPieces, targetDict): ...@@ -281,6 +295,7 @@ def check_if_piece_hit_target(upperPieces, lowerPieces, targetDict):
def piece_collision(pieceA, pieceB) -> int: def piece_collision(pieceA, pieceB) -> int:
""" """
done
Our upper pieces are R, P and S, lower pieces are r, p and s Our upper pieces are R, P and S, lower pieces are r, p and s
We will convert both to lower case letters and check each case We will convert both to lower case letters and check each case
Would be nice to use comparator but can't have r>s>p>r using it Would be nice to use comparator but can't have r>s>p>r using it
...@@ -317,6 +332,7 @@ def piece_collision(pieceA, pieceB) -> int: ...@@ -317,6 +332,7 @@ def piece_collision(pieceA, pieceB) -> int:
def add_swing_action(upperDict, piece, board): def add_swing_action(upperDict, piece, board):
""" """
done
check for adjacent tile. check for adjacent tile.
if there are any adjacent tile to this add swing action from those tile if there are any adjacent tile to this add swing action from those tile
:param upperDict: contain all the upper piece :param upperDict: contain all the upper piece
...@@ -381,6 +397,7 @@ def add_swing_action(upperDict, piece, board): ...@@ -381,6 +397,7 @@ def add_swing_action(upperDict, piece, board):
def find_target(piece_key): def find_target(piece_key):
""" """
done
This function changes the value of the key given in the This function changes the value of the key given in the
target dictionary to the closest enemy piece it can beat target dictionary to the closest enemy piece it can beat
XUAN: by separated the upper to lower piece, we dont need to search for the whole dictionary every time we compare. XUAN: by separated the upper to lower piece, we dont need to search for the whole dictionary every time we compare.
...@@ -420,6 +437,13 @@ def find_target(piece_key): ...@@ -420,6 +437,13 @@ def find_target(piece_key):
def rank_by_appeal(x, targetDict, piece): def rank_by_appeal(x, targetDict, piece):
"""
done
:param x:
:param targetDict:
:param piece:
:return:
"""
# distance_between(x, targetDict[piece]) # distance_between(x, targetDict[piece])
# make_priority_list_of_action(upperDict, piece, targetDict, board) # make_priority_list_of_action(upperDict, piece, targetDict, board)
# the reduce would base on how close it is to its target and how many time we visit this. # the reduce would base on how close it is to its target and how many time we visit this.
......
""" """
logic: This module is hold all method relate to Search algorithm
-> prioritise the action which take the token closer to its target
""" """
from search.main import * from search.movement_logic import *
from search.search_algo import piece_collision
# Constant definition:
from search.util import print_board from search.util import print_board
BLOCK = "[X]"
UPPER_ROCK = 'R'
UPPER_SCISSOR = 'S'
UPPER_PAPER = 'P'
LOWER_ROCK = 'r'
LOWER_PAPER = 'p'
LOWER_SCISSOR = 's'
TYPE = 0
F_ROW = 1
F_COLUMN = 2
ROW = 0
COLUMN = 1
A_WIN = 1
B_WIN = 2
DRAW = 1
MAX_DISTANCE = 10
FIRST_ENTRY = 1
RE_ENTRY = 1
HIGHEST_RANK = 0
# Global variable:
# All the dictionary is made into global variable since all method is interact with them
upperPiecesDict = {}
lowerPiecesDict = {}
setBlocks = set()
targetsDict = {}
# keep track all the lower player's piece <- to ensure no two Upper piece can target only one distinguish lower piece
targetedPiece = set()
# keep track of how many time a upper piece visit a tile while aiming for a target.
# this help rank the action.
positionHistory = {}
board = {} board = {}
'''
METHOD
'''
def get_weaker_piece(piece: str) -> str:
"""
get the weaker piece type in low case
:param piece: key of the piece {e.g: 'r1'}
:return: a single character the follow the rule: P> R> S> P
"""
if piece[TYPE] in [LOWER_ROCK, UPPER_ROCK]:
return LOWER_SCISSOR
elif piece[TYPE] in [LOWER_PAPER, UPPER_PAPER]:
return LOWER_ROCK
return LOWER_PAPER
def add_to_queue(token, state, targetDict): def get_stronger_piece(piece: str) -> str:
""" """
-> check the adjacent tile for potential move. get the stronger piece type in low case
-> add them into a priority queue :param piece: key of the piece {e.g: 'R1'}
:param targetDict: :return: a single character that follow the rule: P> R> S> P
:param state: run
:param token: the one that we want to choose an action for
:return: the list sort base on how close it is to the token's target
""" """
# add all the adjacent move to queue if piece[TYPE] in [LOWER_ROCK, UPPER_ROCK]:
appending_list = add_adjacent_action(token, state) return LOWER_PAPER
elif piece[TYPE] in [LOWER_PAPER, UPPER_PAPER]:
return LOWER_SCISSOR
return LOWER_ROCK
# sort the list base on the how close it is to target
appending_list.sort()
appending_list.sort(key=(lambda x: distance_between(x, targetDict[token])))
def make_board():
"""
add all the piece into a dictionary of board:
(1) -> help with illustrate the current board
(2) -> faster look up using a location.
"""
global board
for piece in lowerPiecesDict:
board[lowerPiecesDict[piece]] = piece
for piece in upperPiecesDict:
board[upperPiecesDict[piece]] = piece
for block in setBlocks:
board[block] = BLOCK
return appending_list
def add_if_allowed(list, token, token_new_position, token_position): def check_valid_action(piece: str, new_position: tuple) -> bool:
""" """
handle check if the tile has sit on top of a block. check if the action is resolved successfully.
or if it is sit on top on a token would beat it -> no piece should defeat any other piece unless the one whom it defeated is its Target.
:param list: the temporary list to append to while await to process -> cant move on top the Block
:param token: the adjcent tile of a token :param piece: we investigate
:param token_new_position: :param new_position: result after perform the action
:return: the list so the local change can be pass to higher scope :return: True if the action is successful. False if there are invalid move
""" """
if compare_tile(token_new_position, token_position): # check if if the action happen {if it fail the new_position will be same as piece's position}
return list if compare_tile(upperPiecesDict[piece], new_position):
if token_new_position == token_new_position not in board.keys() or \ return False
board[token_new_position] != "" or \
board[token_new_position] != get_stronger_token(token): # check if new_position is the piece's target
list.append(token_new_position) if piece in targetsDict.keys() and compare_tile(targetsDict[piece], new_position):
return list return True
# check if the position result from an action is into a free tile.
if new_position in board.keys():
if board[new_position] == BLOCK:
return False
if piece_collision(board[new_position], piece) != DRAW:
return False
return True
def add_adjacent_action(token, state): def check_in(position: tuple, piece: str):
""" """
create a abstraction to hide implementation detail on how to add adjacent move. log each time piece visit a tile.
check if the any slide action is allowed. -> if the piece comeplete its journey {arrived at its Target's location}
:param token:token that we want to find a direction to :param position: of the piece
:return: the queue :param piece: that we want to log
""" """
appending_list = [] global positionHistory
# first time visit this tile.
if position not in positionHistory[piece].keys():
positionHistory[piece][position] = FIRST_ENTRY
else:
positionHistory[piece][position] += RE_ENTRY
# check the right tile
appending_list = add_if_allowed(appending_list, token, slide_right(state[token]), state[token])
# check the left tile def rank(position: tuple, piece: str) -> int:
appending_list = add_if_allowed(appending_list, token, slide_left(state[token]), state[token]) """
rank is base on how far of interested position to piece's target position
-> how ever position is will be rank lower if it is visit before
:param position: we want to rank
:param piece: rank base on the piece
:return: rank
"""
# base rank is the distance between current position to the piece's target
baseRank = distance_between(position, targetsDict[piece])
# reduce_factor is base on how many time has this piece visit current tile.
reduceFactor = 0
if piece in positionHistory.keys() and position in positionHistory[piece].keys():
reduceFactor = positionHistory[piece][position]
# check the up_left return baseRank + reduceFactor
appending_list = add_if_allowed(appending_list, token, slide_up_left(state[token]), state[token])
# check the up_uight
appending_list = add_if_allowed(appending_list, token, slide_up_right(state[token]), state[token])
# check the down_left def piece_collision(pieceA: str, pieceB: str) -> int:
appending_list = add_if_allowed(appending_list, token, slide_down_left(state[token]), state[token]) """
Our upper pieces are R, P and S, lower pieces are r, p and s
We will convert both to lower case letters and check each case
Would be nice to use comparator but can't have r>s>p>r using it
# check the down_right :param pieceA: type of the token in {'R','P','S','r','p','s'}
appending_list = add_if_allowed(appending_list, token, slide_down_right(state[token]), state[token]) :param pieceB: type of the token in {'R','P','S','r','p','s'}
:return: A_WIN, B_WIN or DRAW
"""
pieceA = pieceA[TYPE].lower()
pieceB = pieceB[TYPE].lower()
if pieceA is LOWER_ROCK:
if pieceB == LOWER_SCISSOR:
return A_WIN
elif pieceB == LOWER_PAPER:
return B_WIN
return appending_list elif pieceA == LOWER_SCISSOR:
if pieceB == LOWER_PAPER:
return A_WIN
elif pieceB == LOWER_ROCK:
return B_WIN
elif pieceA == LOWER_PAPER:
if pieceB == LOWER_ROCK:
return A_WIN
elif pieceB == LOWER_SCISSOR:
return B_WIN
return DRAW
def get_stronger_token(token):
if token[FIRST_CHAR] == 'R':
return 'p'
if token[FIRST_CHAR] == 'S':
return 'r'
return 's'
def slide_action(piece: str) -> list:
"""
for each piece there will be 6 total position as result of slide action.
-> check each to ensure they are valid move
:param piece: will perform an slide action
:return: unsorted list of all the valid action
"""
action_list = []
def update_state(state, setblocks, targetDict): position = upperPiecesDict[piece]
for action in (slide_right(position), slide_left(position), slide_up_left(position),
slide_up_right(position), slide_down_left(position), slide_down_right(position)):
if check_valid_action(piece, action):
action_list.append(action)
make_board(state, setblocks) return action_list
print("\n\n")
print_board(board) def swing_action(piece: str) -> list:
for token in state: """
if token[0] in ('s', 'p', 'r'): for each adjacent piece there will be at most 3 swing move.
print("continue") -> check those move to ensure they are valid
:param piece: will perform swing action
:return: unsorted list of all valid action
"""
# find all the adjacent piece
adjacent_pieces = []
position = upperPiecesDict[piece]
for tile in (slide_right(position), slide_left(position), slide_up_left(position),
slide_up_right(position), slide_down_left(position), slide_down_right(position)):
# check if the move is not out of board
if not compare_tile(position, tile):
# the tile can be any object except block
if tile in board and board[tile] != BLOCK:
adjacent_pieces.append(tile)
# if there are at least one adjacent piece, add the position result from performing swing action from those piece.
action_list = []
for adjacent_piece in adjacent_pieces:
for action in (swing_to_tile_1(position, adjacent_piece), swing_to_tile_2(position, adjacent_piece),
swing_to_tile_3(position, adjacent_piece)):
if check_valid_action(piece, action):
action_list.append(action)
return action_list
def find_target(piece: str):
"""
Find a weaker piece to this piece which closest
-> only add if that potential target is not targeted by any other upper piece.
:param piece: which we want to map a target to
"""
global targetsDict
# get the target
targetType = get_weaker_piece(piece)
targetDistance = MAX_DISTANCE
target = ""
for lowerPiece in lowerPiecesDict:
if lowerPiece[TYPE] == targetType and lowerPiece not in targetedPiece:
distance = distance_between(upperPiecesDict[piece], lowerPiecesDict[lowerPiece])
if distance < targetDistance:
target = lowerPiece
targetDistance = distance
if targetDistance != MAX_DISTANCE:
targetsDict[piece] = lowerPiecesDict[target]
targetedPiece.add(target)
def make_ranked_move_list(piece: str) -> list:
"""
add all the possible position after perform an action.
sort them according to their rank{low to high}
:param piece: will be perform the move
:return: sorted list of position
"""
# add all the valid adjacent position result from perform a slide action
position_list = slide_action(piece)
# add all the valid position result from perform a swing action
position_list.extend(swing_action(piece))
# rank the list base on how close it is to its target. The least visited position the higher rank it is.
if piece in targetsDict.keys():
position_list.sort(key=(lambda x: rank(x, piece)))
return position_list
def perform_optimal_combination(move_list: dict):
"""
perform an action from each of the piece sorted action list.
-> prioritise action that after complete bring piece to its target.
-> then choose an action from those piece with the least choice.
-> then choose action from the remained piece in a way that not cause collision
:param move_list: contain all the pottential moved for all piece
"""
# perform all the action that directly lead the piece to its target.
priority_list = []
for piece in move_list:
if piece in targetsDict.keys() and compare_tile(move_list[piece][HIGHEST_RANK], targetsDict[piece]):
# perform swap and update board
del board[upperPiecesDict[piece]]
upperPiecesDict[piece] = targetsDict[piece]
board[targetsDict[piece]] = piece
else:
priority_list.append(piece)
# sort the list base on number of action.
priority_list.sort(key=(lambda key: len(move_list[key])))
# perform an action that does not result in a collision.
for piece in priority_list:
index = HIGHEST_RANK
moved = False
while not moved:
if index >= len(move_list[piece]):
break
if move_list[piece][index] in board.keys() and\
piece_collision(board[move_list[piece][index]], piece) != DRAW:
index += 1
continue continue
potential_new_position = add_to_queue(token, state, targetDict) # perform the action
state[token] = potential_new_position[0] if upperPiecesDict[piece] in board.keys():
print(state[token]) del board[upperPiecesDict[piece]]
return state upperPiecesDict[piece] = move_list[piece][index]
def make_board(state, setblocks): board[move_list[piece][index]] = piece
global board moved = True
board = {}
for piece in state: check_in(move_list[piece][index], piece)
board[state[piece]] = piece
for block in setblocks:
board[block] = ''
def take_turn():
"""
each turn: map out the board in order to look up easily.
choose a combination of move that is partially optimal {move all the piece <some time> closer to its target}
"""
make_board()
print_board(board)
possible_actions = {}
for piece in upperPiecesDict:
possible_actions[piece] = make_ranked_move_list(piece)
perform_optimal_combination(possible_actions)
update_target_dictionary()
def update_target_dictionary():
"""
removed all piece that hit its target.
attempt to assign it a new target.
:return:
"""
global targetsDict, lowerPiecesDict, positionHistory
removed = False
deleted = []
for piece in targetsDict.keys():
if compare_tile(upperPiecesDict[piece], targetsDict[piece]):
# remove the defeated piece
removed_piece = ""
for removed_p in lowerPiecesDict:
if compare_tile(lowerPiecesDict[removed_p], targetsDict[piece]):
removed_piece = removed_p
break
deleted.append(piece)
del lowerPiecesDict[removed_piece]
targetedPiece.remove(removed_piece)
# reset the log for visited node
positionHistory[piece] = {}
removed = True
for piece in deleted:
del targetsDict[piece]
# once the piece hit it target, it is free to find a new target.
# if there are more lower piece then which already targeted {some lower piece is not target}
# we can check if the available pieces can target those
if removed and len(lowerPiecesDict) > len(targetsDict):
for piece in upperPiecesDict:
# when a piece is remove then there will
if piece in targetsDict.keys():
continue
find_target(piece)
\ No newline at end of file
print('R' in ('R', 's')) from search.movement_logic import distance_between
print(distance_between((2, -2), (4, 0)))
print(distance_between((2, -1), (4, 0)))
print(distance_between((1, 0), (4, 0)))
print(distance_between((0, 0), (4, 0)))
print(distance_between((0, -1), (4, 0)))
print(distance_between((1, -2), (4, 0)))
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment