def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. @param state : a state of an assembly problem. @return the list of all legal drop actions available in the state passed as argument. """ # Check if all elements from state are equal # In case yes use itertools.combinations to avoid repetitions. if state[1:] == state[:-1]: valid_moves = [ (a, b, c) for a, b in itertools.combinations(state, 2) for c in range(offset_range(a, b)[0], offset_range(a, b)[1]) if c is not None ] else: valid_moves = [ (a, b, c) for a, b in itertools.permutations(state, 2) for c in range(offset_range(a, b)[0], offset_range(a, b)[1]) if c is not None ] return valid_moves
def actions(self, state): """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Rotations are allowed, but no filtering out the actions that lead to doomed states. """ actionList = [] partList = list(state) possibleCombinations = it.permutations( partList, 2) #Get all possible combinations for combination in possibleCombinations: start, end = offset_range(combination[0], combination[1]) #Get all possible offset for offset in range(start, end): actionList.append( (combination[0], combination[1], offset) ) #Add the part above, part below and offset to the action list for part in partList: #loop though each part actionList.append( ("rotate", part)) #add rotation action for each piece to action list return actionList
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. @param state : a state of an assembly problem. @return the list of all legal drop actions available in the state passed as argument. """ actionList = [] partList = list(state) possibleCombinations = it.permutations( partList, 2) #Get all possible combinations for combination in possibleCombinations: start, end = offset_range( combination[0], combination[1]) #Get all possible offsets for offset in range(start, end): actionList.append( (combination[0], combination[1], offset) ) #Add the part above, part below and offset to the action list return actionList
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. @param state : a state of an assembly problem. @return the list of all legal drop actions available in the state passed as argument. """ #Make a copy of the state as a list part_list=list(state) # Make an empty array to append all legal actions (pa,pu, offset) action_list = [] for pa,pu in itertools.permutations(part_list,2): # returns the permutation of the pa, pu pair start, end = offset_range(pa, pu) # Returns start, end for offset in range(start, end): action_list.append((pa, pu, offset)) # This nested for loop will return all permutation of the pairs with a valid offset range[) # The range will include the start value and exclude the end value (to help with pythonic indexing) return action_list
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. """ # #raise NotImplementedError part_list = list(state) filtered_actions = [] for pa, pu in itertools.product(part_list, repeat=2): if pa != pu: start, end = offset_range(pa, pu) for offset in range(start, end): new_part = TetrisPart(pa, pu, offset) if new_part.offset != None: for goal in self.goal: if appear_as_subpart(new_part.get_frozen(), goal): filtered_actions.append((pa, pu, offset)) return filtered_actions
def actions(self, state): """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Rotations are allowed, but no filtering out the actions that lead to doomed states. """ # #raise NotImplementedError part_list = list(state) all_legal_actions = [] for pa_index in range(len(part_list)): all_legal_actions.append((part_list[pa_index], None, None)) for pu_index in range(len(part_list)): if pa_index != pu_index: start, end = offset_range(part_list[pa_index], part_list[pu_index]) for offset in range(start, end): all_legal_actions.append( (part_list[pa_index], part_list[pu_index], offset)) return all_legal_actions
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. """ #Make an empty list to append pruned actions action_list=[] # Make a copy of the state as a list state_list=list(state) # Make a similar nested for loop as AssemblyProblem_1 for pa,pu in itertools.permutations(state_list,2): start, end = offset_range(pa, pu) # Returns start, end for offset in range(start, end): # Make a TetrisPart of the pa,pu and offset to get a value for TetrisPart.offset temp_piece=TetrisPart(pa,pu,offset) # Pruning # If valid piece, append the action # Does it appear in the goal state? # self.goal is NOT a part -> how to convert state to part? if temp_piece.offset!=None and appear_as_subpart(temp_piece,TetrisPart(self.goal)): action_list.append((pa, pu, offset)) return action_list
def actions(self, state): #DONE """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Rotations are allowed, but no filtering out the actions that lead to doomed states. """ # EACH COMBINATION OF 2 PARTS AND AN OFFSET, OR # A PART AND A ROTATION IS AN ACTION # EACH DROP CAN EXIST WITH OFFSETS IN ALLOWABLE RANGE # RETURN LIST OF TUPLES: (pa, pu, offset) or (part, rotation) actions = [] part_list = list(make_state_canonical(state)) # HINT for u in range(0, len(part_list)): #under for a in range(0, len(part_list)): #above if u == a: # APPEND A ROTATION p = part_list[u] for rot in range(1,4): actions.append((p, rot)) else: # APPEND A DROP pa = part_list[a] pu = part_list[u] offsets = offset_range(pa, pu) for o in range(offsets[0], offsets[1]): new_part = TetrisPart(pa,pu,o) # No pruning, but check valid offset value if new_part.offset is not None: actions.append((pa, pu, o)) #tuple return actions
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. """ actionList = [] partList = list(state) goals = np.array(self.goal) possibleCombinations = it.permutations( partList, 2) #Get all possible combinations for combination in possibleCombinations: start, end = offset_range( combination[0], combination[1]) #Get all possible offsets for offset in range(start, end): resultPiece = TetrisPart(combination[0], combination[1], offset) for goal in goals: #Loop through each goal piece if ( appear_as_subpart(resultPiece.get_frozen(), goal) ): #Check if the combination is in the current goal piece actionList.append( (combination[0], combination[1], offset) ) #Add part above, part below and offset to action list return actionList
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. """ valid_moves = [ (a, b, c) for a, b in itertools.permutations(state, 2) for c in range((offset_range(a, b)[0]), (offset_range(a, b)[1])) if c is not None and appear_as_subpart( TetrisPart(part_under=b, part_above=a, offset=c).get_frozen(), self.goal[0]) ] return valid_moves
def actions(self, state): #DONE """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. Actions are just drops """ # EACH COMBINATOIN OF 2 PARTS IS AN ACTION # EACH COMBINATION CAN EXIST IN ONE OF TWO ORDERS # EACH COMBINATION CAN EXIST WITH OFFSETS IN ALLOWABLE RANGE # RETURN ACTIONS AS A TUPLE: (pa, pu, offset) actions = [] part_list = list(make_state_canonical(state)) # HINT ''' # SLOWER -> didnt use for part1, part2 in itertools.combinations(part_list, 2): for pa, pu in itertools.permutations((part1, part2)): offsets = offset_range(pa, pu) for o in range(offsets[0], offsets[1]): new_part = TetrisPart(pa,pu,o) # Check valid offset and not a duplicate if (new_part.offset is not None and (pa, pu, o) not in actions): # P R U N I N G # Check new part exists in goal, and action is unique for part in self.goal: if appear_as_subpart(new_part.get_frozen(), part): actions.append((pa, pu, o)) #tuple break #do not keep checking and appending ''' for u in range(0, len(part_list)): #under for a in range(0, len(part_list)): #above if u != a: # check index isnt the same, because actual part can be pa = part_list[a] pu = part_list[u] offsets = offset_range(pa, pu) for o in range(offsets[0], offsets[1]): new_part = TetrisPart(pa,pu,o) # Check valid offset and not a duplicate if (new_part.offset is not None and (pa, pu, o) not in actions): # P R U N I N G # Check new part exists in goal, and action is unique for part in self.goal: if appear_as_subpart(new_part.get_frozen(), part): actions.append((pa, pu, o)) #tuple break #do not keep checking and appending return actions
def actions(self, state): #DONE """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Filter out actions (drops and rotations) that are doomed to fail using the function 'cost_rotated_subpart'. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. This should be checked with the function "cost_rotated_subpart()'. """ # EACH COMBINATION OF 2 PARTS AND AN OFFSET, OR # A PART AND A ROTATION IS AN ACTION # EACH DROP CAN EXIST WITH OFFSETS IN ALLOWABLE RANGE # EACH ROTATION CAN EXIST WITH ROTATIONS 1, 2, OR 3 # RETURN LIST OF TUPLES: (pa, pu, offset) or (part, rotation) actions = [] part_list = list(make_state_canonical(state)) # HINT for u in range(0, len(part_list)): #under for a in range(0, len(part_list)): #above if u == a: # APPEND A ROTATION p = part_list[u] #Do not want to prune rotations, otherwise it will fail #to detect parts (especially if the goal is rotated after # it has been completely assembled) for r in range(1,4): if (p,r) not in actions: actions.append((p,r)) else: # APPEND A DROP pa = part_list[a] # u!= a pu = part_list[u] offsets = offset_range(pa, pu) for o in range(offsets[0], offsets[1]): # P R U N I N G # COMPUTE NEW PART # IF NEW PART EXISTS IN GOAL, APPEND THE ACTION # ROTATION IS ALLOWED (COST != INF) new_part = TetrisPart(pa,pu,o) if (new_part.offset is not None and (pa, pu, o) not in actions): # P R U N I N G # NEW PART EXISTS IN GOAL (C_R_S != INF) for part in self.goal: if (cost_rotated_subpart(new_part.get_frozen(), part) < 5): actions.append((pa, pu, o)) #tuple break #do not keep checking and appending return actions
def actions(self, state): """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Filter out actions (drops and rotations) that are doomed to fail using the function 'cost_rotated_subpart'. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. This should be checked with the function "cost_rotated_subpart()'. """ # Declare results array to store legal actions. actionsToTake = [] # Continue if there is a state. if state is not None: # Store separate parts of state in hold_state_parts array by # looping through state. hold_state_parts = [] for part in state: hold_state_parts.append(part) actionsToTake.append((part, None, 0)) # Store all combinations of both parts (all actions). permutations_hold = itertools.permutations(hold_state_parts, 2) # Loop through all combinations, find offset and store each part with offset # range in actionsToTake array. for part in permutations_hold: range_of_offset = offset_range(part[0], part[1]) range_offset = list( range(range_of_offset[0], range_of_offset[1])) for offset_number in range_offset: make_object_part = TetrisPart(part[0], part_under=part[1], offset=offset_number) part_object = make_object_part.get_frozen() # Check if part exists in final goal part with consideration of all rotations. if cost_rotated_subpart(part_object, self.goal) != np.inf: actionsToTake.append((part[0], part[1], offset_number)) # Return results array. return actionsToTake
def actions(state): part_list = list(state) legal_actions = [] for pa_index in range(len(part_list)): for pu_index in range(len(part_list)): if pa_index != pu_index: start, end = offset_range(part_list[pa_index], part_list[pu_index]) for offset in range(start, end): legal_actions.append( (part_list[pa_index], part_list[pu_index], offset)) return legal_actions
def actions(self, state): #DONE """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. @param state : a state of an assembly problem. @return i the list of all legal drop actions available in the state passed as argument. the individual actions are tuples, contained in a list. """ # EACH COMBINATOIN OF 2 PARTS IS AN ACTION # EACH COMBINATION CAN EXIST IN ONE OF TWO ORDERS # EACH COMBINATION CAN EXIST WITH OFFSETS IN ALLOWABLE RANGE # RETURN AS A LIST OF TUPLES: (pa, pu, offset) actions = [] part_list = list(make_state_canonical(state)) # HINT #cemetary: for u in range(0, len(part_list)): #under for a in range(0, len(part_list)): #above if u != a: # check index isnt the same, because actual part can be pa = part_list[a] pu = part_list[u] offsets = offset_range(pa, pu) for o in range(offsets[0], offsets[1]): new_part = TetrisPart(pa,pu,o) # No pruning, but check for valid offset value if new_part.offset is not None: actions.append((pa, pu, o)) #tuple ''' # using itertools -> SLOWER, didnt use. for part1, part2 in itertools.combinations(part_list, 2): for pa, pu in itertools.permutations((part1, part2)): offsets = offset_range(pa, pu) for o in range(offsets[0], offsets[1]): new_part = TetrisPart(pa,pu,o) # Ensure valid offset value if new_part.offset is not None: actions.append((pa,pu,o)) #tuple ''' return actions
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. """ # Declare results array to store legal drop actions. actionsToTake = [] # Continue if there is a state. if state != None: # Store separate parts of state in hold_state_parts array by # looping through state. hold_state_parts = [] for i in state: hold_state_parts.append(i) # Store all combinations of both parts (all actions). permutations_hold = itertools.permutations( hold_state_parts, 2) # Permutations of state parts # Loop through all combinations, find offset and store each part with offset # range in actionsToTake array. for part in permutations_hold: range_of_offset = offset_range(part[0], part[1]) # Get offset range range_offset = list( range(range_of_offset[0], range_of_offset[1])) for offset_number in range_offset: make_object_part = TetrisPart(part[0], part_under=part[1], offset=offset_number) part_object = make_object_part.get_frozen() # Perform search tree pruning by checking if current part appears in final # goal part by calling appear_as_subpart function. if appear_as_subpart(part_object, self.finalGoal): actionsToTake.append((part[0], part[1], offset_number)) # Return resulting array return actionsToTake
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. @param state : a state of an assembly problem. @return the list of all legal drop actions available in the state passed as argument. """ # #raise NotImplementedError # part_list = list(state) # HINT ''' part_list = list(state) all_legal_actions = [] for pa_index in range(len(part_list)): for pu_index in range(len(part_list)): if pa_index != pu_index: start, end = offset_range(part_list[pa_index], part_list[pu_index]) for offset in range(start, end): all_legal_actions.append((part_list[pa_index], part_list[pu_index], offset)) return all_legal_actions ''' part_list = list(state) all_legal_actions = [] for pa, pu in itertools.product(part_list, repeat=2): if pa != pu: start, end = offset_range(pa, pu) for offset in range(start, end): all_legal_actions.append((pa, pu, offset)) return all_legal_actions
def actions(self, state): """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Filter out actions (drops and rotations) that are doomed to fail using the function 'cost_rotated_subpart'. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. This should be checked with the function "cost_rotated_subpart()'. """ actionList = [] partList = list(state) goals = np.array(self.goal) possibleCombinations = it.permutations( partList, 2) #Get all possible combinations for combination in possibleCombinations: start, end = offset_range(combination[0], combination[1]) #Get all possible offset for offset in range(start, end): resultPiece = TetrisPart(combination[0], combination[1], offset) for goal in goals: #Loop through each goal piece cost = cost_rotated_subpart( resultPiece.get_frozen(), goal ) #Check if the cost of rotations of any goal for the piece is not np.inf if (cost != np.inf): actionList.append( (combination[0], combination[1], offset) ) #Add part above, part below and offset to action list for part in partList: #Loop through each part for goal in goals: #Loop through each goal piece numberOfRotations = cost_rotated_subpart(part, goal) if ( numberOfRotations != np.inf ): #Check if the piece needs to be rotated to be part of a goal piece actionList.append( ("rotate", part) ) #add rotation action for the part to the action list return actionList
def actions(self, state): """ Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. @param state : a state of an assembly problem. @return the list of all legal drop actions available in the state passed as argument. """ # Declare results array to store legal drop actions. actionsToTake = [] # Continue if there is a state. if state is not None: # Store separate parts of state in hold_state_parts array by # looping through state. hold_state_parts = [] for i in state: hold_state_parts.append(i) # Store all combinations of both parts (all actions). permutations_hold = itertools.permutations(hold_state_parts, 2) # Loop through all combinations, find offset and store each part with offset # range in actionsToTake array. Return actionsToTake array. for part in permutations_hold: range_of_offset = offset_range(part[0], part[1]) range_offset = list( range(range_of_offset[0], range_of_offset[1])) for offset_number in range_offset: actionsToTake.append((part[0], part[1], offset_number)) return actionsToTake
def actions(self, state): """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Rotations are allowed, but no filtering out the actions that lead to doomed states. """ # #Make a copy of the state as a list part_list=list(state) # Make an empty array to append all legal actions (pa,pu, offset) action_list = [] for pa,pu in itertools.permutations(part_list,2): # returns the permutation of the pa, pu pair start, end = offset_range(pa, pu) # Returns start, end for offset in range(start, end): action_list.append((pa, pu, offset))
def actions(self, state): """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Rotations are allowed, but no filtering out the actions that lead to doomed states. """ # Declare results array to store legal actions. actionsToTake = [] # Continue if there is a state. if state is not None: # Store separate parts of state in hold_state_parts array by # looping through state. hold_state_parts = [] for part in state: hold_state_parts.append(part) actionsToTake.append((part, None, 0)) # Store all combinations of both parts (all actions). permutations_hold = itertools.permutations(hold_state_parts, 2) # Loop through all combinations, find offset and store each part with offset # range in actionsToTake array. Return actionsToTake array. for part in permutations_hold: range_of_offset = offset_range(part[0], part[1]) range_offset = list( range(range_of_offset[0], range_of_offset[1])) for offset_number in range_offset: actionsToTake.append((part[0], part[1], offset_number)) return actionsToTake
def actions(self, state): """Return the actions that can be executed in the given state. The result would typically be a list, but if there are many actions, consider yielding them one at a time in an iterator, rather than building them all at once. Filter out actions (drops and rotations) that are doomed to fail using the function 'cost_rotated_subpart'. A candidate action is eliminated if and only if the new part it creates does not appear in the goal state. This should be checked with the function "cost_rotated_subpart()'. """ #raise NotImplementedError part_list = list(state) filtered_actions = [] for pa_index in range(len(part_list)): filtered_actions.append((part_list[pa_index], None, None)) for pu_index in range(len(part_list)): if pa_index != pu_index: start, end = offset_range(part_list[pa_index], part_list[pu_index]) for offset in range(start, end): new_part = TetrisPart(part_list[pa_index], part_list[pu_index], offset) if new_part.offset != None: if appear_as_subpart(new_part.get_frozen(), self.goal[0]): filtered_actions.append( (part_list[pa_index], part_list[pu_index], offset)) return filtered_actions