예제 #1
0
    def findPath(self):
        s = Stack()  #stack to save the path
        s.push(self._startCell)
        self._markPath(self._startCell.row, self._startCell.col)
        while True:
            #inside the loop where neighbor cell is checked for valid move
            #same time, checked if we get the exit
            if s.isEmpty():
                return False
            current_cell = s.peek()
            row = current_cell.row
            col = current_cell.col
            if not self._exitFound(row, col):
                for r in [row - 1, row, row + 1]:
                    if not (current_cell.row == s.peek().row and \
                            current_cell.col == s.peek().col):
                        break
                    for c in [col - 1, col, col + 1]:
                        if ((r == row) ^ (c == col)):
                            if self._validMove(r, c):
                                self._markPath(r, c)
                                s.push(_CellPosition(r, c))
                                break
                if current_cell.row == s.peek().row and\
                        current_cell.col == s.peek().col:
                    not_in_path = s.pop()
                    self._markTried(not_in_path.row, not_in_path.col)

            else:
                return True
예제 #2
0
    def findPath(self):
        path = Stack()
        path.push(self._startCell)
        self._mazeCells[self._startCell.row, self._startCell.col] = \
            self.PATH_TOKEN
        while not self._exitFound(path.peek().row, path.peek().col):
            curr = path.peek()
            if self._validMove(curr.row - 1, curr.col):
                path.push(_CellPosition(curr.row - 1, curr.col))
                self._markPath(curr.row - 1, curr.col)

            elif self._validMove(curr.row, curr.col - 1):
                path.push(_CellPosition(curr.row, curr.col - 1))
                self._markPath(curr.row, curr.col - 1)

            elif self._validMove(curr.row + 1, curr.col):
                path.push(_CellPosition(curr.row + 1, curr.col))
                self._markPath(curr.row + 1, curr.col)

            elif self._validMove(curr.row, curr.col + 1):
                path.push(_CellPosition(curr.row, curr.col + 1))
                self._markPath(curr.row, curr.col + 1)

            else:
                path.pop()
                self._markTried(curr.row, curr.col)
                if len(path) == 0:
                    return False
        return True
예제 #3
0
    def findPath(self):
        path_stack = Stack()
        new = self._startCell
        path_stack.push(new)

        while len(path_stack) != 0:
            new.row = path_stack.peek().row
            new.col = path_stack.peek().col
            self._markPath(new.row, new.col)
            flag_valid = False
            for i, j in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
                if self._validMove(path_stack.peek().row + i,
                                   path_stack.peek().col + j):
                    new.row = new.row + i
                    new.col = new.col + j
                    path_stack.push(_CellPosition(new.row, new.col))
                    self._markPath(new.row, new.col)
                    flag_valid = True
                    break
            if flag_valid:
                if self._exitFound(new.row, new.col):
                    self._markPath(new.row, new.col)
                    return True
                continue
            cell = path_stack.pop()
            self._markTried(cell.row, cell.col)
        return False
 def findPath( self ):
     path_stack = Stack()
     cur_cell = self._startCell
     path_stack.push(cur_cell)
     self._markPath( cur_cell.row, cur_cell.col )
     
     while len( path_stack ) != 0:
         flag_valid = 0
         for (v, h) in [(1, 0), (-1, 0), (0, -1), (0 ,1)]:
             cur_row = cur_cell.row + v
             cur_col = cur_cell.col + h
             if self._validMove( cur_row, cur_col ):
                 path_stack.push( _CellPosition(cur_row, cur_col) )
                 self._markPath( cur_row, cur_col )
                 #print "( " + str(cur_row) + ", " + str(cur_col) + " ) is valid Path Point"
                 flag_valid = 1
                 break
         if flag_valid == 0:
             pop_cell = path_stack.pop()
             self._markTried( pop_cell.row, pop_cell.col )
             #print "( " + str(pop_cell.row) + ", " + str(pop_cell.col) + " ) is Invalid Path Point"
             if len(path_stack) == 0:
                 return False
         cur_cell = path_stack.peek()
         #print "( " + str(cur_cell.row) + ", " + str(cur_cell.col) + " ) is on the top."
         if self._exitFound( cur_cell.row, cur_cell.col ):
             #print len(path_stack)
             return True
예제 #5
0
    def find_path(self):
        stack = Stack()
        current = self.startCell
        current.path.append(current)
        current.parent = current

        if current == self.exitCell:
            return True
        home_cords_nei = self.check_neighbors(current.row, current.col)
        for cell in home_cords_nei:
            if cell == self.exitCell:
                return True
            cell.path.append(current)
            stack.push(cell)
        self.mark_tried(current.row, current.col)

        while not stack.isEmpty():
            parent = current
            current = stack.peek()
            current.parent = parent
            current.path += parent.path
            current.path.append(current)

            self.mark_tried(current.row, current.col)
            if self.exit_found(current.row, current.col):
                self.exit = current
                return True
            stack.pop()
            for cell in self.check_neighbors(current.row, current.col):
                stack.push(cell)
        return False
예제 #6
0
    def findPath(self):
        """
        finds  path in a Maze and Returns True
        if no path it will return None
        """
        maze_stack = Stack()
        maze_stack.push(self._startCell)
        current_cell = self._startCell
        self._markPath(self._startCell.row, self._startCell.col)
        while not maze_stack.isEmpty():
            possible_moves = [(-1, 0), (0, 1), (1, 0), (0, -1)]

            current_cell.row = maze_stack.peek().row
            current_cell.col = maze_stack.peek().col

            self._markPath(current_cell.row, current_cell.col)

            moved = False
            for i, j in possible_moves:
                if self._validMove(current_cell.row + i, current_cell.col + j):
                    current_cell.row = current_cell.row + i
                    current_cell.col = current_cell.col + j
                    maze_stack.push(
                        _CellPosition(current_cell.row, current_cell.col))
                    moved = True
                    break
            if moved:
                if self._exitFound(current_cell.row, current_cell.col):
                    self._markPath(current_cell.row, current_cell.col)
                    return True
                continue
            visited_cell = maze_stack.pop()
            self._markTried(visited_cell.row, visited_cell.col)
예제 #7
0
파일: maze.py 프로젝트: glibesyck/Maze
 def find_path(self):
     """
     Attempts to solve the maze by finding a path from the starting cell
     to the exit. Returns True if a path is found and False otherwise.
     """
     stack_of_cells = Stack()
     stack_of_cells.push((self._start_cell.row, self._start_cell.col))
     self._mark_path(self._start_cell.row, self._start_cell.col)
     while not stack_of_cells.is_empty():
         current_cell = stack_of_cells.peek()
         valid_neighbor = False
         for direction in directions:
             if self._valid_move(current_cell[0] + direction[0],
                                 current_cell[1] + direction[1]):
                 stack_of_cells.push((current_cell[0] + direction[0],
                                      current_cell[1] + direction[1]))
                 valid_neighbor = True
                 self._mark_path(current_cell[0] + direction[0],
                                 current_cell[1] + direction[1])
                 if self._exit_found(current_cell[0] + direction[0],
                                     current_cell[1] + direction[1]):
                     return True
                 break  #we don't need 2 valid neighbor at the same time
         if not valid_neighbor:
             self._mark_tried(current_cell[0], current_cell[1])
             stack_of_cells.pop()
     return False
예제 #8
0
파일: tree23map.py 프로젝트: storypku/tlpi
    def __delitem__(self, target):
        assert target is not None, "Invalid map key."
        keyFound = False
        nodeTrack = Stack()

        node = self._root
        while node is not None:
            nodeTrack.push(node)
            if node.hasKey(target):
                keyFound = True
                break
            else:
                node = node.getBranch(target)

        if not keyFound:   # If target key not found...
            raise KeyError(target)
        # If the target node is not a leaf node, swap item with its in-order
        # successor (always leaf), and then go to the new location of item
        # to delete.
        if not nodeTrack.peek().isLeaf():
            transNode = nodeTrack.peek()
            if transNode.key1 == target:
                node = transNode.middle
            else:
                node = transNode.right
            nodeTrack.push(node)
            while not node.isLeaf():
                node = node.left
                nodeTrack.push(node)
            # <node> is anow the leaf node containing the in-order successor
            # key of <target>.
            if transNode.key1 == target:
                transNode.key1, node.key1 = node.key1, transNode.key1
                transNode.value1, node.value1 = node.value1, transNode.value1
            else:
                transNode.key2, node.key1 = node.key1, transNode.key2
                transNode.value2, node.value1 = node.value1, transNode.value2

        leafNode = nodeTrack.pop()
        if leafNode.isFull():
            self._t23DegFull(leafNode, target)
        else:
            leafNode.key1 = None
            leafNode.value1 = None
            self._t23FixNode(nodeTrack, leafNode)

        self._size -= 1
class ExtoPostfix:
	"""
	Receive an infix expression and turn it into a postfix expression.
	This is a helper module of postfixCal.py.
	"""
	def __init__(self):
		self._isp = {'#':0, '(':1, '*':5, '/':5, '+':3, '-':3, ')':6}	#in stack priority
		self._icp = {'#':0, '(':6, '*':4, '/':4, '+':2, '-':2, ')':1}	#in coming priority
		self._postfix = []		#the list used to save the final postfix expression.
		self._oprtStack = Stack()	#the stack used to change the order of operators.

	def __str__(self):
		self._postfix = [elem for elem in self._postfix if elem != ')' and elem != '(']
		return ','.join(self._postfix)

	def _getPostfix(self,expr):
		"""
		Algorithm:
		1)initialize the _oprtStack by pushing '#' into it.
		2)read in the first element of the infix expr, and assign it to variable ch.
		3)repeat the following steps until ch = '#', meanwhile, the top element of the _oprtStack is also '#':
			a)if ch is operand, append it to the _postfix, and read the next ch;
			b)if ch is operator, compare the priority(icp) of ch and the priority(isp) of the top element(op) in  _oprtStack:
				if icp(ch) > isp(op), push ch onto _oprtStack, and read another ch
				if icp(ch) < isp(op), pop the top element in _oprtStack, and append it to _postfix
				if icp(ch) == isp(op), pop the top element in _oprtStack,if op is '(', read another ch.
		"""
		expr = expr.split()
		self._oprtStack.push('#')
		ch = expr.pop(0)
		while self._oprtStack.isEmpty()==False and ch != '#':
				if ch.isdigit():
						self._postfix.append(ch)
						ch = expr.pop(0)
				else:
						ch1 = self._oprtStack.peek()
						if self._isp[ch1] < self._icp[ch]:
								self._oprtStack.push(ch)
								ch = expr.pop(0)
						elif self._isp[ch1] > self._icp[ch]:
								out = self._oprtStack.pop()
								self._postfix.append(out)
						else:
								out = self._oprtStack.pop()
								if out == '(':
										ch = expr.pop(0)

		for i in range(len(self._oprtStack)-1):
				ch1 = self._oprtStack.pop()
				self._postfix.append(ch1)

	def backExpr(self,expr):
		self._getPostfix(expr)
		return self._postfix
    def findPath( self ):
        stack = Stack()
        self._markPath(self._startCell.row, self._startCell.col) 

        stack.push(self._startCell)
        
        while not stack.isEmpty():
            # debug
            stack.show()     

            cur = _CellPosition(0, 0)
            cur.row = stack.peek().row
            cur.col = stack.peek().col
            print "current:"
            print (cur.row, cur.col) 
            if cur.row == self._exitCell.row and \
               cur.col == self._exitCell.col:
                print "findPath ok"
                return 1

            if self.haveUp(cur.row, cur.col):
                cur.row = cur.row - 1
                stack.push(cur)
                self._markPath(cur.row, cur.col) 
                continue

            if self.haveRight(cur.row, cur.col):
                cur.col = cur.col + 1
                stack.push(cur)
                self._markPath(cur.row, cur.col) 
                continue
            
            if self.haveDown(cur.row, cur.col):
                cur.row = cur.row + 1
                stack.push(cur)
                self._markPath(cur.row, cur.col) 
                continue
            
            if self.haveLeft(cur.row, cur.col):
                cur.col = cur.col - 1
                stack.push(cur)
                self._markPath(cur.row, cur.col) 
                continue

            print "aaaaaaaaaaaaa"
            self._markTried(cur.row, cur.col) 
            stack.pop() 
            stack.show()     
            

        print "findPath fail"
        return 0
예제 #11
0
    def findPath(self):
        _pathStack = Stack()
        assert self._startPos is not None, "starting position is not defined"
        _pathStack.push(self._startPos)
        _currentCellRow = _pathStack.peek().row
        _currentCellCol = _pathStack.peek().col
        while ([_currentCellRow, _currentCellCol] !=
               [self._endPos.row, self._endPos.col]):
            print("here")
            _nextPath = False
            _check = False
            for i, j in itertools.product(range(-1, 2, 1), repeat=2):
                if (abs(i - j) == 1):
                    _nextPath = self._validMove(_currentCellRow + i,
                                                _currentCellCol + j)
                    if (_nextPath):
                        _check = True
                        print(_currentCellRow + i, _currentCellCol + j, "\n")
                        self._maze[_currentCellRow + i,
                                   _currentCellCol + j] = self.MAZE_PATH_TOKEN
                        _pathStack.push(
                            CellPosition(_currentCellRow + i,
                                         _currentCellCol + j))
                        break

            if (not _check):
                removedPath = _pathStack.pop()
                self._maze[removedPath.row,
                           removedPath.col] = self.MAZE_TRIED_TOKEN
            if (_pathStack is None):

                return False
            _currentCellRow = _pathStack.peek().row
            _currentCellCol = _pathStack.peek().col

        return True
예제 #12
0
파일: maze.py 프로젝트: DariaMinieieva/maze
    def find_path(self):
        """
        Attempts to solve the maze by finding a path from the starting cell
        to the exit. Returns True if a path is found and False otherwise.
        """
        empty = self.empty_path()
        self.reset()

        mid_pos = self._start_cell
        path = Stack()
        self._mark_path(mid_pos.row, mid_pos.col)
        path.push(mid_pos)

        while mid_pos != self._exit_cell and empty:
            if _CellPosition(mid_pos.row - 1, mid_pos.col) in empty:
                mid_pos = _CellPosition(mid_pos.row - 1, mid_pos.col)
                empty.remove(mid_pos)
                self._mark_path(mid_pos.row, mid_pos.col)
                path.push(mid_pos)
                continue

            elif _CellPosition(mid_pos.row, mid_pos.col + 1) in empty:
                mid_pos = _CellPosition(mid_pos.row, mid_pos.col + 1)
                empty.remove(mid_pos)
                self._mark_path(mid_pos.row, mid_pos.col)
                path.push(mid_pos)

            elif _CellPosition(mid_pos.row + 1, mid_pos.col) in empty:
                mid_pos = _CellPosition(mid_pos.row + 1, mid_pos.col)
                empty.remove(mid_pos)
                self._mark_path(mid_pos.row, mid_pos.col)
                path.push(mid_pos)

            elif _CellPosition(mid_pos.row, mid_pos.col - 1) in empty:
                mid_pos = _CellPosition(mid_pos.row, mid_pos.col - 1)
                empty.remove(mid_pos)
                self._mark_path(mid_pos.row, mid_pos.col)
                path.push(mid_pos)

            else:
                self._mark_tried(mid_pos.row, mid_pos.col)
                path.pop()
                try:
                    mid_pos = path.peek()
                except AssertionError:
                    return False

        return True
예제 #13
0
    def findPath(self):
        path_stack = Stack()
        path_stack.push(self._startCell)
        # print(path_stack.peek().row, path_stack.peek().col)

        while len(path_stack) > 0:
            pos_row = path_stack.peek().row
            pos_col = path_stack.peek().col

            if self._validMove(pos_row - 1, pos_col):
                self._mazeCells[pos_row, pos_col] = self.PATH_TOKEN
                path_stack.push(_CellPosition(pos_row - 1, pos_col))
                if self._exitFound(pos_row - 1, pos_col):
                    self._mazeCells[pos_row - 1, pos_col] = self.PATH_TOKEN
                    return True

            elif self._validMove(pos_row + 1, pos_col):
                self._mazeCells[pos_row, pos_col] = self.PATH_TOKEN
                path_stack.push(_CellPosition(pos_row + 1, pos_col))
                if self._exitFound(pos_row + 1, pos_col):
                    self._mazeCells[pos_row + 1, pos_col] = self.PATH_TOKEN
                    return True

            elif self._validMove(pos_row, pos_col - 1):
                self._mazeCells[pos_row, pos_col] = self.PATH_TOKEN
                path_stack.push(_CellPosition(pos_row, pos_col - 1))
                if self._exitFound(pos_row, pos_col - 1):
                    self._mazeCells[pos_row, pos_col - 1] = self.PATH_TOKEN
                    return True

            elif self._validMove(pos_row, pos_col + 1):
                self._mazeCells[pos_row, pos_col] = self.PATH_TOKEN
                path_stack.push(_CellPosition(pos_row, pos_col + 1))
                if self._exitFound(pos_row, pos_col + 1):
                    self._mazeCells[pos_row, pos_col + 1] = self.PATH_TOKEN
                    return True

            else:
                self._mazeCells[pos_row, pos_col] = self.TRIED_TOKEN
                path_stack.pop()

        return False
예제 #14
0
 def find_path(self):
     if not self.maze_cells[self.exit_cell.row, self.exit_cell.col] is None:
         return False
     tmp = Stack()
     i, j = self.start_cell.row, self.start_cell.col
     dead_ends = [self.CELL_PATH, self.CELL_TRIED, self.CELL_WALL]
     directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
     tmp.push([i, j])
     self.maze_cells[i, j] = self.CELL_PATH
     while True:
         for direction in directions:
             try:
                 i1, j1 = i + direction[0], j + direction[1]
                 t = self.maze_cells[i1, j1]
             except IndexError:
                 continue
             while self.maze_cells[i1, j1] \
                     not in dead_ends:
                 i += direction[0]
                 j += direction[1]
                 tmp.push([i, j])
                 self.maze_cells[i, j] = self.CELL_PATH
                 if i == self.exit_cell.row and j == self.exit_cell.col:
                     return True
                 if i == self.start_cell.row and j == self.start_cell.col:
                     return False
         if self.check_cell(i, j) is None:
             while True:
                 coor = tmp.pop()
                 if tmp.isEmpty():
                     return False
                 self.maze_cells[coor[0], coor[1]] = self.CELL_TRIED
                 coor = tmp.peek()
                 tmpcoor = self.check_cell(coor[0], coor[1])
                 if tmpcoor:
                     i, j = coor[0], coor[1]
                     break
         if i == self.start_cell.row and j == self.start_cell.col:
             return False
         if i == self.exit_cell.row and j == self.exit_cell.col:
             return True
예제 #15
0
    def find_path(self):
        """
        Attempts to solve the maze by finding a path from the starting cell
        to the exit. Returns True if a path is found and False otherwise.
        """
        maze_path = Stack()
        first_position = self._start_cell
        curr_row = first_position.row
        curr_col = first_position.col
        maze_path.push(_CellPosition(curr_row, curr_col))
        self._mark_path(curr_row, curr_col)

        while not self._exit_found(curr_row, curr_col):

            for direction in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
                new_row = curr_row + direction[0]
                new_col = curr_col + direction[1]
                if self._valid_move(new_row, new_col):
                    curr_row = new_row
                    curr_col = new_col
                    maze_path.push(_CellPosition(curr_row, curr_col))
                    self._mark_path(curr_row, curr_col)
                    break

                else:
                    continue

            else:
                self._mark_tried(curr_row, curr_col)
                maze_path.pop()
                if maze_path.is_empty():
                    return False
                previous_cell = maze_path.peek()
                curr_row = previous_cell.row
                curr_col = previous_cell.col

        return True
예제 #16
0
class Maze:
    # Define constants to represent contents of the maze cells.
    MAZE_WALL = "%"  # *
    PATH_TOKEN = "."  # x
    TRIED_TOKEN = "-"  # o

    # Creates a maze object with all cells marked as open.
    def __init__(self, numRows, numCols):
        self._mazeCells = Array2D(numRows, numCols)
        self._startCell = None
        self._exitCell = None
        self._path = Stack()
        self._path_found = False

    # Returns the number of rows in the maze.
    def numRows(self):
        return self._mazeCells.numRows()

    # Returns the number of columns in the maze.
    def numCols(self):
        return self._mazeCells.numCols()

    # Fills the indicated cell with a "wall" marker.
    def setWall(self, row, col):
        assert row >= 0 and row < self.numRows() and col >= 0 and col < self.numCols(), "Cell index out of range."
        self._mazeCells.__setitem__((row, col), self.MAZE_WALL)

    # Sets the starting cell position.
    def setStart(self, row, col):
        assert row >= 0 and row < self.numRows() and col >= 0 and col < self.numCols(), "Cell index out of range."
        self._startCell = _CellPosition(row, col)

    # Sets the exit cell position.
    def setExit(self, row, col):
        assert row >= 0 and row < self.numRows() and col >= 0 and col < self.numCols(), "Cell index out of range."
        self._exitCell = _CellPosition(row, col)

    # Attempts to solve the maze by finding a path from the starting cell
    # to the exit. Returns True if a path is found and False otherwise.
    def findPath(self):
        start = (self._startCell.row, self._startCell.col)
        end = (self._exitCell.row, self._exitCell.col)
        # If start is the same as end, then there's an error
        if start == end:
            return False
        self._path.push(start)
        self.make_a_move()
        return self._path_found

    def make_a_move(self):
        # Keep recursion going until stack is empty from not
        # finding a path
        if self._path._size > 0:
            cur_row, cur_col = self._path.peek()
            # If the current cell is also the exit cell
            # Break out of the recursion and return True!
            if self._exitFound(cur_row, cur_col):
                self._markPath(cur_row, cur_col)
                self._path_found = True
                return
            # Checks to see if any of the surrounding cells are
            # valid to move into- up, right, bottom, left
            # If there are valid moves available, move into one
            if (
                self._validMove(cur_row - 1, cur_col)
                or self._validMove(cur_row, cur_col + 1)
                or self._validMove(cur_row + 1, cur_col)
                or self._validMove(cur_row, cur_col - 1)
            ):
                # Mark the current cell we're on as 'tried'
                self._markPath(cur_row, cur_col)
                # We will now go for one of the next cells
                if self._validMove(cur_row - 1, cur_col):
                    self._path.push((cur_row - 1, cur_col))
                    self.make_a_move()
                elif self._validMove(cur_row, cur_col + 1):
                    self._path.push((cur_row, cur_col + 1))
                    self.make_a_move()
                elif self._validMove(cur_row + 1, cur_col):
                    self._path.push((cur_row + 1, cur_col))
                    self.make_a_move()
                elif self._validMove(cur_row, cur_col - 1):
                    self._path.push((cur_row, cur_col - 1))
                    self.make_a_move()
            # Otherwise, we are at a dead end and must backtrace
            else:
                self._markTried(self._path.peek()[0], self._path.peek()[1])
                self._path.pop()
                self.make_a_move()

    # Resets the maze by removing all "path" and "tried" tokens.
    # def reset( self ):
    # ......

    # Prints a text-based representation of the maze.
    def draw(self):
        # For each row
        for row, row_ndx in enumerate(range(self.numRows())):
            row_display = ""
            # Iterate through the number of columns there are
            # And then print the (row) value
            for col, col_ndx in enumerate(range(self.numCols())):
                if self._mazeCells.__getitem__((row_ndx, col_ndx)) == None:
                    row_display += " "
                else:
                    row_display += str(self._mazeCells.__getitem__((row_ndx, col_ndx)))
            print row_display

    # Returns True if the given cell position is a valid move.
    def _validMove(self, row, col):
        return (
            row >= 0
            and row < self.numRows()
            and col >= 0
            and col < self.numCols()
            and self._mazeCells[row, col] is None
        )

    # Helper method to determine if the exit was found.
    def _exitFound(self, row, col):
        return row == self._exitCell.row and col == self._exitCell.col

    # Drops a "tried" token at the given cell.
    def _markTried(self, row, col):
        self._mazeCells.__setitem__((row, col), self.TRIED_TOKEN)

    # Drops a "path" token at the given cell.
    def _markPath(self, row, col):
        self._mazeCells.__setitem__((row, col), self.PATH_TOKEN)
예제 #17
0
class Maze:
    # Define constants to represent contents of the maze cells.
    MAZE_WALL = " *"
    PATH_TOKEN = " x"
    TRIED_TOKEN = " o"

    # Creates a maze object with all cells marked as open.
    def __init__(self, num_rows, num_cols):
        self.stack = Stack()
        self._mazeCells = Array2D(num_rows, num_cols)
        self._startCell = None
        self._exitCell = None
        self.st = Stack()

    # Returns the number of rows in the maze.
    def num_rows(self):
        return self._mazeCells.num_rows()

    # Returns the number of columns in the maze.
    def num_cols(self):
        return self._mazeCells.num_cols()

    # Fills the indicated cell with a "wall" marker.
    def setWall(self, row, col):
        assert 0 <= row < self.num_rows() and \
               0 <= col < self.num_cols(), "Cell index out of range."
        self._mazeCells[row, col] = self.MAZE_WALL

    # Sets the starting cell position.
    def setStart(self, row, col):
        assert 0 <= row < self.num_rows() and \
               0 <= col < self.num_cols(), "Cell index out of range."
        self._startCell = _CellPosition(row, col)

    # Sets the exit cell position.
    def setExit(self, row, col):
        assert 0 <= row < self.num_rows() and \
               0 <= col < self.num_cols(), "Cell index out of range."
        self._exitCell = _CellPosition(row, col)

    # Method to find neighbour cells
    def neighbours(self, _row, _col):
        info = []
        for coord in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
            row, col = _row + coord[0], _col + coord[1]
            if self._validMove(row, col):
                if not self._mazeCells[row, col]:
                    info.append(_CellPosition(row, col))
        return info

    # Attempts to solve the maze by finding a path from the starting cell
    # to the exit. Returns True if a path is found and False otherwise.
    def findPath(self):
        self.stack.push(self._startCell)

        while len(self.stack):
            current = self.stack.peek()
            row, col = current.row, current.col

            if self._exitFound(row, col):
                self._markPath(row, col)
                return True

            fine_cells = self.neighbours(row, col)
            if fine_cells:
                self._markPath(row, col)
                for element in fine_cells:
                    self.stack.push(element)
            else:
                self._markTried(row, col)
                self.stack.pop()

    # Resets the maze by removing all "path" and "tried" tokens.
    def reset(self):
        for row in range(self._mazeCells.num_rows()):
            for col in range(self._mazeCells.num_cols()):
                if self._mazeCells[row, col] in [" x", " o"]:
                    self._mazeCells[row, col] = None

    # Prints a text-based representation of the maze.
    def draw(self):
        for row in range(self._mazeCells.num_rows()):
            for col in range(self._mazeCells.num_cols()):
                if self._mazeCells[row, col]:
                    print(self._mazeCells[row, col], end=" ")
                else:
                    print("  ", end=" ")
            print()

    # Returns True if the given cell position is a valid move.
    def _validMove(self, row, col):
        return 0 <= row < self.num_rows() \
               and 0 <= col < self.num_cols() \
               and self._mazeCells[row, col] is None

    # Helper method to determine if the exit was found.
    def _exitFound(self, row, col):
        return row == self._exitCell.row and col == self._exitCell.col

    # Drops a "tried" token at the given cell.
    def _markTried(self, row, col):
        self._mazeCells[row, col] = self.TRIED_TOKEN

    # Drops a "path" token at the given cell.
    def _markPath(self, row, col):
        self._mazeCells[row, col] = self.PATH_TOKEN
예제 #18
0
 def find_path(self):
     """
     Attempts to solve the maze by finding a path from the starting cell
     to the exit. Returns True if a path is found and False otherwise.
     """
     path = Stack()
     i = self._start_cell.row
     j = self._start_cell.col
     counter = 0
     while True:
         check = 0
         if self._exit_found(i, j):
             for _ in range(len(path)):
                 coord = path.pop()
                 self._maze_cells[coord[0], coord[1]] = "x"
             self._maze_cells[self._exit_cell.row,
                              self._exit_cell.col] = "x"
             return True
         if (self._valid_move(i - 1, j)
                 and self._maze_cells[i - 1, j] == None and check == 0):
             if path.is_empty() or path.peek() != (i - 1, j):
                 path.push((i, j))
                 counter = 0
                 check = 1
                 i -= 1
             elif counter == 1:
                 self._maze_cells[i, j] = "o"
                 try:
                     path.pop()
                 except AssertionError:
                     return False
                 counter = 0
                 check = 1
                 i -= 1
             else:
                 counter += 1
         if (self._valid_move(i, j + 1)
                 and self._maze_cells[i, j + 1] == None and check == 0):
             if path.is_empty() or path.peek() != (i, j + 1):
                 path.push((i, j))
                 counter = 0
                 check = 1
                 j += 1
             elif counter == 1:
                 self._maze_cells[i, j] = "o"
                 try:
                     path.pop()
                 except AssertionError:
                     return False
                 counter = 0
                 check = 1
                 j += 1
             else:
                 counter += 1
         if (self._valid_move(i + 1, j)
                 and self._maze_cells[i + 1, j] == None and check == 0):
             if path.is_empty() or path.peek() != (i + 1, j):
                 path.push((i, j))
                 counter = 0
                 check = 1
                 i += 1
             elif counter == 1:
                 self._maze_cells[i, j] = "o"
                 try:
                     path.pop()
                 except AssertionError:
                     return False
                 counter = 0
                 check = 1
                 i += 1
             else:
                 counter += 1
         if (self._valid_move(i, j - 1)
                 and self._maze_cells[i, j - 1] == None and check == 0):
             if path.is_empty() or path.peek() != (i, j - 1):
                 path.push((i, j))
                 counter = 0
                 check = 1
                 j -= 1
             elif counter == 1:
                 self._maze_cells[i, j] = "o"
                 try:
                     path.pop()
                 except AssertionError:
                     return False
                 counter = 0
                 check = 1
                 j -= 1
             else:
                 counter += 1
         if check == 0 and counter == 0:
             return False
예제 #19
0
class Maze:
    # Define constants to represent contents of the maze cells.
    MAZE_WALL = "%"  #*
    PATH_TOKEN = "."  #x
    TRIED_TOKEN = "-"  #o

    # Creates a maze object with all cells marked as open.
    def __init__(self, numRows, numCols):
        self._mazeCells = Array2D(numRows, numCols)
        self._startCell = None
        self._exitCell = None
        self._path = Stack()
        self._path_found = False

    # Returns the number of rows in the maze.
    def numRows(self):
        return self._mazeCells.numRows()

    # Returns the number of columns in the maze.
    def numCols(self):
        return self._mazeCells.numCols()

    # Fills the indicated cell with a "wall" marker.
    def setWall(self, row, col):
        assert row >= 0 and row < self.numRows() and \
        col >= 0 and col < self.numCols(), "Cell index out of range."
        self._mazeCells.__setitem__((row, col), self.MAZE_WALL)

    # Sets the starting cell position.
    def setStart(self, row, col):
        assert row >= 0 and row < self.numRows() and \
        col >= 0 and col < self.numCols(), "Cell index out of range."
        self._startCell = _CellPosition(row, col)

    # Sets the exit cell position.
    def setExit(self, row, col):
        assert row >= 0 and row < self.numRows() and \
        col >= 0 and col < self.numCols(), \
        "Cell index out of range."
        self._exitCell = _CellPosition(row, col)

    # Attempts to solve the maze by finding a path from the starting cell
    # to the exit. Returns True if a path is found and False otherwise.
    def findPath(self):
        start = (self._startCell.row, self._startCell.col)
        end = (self._exitCell.row, self._exitCell.col)
        # If start is the same as end, then there's an error
        if start == end:
            return False
        self._path.push(start)
        self.make_a_move()
        return self._path_found

    def make_a_move(self):
        # Keep recursion going until stack is empty from not
        # finding a path
        if self._path._size > 0:
            cur_row, cur_col = self._path.peek()
            # If the current cell is also the exit cell
            # Break out of the recursion and return True!
            if self._exitFound(cur_row, cur_col):
                self._markPath(cur_row, cur_col)
                self._path_found = True
                return
            # Checks to see if any of the surrounding cells are
            # valid to move into- up, right, bottom, left
            # If there are valid moves available, move into one
            if (self._validMove(cur_row - 1, cur_col) or \
                self._validMove(cur_row, cur_col + 1) or \
                self._validMove(cur_row + 1, cur_col) or \
                self._validMove(cur_row, cur_col - 1)):
                # Mark the current cell we're on as 'tried'
                self._markPath(cur_row, cur_col)
                # We will now go for one of the next cells
                if self._validMove(cur_row - 1, cur_col):
                    self._path.push((cur_row - 1, cur_col))
                    self.make_a_move()
                elif self._validMove(cur_row, cur_col + 1):
                    self._path.push((cur_row, cur_col + 1))
                    self.make_a_move()
                elif self._validMove(cur_row + 1, cur_col):
                    self._path.push((cur_row + 1, cur_col))
                    self.make_a_move()
                elif self._validMove(cur_row, cur_col - 1):
                    self._path.push((cur_row, cur_col - 1))
                    self.make_a_move()
            # Otherwise, we are at a dead end and must backtrace
            else:
                self._markTried(self._path.peek()[0], self._path.peek()[1])
                self._path.pop()
                self.make_a_move()

    # Resets the maze by removing all "path" and "tried" tokens.
    #def reset( self ):
    #......

    # Prints a text-based representation of the maze.
    def draw(self):
        # For each row
        for row, row_ndx in enumerate(range(self.numRows())):
            row_display = ''
            # Iterate through the number of columns there are
            # And then print the (row) value
            for col, col_ndx in enumerate(range(self.numCols())):
                if self._mazeCells.__getitem__((row_ndx, col_ndx)) == None:
                    row_display += ' '
                else:
                    row_display += str(
                        self._mazeCells.__getitem__((row_ndx, col_ndx)))
            print row_display

    # Returns True if the given cell position is a valid move.
    def _validMove(self, row, col):
        return row >= 0 and row < self.numRows() \
        and col >= 0 and col < self.numCols() \
        and self._mazeCells[row, col] is None

    # Helper method to determine if the exit was found.
    def _exitFound(self, row, col):
        return row == self._exitCell.row and \
        col == self._exitCell.col

    # Drops a "tried" token at the given cell.
    def _markTried(self, row, col):
        self._mazeCells.__setitem__((row, col), self.TRIED_TOKEN)

    # Drops a "path" token at the given cell.
    def _markPath(self, row, col):
        self._mazeCells.__setitem__((row, col), self.PATH_TOKEN)
예제 #20
0
class ExtoPostfix:
    """
    Receive an infix expression and turn it into a postfix expression.
    This is a helper module of postfixCal.py.
    """
    def __init__(self):
        self._isp = {
            '#': 0,
            '(': 1,
            '*': 5,
            '/': 5,
            '+': 3,
            '-': 3,
            ')': 6
        }  # in stack priority
        self._icp = {
            '#': 0,
            '(': 6,
            '*': 4,
            '/': 4,
            '+': 2,
            '-': 2,
            ')': 1
        }  # in coming priority
        # the list used to save the final postfix expression.
        self._postfix = []
        # the stack used to change the order of operators.
        self._oprtStack = Stack()

    def __str__(self):
        self._postfix = [
            elem for elem in self._postfix if elem != ')' and elem != '('
        ]
        return ','.join(self._postfix)

    def _getPostfix(self, expr):
        """
        Algorithm:
        1)initialize the _oprtStack by pushing '#' into it.
        2)read in the first element of the infix expr, and assign it to variable ch.
        3)repeat the following steps until ch = '#', meanwhile, the top element of the _oprtStack is also '#':
                a)if ch is operand, append it to the _postfix, and read the next ch;
                b)if ch is operator, compare the priority(icp) of ch and the priority(isp) of the top element(op) in  _oprtStack:
                        if icp(ch) > isp(op), push ch onto _oprtStack, and read another ch
                        if icp(ch) < isp(op), pop the top element in _oprtStack, and append it to _postfix
                        if icp(ch) == isp(op), pop the top element in _oprtStack,if op is '(', read another ch.
        """
        expr = expr.split()
        self._oprtStack.push('#')
        ch = expr.pop(0)
        while self._oprtStack.isEmpty() == False and ch != '#':
            if ch.isdigit():
                self._postfix.append(ch)
                ch = expr.pop(0)
            else:
                ch1 = self._oprtStack.peek()
                if self._isp[ch1] < self._icp[ch]:
                    self._oprtStack.push(ch)
                    ch = expr.pop(0)
                elif self._isp[ch1] > self._icp[ch]:
                    out = self._oprtStack.pop()
                    self._postfix.append(out)
                else:
                    out = self._oprtStack.pop()
                    if out == '(':
                        ch = expr.pop(0)

        for i in range(len(self._oprtStack) - 1):
            ch1 = self._oprtStack.pop()
            self._postfix.append(ch1)

    def backExpr(self, expr):
        self._getPostfix(expr)
        return self._postfix