def toBase(decimal,base):
    # if base is greater than 16, raise error
    if base >16 or base <=0:
        raise ValueError ('base must be between 1 and 16')
    elif isinstance(decimal,int)==False:
        raise ValueError('the number must be a integer')
    elif decimal==0:
        return str(0)
    
    hex_num = "0123456789ABCDEF"
    
    s = Stack()

    while decimal > 0:
        remainder = decimal % base
        s.push(remainder)
        decimal = decimal // base

    output = ""
    # want to pop all the stack contents out
    while not s.isEmpty():
    #hex_num[s.pop()] would make sure base>10, the alphabet would be used
        output += hex_num[s.pop()]
    
    return output

#testing
# print(toBase(101,2)) # should be 1100101
# print(toBase(101,16)) # should be 65
# print(toBase(188,16)) # should be BC
class QueueUsingStack:
    '''
        Implementing Queue using two stacks
        We implement only enqueue and dequeue methods
    '''
    def __init__(self):
        self.a_stack = Stack(20)
        self.b_stack = Stack(20)

    def enqueue(self, x):
        self.a_stack.push(x)
        print("Enqueueing element: {}\n".format(x))
        print("A Stack: ", end="")
        self.a_stack.print()
        print("B Stack: ", end="")
        self.b_stack.print()
        print("---------------------------------------------")

    def dequeue(self):
        if not self.b_stack.isEmpty():
            element = self.b_stack.pop()
        else:
            while (self.a_stack.top != 0):
                x = self.a_stack.pop()
                self.b_stack.push(x)
            element = self.a_stack.pop()

        print("Dequeued element: {}\n".format(element))
        print("A Stack: ", end="")
        self.a_stack.print()
        print("B Stack: ", end="")
        self.b_stack.print()
        print("---------------------------------------------")
        return element
Exemplo n.º 3
0
def infixToPostfix(infixexpr):
    from stacks import Stack
    from string import digits, ascii_uppercase
    print(infixexpr)
    infixexpr = infixexpr.replace('**', '^')
    print(infixexpr)
    tokenList = ''.join(
        [' ' + x + ' ' if not x in digits else x for x in infixexpr])
    tokenList = tokenList.split()
    print(tokenList)

    prec = {}
    prec['^'] = 4
    prec['*'] = 3
    prec['/'] = 3
    prec['+'] = 2
    prec['-'] = 2
    prec['('] = 1
    postfixList = []
    opStack = Stack()

    for token in tokenList:
        if token in ascii_uppercase or token.isdigit():
            postfixList.append(token)
        elif token == '(':
            opStack.push(token)
        elif token == ')':
            if not opStack.isEmpty():
                topStack = opStack.pop()
            while not opStack.isEmpty() and topStack != '(':
                postfixList.append(topStack)
                topStack = opStack.pop()
        else:
            while not opStack.isEmpty() and prec[
                    opStack.peek()] >= prec[token]:
                postfixList.append(opStack.pop())
            opStack.push(token)

    while not opStack.isEmpty():
        postfixList.append(opStack.pop())
    result = ' '.join(postfixList)
    result = result.replace('^', '**')
    return result
Exemplo n.º 4
0
def sortAscendingOrder(s1):
    s2 = Stack()
    while not s1.isEmpty():
        # print 'S2:', s2.stack()
        # print 'S1:', s1.stack()
        last = s1.pop()
        while (not s2.isEmpty() and s2.peek() > last):
            s1.push(s2.pop())
        s2.push(last)
    return s2
Exemplo n.º 5
0
def sortAscendingOrder(s1):
    s2 = Stack()
    while not s1.isEmpty():
        # print 'S2:', s2.stack()
        # print 'S1:', s1.stack()
        last = s1.pop()
        while (not s2.isEmpty() and s2.peek() > last):
            s1.push(s2.pop())
        s2.push(last)
    return s2
Exemplo n.º 6
0
def deciToBin(num):
    binaryStack = Stack()
    binNum = ""
    print(f"The binary of {num} is: ", end="")
    while num > 0:
        binaryStack.push(num % 2)
        num = num // 2

    while not (binaryStack.isEmpty()):
        binNum += str(binaryStack.peek())
        binaryStack.pop()
    print(binNum)
Exemplo n.º 7
0
def searchDFSTrace(graph, start, end):
    stack = Stack()
    stack.push([start])
    while not stack.isEmpty():
        path = stack.pop()
        last = path[-1]
        if last == end:
            return path
        for adjacent in graph.get(last, []):
            new_path = list(path)
            new_path.append(adjacent)
            stack.push(new_path)
Exemplo n.º 8
0
def searchDFSTrace(graph, start, end):
    stack = Stack()
    stack.push([start])
    while not stack.isEmpty():
        path = stack.pop()
        last = path[-1]
        if last == end:
            return path
        for adjacent in graph.get(last, []):
            new_path = list(path)
            new_path.append(adjacent)
            stack.push(new_path)
Exemplo n.º 9
0
def balanceCheck(strng):
    brackets = Stack()
    index = 0
    isBalanced = True
    while index < len(strng) and isBalanced:
        content = strng[index]
        ending = content in ")}]"
        if not (brackets.isEmpty()):
            if ending:
                brackets.pop()
            else:
                brackets.push(content)
        elif ending and brackets.isEmpty():
            isBalanced = False
        else:
            brackets.push(content)
        index += 1
    if isBalanced:
        print("It is balanced!")
    else:
        print("It is unbalanced!")
Exemplo n.º 10
0
def searchDFS(graph, start):
    visited = []
    stack = Stack()
    stack.push(start)
    while not stack.isEmpty():
        vertex = stack.pop()
        if vertex not in visited:
            visited.append(vertex)
            print "VERTEX", vertex
            for edges in graph[vertex]:
                stack.push(edges)
    return visited
Exemplo n.º 11
0
def searchDFS(graph, start):
    visited = []
    stack = Stack()
    stack.push(start)
    while not stack.isEmpty():
        vertex = stack.pop()
        if vertex not in visited:
            visited.append(vertex)
            print 'VERTEX', vertex
            for edges in graph[vertex]:
                stack.push(edges)
    return visited
Exemplo n.º 12
0
def stringReverse(s: str) -> str:
	#Creating a Stack Object
	stack = Stack()
	#For every character in string push to stack
	for x in s:
		stack.push(x)
	revStr = "" #The string to be returned
	#While the stack is not empty
	while not stack.isEmpty():
		#Add the popped element to the revStr
		revStr += stack.pop()
	return revStr
def isBracketBalanced(valueString):
    s = Stack()
    index = 0
    isBalanced = True

    while index < len(valueString) and isBalanced:

        character = valueString[index]
        if character in "([{":
            s.push(character)
        else:
            if s.isEmpty():
                isBalanced = False
            else:
                top = s.pop()
                if not isMatch(top, character):
                    isBalanced = False

        index += 1
    if s.isEmpty() and isBalanced:
        return True
    else:
        return False
Exemplo n.º 14
0
def divideBy2(decNumber):
    remStack = Stack()

    while decNumber > 0:
        rem = decNumber % 2
        remStack.push(rem)
        decNumber = decNumber // 2

    binString = ""

    while not remStack.isEmpty():
        binString = binString + str(remStack.pop())

    return binString
Exemplo n.º 15
0
def convertBase(num, base=2):
    from stacks import Stack
    s = Stack()
    while num != 0:
        remainder = str(num % base)
        numList = ['10', '11', '12', '13', '14', '15']
        if remainder in numList:
            remainder = 'ABCDEF'[numList.index(remainder)]
        s.push(remainder)
        num //= base
    convertedNum = ''
    while not s.isEmpty():
        convertedNum += s.pop()
    return convertedNum
Exemplo n.º 16
0
def integerToBinary(num: int) -> str:
  #Initialising the Stack Object
	s = Stack()
	ans = num
	while ans != 0:
    #Appending the remainder to the Stack
		s.push(ans % 2)
    #Storing the non decimal part of divison by floor divison
		ans = ans//2 
	binary = ""
  #While stack isn't empty pop into binary
	while not s.isEmpty():
		binary += str(s.pop())
	return binary
Exemplo n.º 17
0
def isBracketBalanced(string: str) -> bool:

    bracketStack = Stack()
    isBalanced = True
    index = 0

    while index < len(string) and isBalanced:
        x = string[index]
        if x in "({[":
            bracketStack.push(x)
        else:
            if bracketStack.isEmpty():
                isBalanced = False
            else:
                top = bracketStack.pop()
                if not isAMatch(top, x):
                    isBalanced = False
        index += 1

    if bracketStack.isEmpty() and isBalanced:
        return True
    else:
        return False
Exemplo n.º 18
0
def baseConverter(decNumber, base):
    digits = "0123456789ABCDEF"
    remStack = Stack()

    while decNumber > 0:
        rem = decNumber % base
        remStack.push(rem)
        decNumber = decNumber // base

    new_string = ""

    while not remStack.isEmpty():
        new_string = new_string + digits[remStack.pop()]

    return new_string
Exemplo n.º 19
0
def parenthesisChecker(parString):
    s = Stack()
    for sym in parString:
        # if it is a open parenthesis, push in
        if sym in "([{":
            s.push(sym)
        elif sym in ")]}":
            # if it is a close parenthesis but the stack is empty, return false
            if s.isEmpty():
                return False
            else:
                top = s.pop()
                # the close parenthesis needs to match, if not match, return false
                if not parenthesisMatches(top, sym):
                    return False
    # if everything goes well and did not return False early then the parString is fine and return True
    return True
Exemplo n.º 20
0
def generateMaze(nodes):
    nodes.getEmptyGrid()
    index = randint(0, len(nodes.nodeList)-1)
    nodeEnd = nodes.nodeList[index]
    nodeEnd.visited = True
    allNodesVisited = False
    #print "start = " + str(index)
    stack = Stack()

    while not allNodesVisited:
        unvisitedNodes = nodes.getUnvisitedNodes()
        index = randint(0, len(unvisitedNodes)-1)
        nodeStart = unvisitedNodes[index]
        endFound = False
        stack.push(nodeStart)
        while not endFound:
            directionList = nodes.getDirections(stack.peek())
            directionIndex = randint(0, len(directionList)-1)
            direction = directionList[directionIndex]
            nodeNext = nodes.getUnlinkedNode(stack.peek(), direction)
            if not nodeNext.visited:
                if stack.contains(nodeNext):
                    while stack.peek() is not nodeNext:
                        stack.pop()
                else:
                    stack.push(nodeNext)
            else:
                #Carve out the path that is defined by the stack
                stack.push(nodeNext)
                endFound = True
                while not stack.isEmpty():
                    node1 = stack.pop()
                    node2 = stack.peek()
                    node1.visited = True
                    if node2 is not None:
                        #print node1, node2
                        direction = nodes.getDirectionFromNodes(node1, node2)
                        nodes.addPath(node1, direction)
                    else:
                        stack.clear()
                    
        unvisitedNodes = nodes.getUnvisitedNodes()
        if len(unvisitedNodes) == 0:
            allNodesVisited = True
Exemplo n.º 21
0
def abs_to_relative_two(s):
    stack = Stack()
    index = 0
    len_f = len(s)
    while index < len_f:
        while index< len_f and s[index] != '.':
            stack.push(s[index])
            index += 1
        point_count = 0
        while index<len_f and s[index] == '.':
            index += 1
            point_count += 1
        if point_count == 2:
            stack.pop()
            while not stack.isEmpty() and stack.peer() != '/':
                stack.pop()

        index += 1
    return ''.join(stack.items) # print relative path
Exemplo n.º 22
0
def generateMaze(nodes):
    nodes.getEmptyGrid()
    index = randint(0, len(nodes.nodeList)-1)
    node = nodes.nodeList[index]
    node.visited = True
    allNodesVisited = False
    #print "start = " + str(node.row) + ", " + str(node.column)
    stack = Stack()
    #unvisitedNeighbors = nodes.getUnvisitedNeighbors(node)
    #print len(unvisitedNeighbors)
    stack.push(node)

    while not stack.isEmpty():
        unvisitedNeighbors = nodes.getUnvisitedNeighbors(stack.peek())
        #print "Unvisited Neighbors = " + str(len(unvisitedNeighbors))
        if len(unvisitedNeighbors) > 0:
            index = randint(0, len(unvisitedNeighbors)-1)
            nodeNext = unvisitedNeighbors[index]
            direction = nodes.getDirectionFromNodes(stack.peek(), nodeNext)
            nodes.addPath(stack.peek(), direction)
            nodeNext.visited = True
            stack.push(nodeNext)
        else:
            stack.pop()
Exemplo n.º 23
0
class Ghost(MazeMouse):
    def __init__(self, nodes, level, spritesheet):
        MazeMouse.__init__(self, nodes, level, spritesheet)
        self.name = "ghost"
        self.goal = Vector2D()
        self.modeStack = self.setupModeStack()
        self.mode = self.modeStack.pop()
        self.modeTimer = 0
        self.homeNode = None
        self.startDirection = UP
        self.exitHome = True
        self.guideDog = False
        self.leftHome = True
        self.previousDirection = None

    def setGuideStack(self):
        self.guideStack = Stack()
        self.guideStack.push(LEFT)
        self.guideStack.push(UP)

    def getStartNode(self):
        node = MAZEDATA[self.level]["start"]["ghost"]
        return self.nodes.getNode(*node, nodeList=self.nodes.homeList)

    def setStartPosition(self):
        self.setHomeNode()
        self.direction = self.startDirection
        self.target = self.node.neighbors[self.direction]
        self.setPosition()
        self.checkDirectionChange()

    def checkDirectionChange(self):
        if self.direction != self.previousDirection:
            self.previousDirection = self.direction
            row = self.imageRow
            col = 0
            if self.mode.name == "SPAWN":
                row, col = self.setSpawnImages()
            elif self.mode.name != "FREIGHT":
                if self.direction == LEFT:
                    col = 4
                elif self.direction == RIGHT:
                    col = 6
                elif self.direction == DOWN:
                    col = 2
                elif self.direction == UP:
                    col = 0

            self.setImage(row, col)

    def setImage(self, row, col):
        self.image = self.spritesheet.getImage(col, row, 32, 32)

    def setSpawnImages(self):
        row = 6
        if self.direction == LEFT:
            col = 6
        elif self.direction == RIGHT:
            col = 7
        elif self.direction == DOWN:
            col = 4
        elif self.direction == UP:
            col = 5
        return row, col

    def getClosestDirection(self, validDirections):
        distances = []
        for direction in validDirections:
            diffVec = self.node.position + direction * WIDTH - self.goal
            distances.append(diffVec.magnitudeSquared())
        index = distances.index(min(distances))
        return validDirections[index]

    def getValidDirections(self):
        validDirections = []
        for key in self.node.neighbors.keys():
            if self.node.neighbors[key] is not None:
                if not key == self.direction * -1:
                    validDirections.append(key)
        if len(validDirections) == 0:
            validDirections.append(self.forceBacktrack())

        if (self.node.home and DOWN in validDirections
                and self.mode.name != "SPAWN"):
            validDirections.remove(DOWN)

        if self.node.nowayUp and UP in validDirections:
            validDirections.remove(UP)

        if not self.leftHome:
            if self.exitHome:
                validDirections = self.guideOutOfHome(validDirections)
            else:
                validDirections = self.trapInHome(validDirections)

        return validDirections

    def randomDirection(self, validDirections):
        index = randint(0, len(validDirections) - 1)
        return validDirections[index]

    def moveBySelf(self):
        if self.overshotTarget():
            self.node = self.target
            self.portal()
            validDirections = self.getValidDirections()
            self.direction = self.getClosestDirection(validDirections)
            self.target = self.node.neighbors[self.direction]
            self.setPosition()
            if self.mode.name == "SPAWN":
                if self.position == self.goal:
                    self.mode = self.modeStack.pop()

    def forceBacktrack(self):
        if self.direction * -1 == UP:
            return UP
        if self.direction * -1 == DOWN:
            return DOWN
        if self.direction * -1 == LEFT:
            return LEFT
        if self.direction * -1 == RIGHT:
            return RIGHT

    def setupModeStack(self):
        modes = Stack()
        modes.push(Mode(name="CHASE"))
        modes.push(Mode(name="SCATTER", time=5))
        modes.push(Mode(name="CHASE", time=20))
        modes.push(Mode(name="SCATTER", time=7))
        modes.push(Mode(name="CHASE", time=20))
        modes.push(Mode(name="SCATTER", time=7))
        modes.push(Mode(name="CHASE", time=20))
        modes.push(Mode(name="SCATTER", time=7))
        return modes

    def setScatterGoal(self):
        self.goal = Vector2D()

    def setChaseGoal(self, pacman):
        self.goal = pacman.position

    def modeUpdate(self, dt):
        self.modeTimer += dt
        if self.mode.time is not None:
            if self.modeTimer >= self.mode.time:
                self.reverseGhostDirection()
                self.mode = self.modeStack.pop()
                self.modeTimer = 0

    def update(self, dt, pacman, blinky):
        speedMod = self.modifySpeed()
        self.position += self.direction * speedMod * dt
        self.modeUpdate(dt)
        if self.mode.name == "CHASE":
            self.setChaseGoal(pacman, blinky)
        elif self.mode.name == "SCATTER":
            self.setScatterGoal()
        elif self.mode.name == "FREIGHT":
            self.setRandomGoal()
        elif self.mode.name == "SPAWN":
            self.setSpawnGoal()
        self.moveBySelf()
        if self.mode.name != "FREIGHT":
            self.checkDirectionChange()
        else:
            if (self.mode.time - self.modeTimer) < 1:
                self.setImage(6, 2)

    def modifySpeed(self):
        if (self.node.portalNode is not None
                or self.target.portalNode is not None):
            return self.speed / 2.0
        return self.speed * self.mode.speedMult

    def setFreightMode(self):
        if self.mode.name != "SPAWN":
            if self.mode.name != "FREIGHT":
                if self.mode.time is not None:
                    dt = self.mode.time - self.modeTimer
                    self.modeStack.push(Mode(name=self.mode.name, time=dt))
                else:
                    self.modeStack.push(Mode(name=self.mode.name))
                self.reverseGhostDirection()
                self.mode = Mode("FREIGHT", time=7, speedMult=0.5)
                self.modeTimer = 0

            else:
                self.mode = Mode("FREIGHT", time=7, speedMult=0.5)
                self.modeTimer = 0
            self.setImage(6, 0)

    def setRandomGoal(self):
        x = randint(0, NCOLS * WIDTH)
        y = randint(0, NROWS * HEIGHT)
        self.goal = Vector2D(x, y)

    def setRespawnMode(self):
        self.mode = Mode("SPAWN", speedMult=2)
        self.modeTimer = 0
        self.setGuideStack()
        self.leftHome = False

    def setSpawnGoal(self):
        self.goal = self.homeNode.position

    def trapInHome(self, validDirections):
        if LEFT in validDirections:
            validDirections.remove(LEFT)
        if RIGHT in validDirections:
            validDirections.remove(RIGHT)
        return validDirections

    def guideOutOfHome(self, validDirections):
        if not self.guideDog:
            if self.target == self.homeNode:
                self.guideDog = True
                validDirections = []
                validDirections.append(self.guideStack.pop())
        else:
            validDirections = []
            validDirections.append(self.guideStack.pop())
            if self.guideStack.isEmpty():
                self.guideDog = False
                self.leftHome = True
        return validDirections

    def reverseGhostDirection(self):
        if self.leftHome:
            self.reverseDirection()
Exemplo n.º 24
0
class NodeGroup(object):
    def __init__(self, width, height):
        '''width and height are the minimum distance between nodes'''
        self.nodeList = []
        self.width = width
        self.height = height
        self.grid = None
        self.nodeStack = Stack()
        self.fRows = 0
        self.fCols = 0
        
    def getNode(self, row, col):
        '''Get the node from the nodeList given the row and col'''
        for node in self.nodeList:
            if node.row == row and node.col == col:
                return node
        return None

    def getNodeFromNode(self, node):
        '''Checks list of node already exists, if so get that node.
           If node does not exist, then return the input node'''
        if node is not None:
            #return self.getNode(node.row, node.col)
            for inode in self.nodeList:
                if node.row == inode.row and node.col == inode.col:
                    return inode
        return node
    
    def findFirstNodeInGrid(self, rows, cols):
        '''Searches grid until it runs into a node, return that Node'''
        nodeFound = False
        for row in range(rows):
            for col in range(cols):
                if self.grid[row][col] == "+":
                    return Node(col, row, self.width, self.height)
        return None

    def addNode(self, node):
        '''Add a node to the nodeList if not already in the list'''
        nodeInList = self.nodeInList(node)
        if not nodeInList:
            self.nodeList.append(node)

    def nodeInList(self, node):
        '''Return True if the node is already in nodeList'''
        for inode in self.nodeList:
            if node.row == inode.row and node.col == inode.col:
                return True
        return False
    
    def createNodeListFromFile(self, filename):
        '''Creates a connected nodelist from a properly formatted file'''
        self.grid = loadtxt(filename, dtype=str)
        self.fRows, self.fCols = self.grid.shape
        startNode = self.findFirstNodeInGrid(self.fRows, self.fCols)
        self.nodeStack.push(startNode)
        # print self.grid.shape
        while not self.nodeStack.isEmpty():
            node = self.nodeStack.pop()
            self.addNode(node)
            leftNode = self.followPath(LEFT, node.row, node.col)
            rightNode = self.followPath(RIGHT, node.row, node.col)
            upNode = self.followPath(UP, node.row, node.col)
            downNode = self.followPath(DOWN, node.row, node.col)
            leftNode = self.getNodeFromNode(leftNode)
            rightNode = self.getNodeFromNode(rightNode)
            upNode = self.getNodeFromNode(upNode)
            downNode = self.getNodeFromNode(downNode)
            node.neighbors[LEFT] = leftNode
            node.neighbors[RIGHT] = rightNode
            node.neighbors[UP] = upNode
            node.neighbors[DOWN] = downNode
            if leftNode is not None and not self.nodeInList(leftNode):
                self.nodeStack.push(leftNode)
            if rightNode is not None and not self.nodeInList(rightNode):
                self.nodeStack.push(rightNode)
            if upNode is not None and not self.nodeInList(upNode):
                self.nodeStack.push(upNode)
            if downNode is not None and not self.nodeInList(downNode):
                self.nodeStack.push(downNode)

    def followPath(self, direction, row, col):
        if direction == LEFT and col-1 >= 0:
            if self.grid[row][col-1] == "-" or self.grid[row][col-1] == "+":
                while self.grid[row][col-1] != "+":
                    col -= 1
                return Node(col-1, row, self.width, self.height)
            else:
                return None
        elif direction == RIGHT and col+1 < self.fCols:
            if self.grid[row][col+1] == "-" or self.grid[row][col+1] == "+":
                while self.grid[row][col+1] != "+":
                    col += 1
                return Node(col+1, row, self.width, self.height)
            else:
                return None
        elif direction == UP and row-1 >= 0:
            if self.grid[row-1][col] == "|" or self.grid[row-1][col] == "+":
                while self.grid[row-1][col] != "+":
                    row -= 1
                return Node(col, row-1, self.width, self.height)
            else:
                return None
        elif direction == DOWN and row+1 < self.fRows:
            if self.grid[row+1][col] == "|" or self.grid[row+1][col] == "+":
                while self.grid[row+1][col] != "+":
                    row += 1
                return Node(col, row+1, self.width, self.height)
            else:
                return None
        else:
            return None    

    def render(self, screen):
        for node in self.nodeList:
            node.render(screen)
Exemplo n.º 25
0
class NodeGroup(object):
    def __init__(self, level):
        self.level = level
        self.nodeList = []
        self.grid = None
        self.nodeStack = Stack()
        self.nodeSymbols = ["+", "n", "N", "M", "H", "F"]
        self.homeList = []
        self.createMainList()
        self.createHomeList()

    def createMainList(self):
        self.createNodeList(MAZEDATA[self.level]["file"], self.nodeList)
        self.setupPortalNodes()

    def createHomeList(self):
        self.createNodeList("home.txt", self.homeList)
        self.moveHomeNodes()
        
    def createNodeList(self, textFile, nodeList):
        self.grid = loadtxt(textFile, dtype=str)
        startNode = self.findFirstNode(*self.grid.shape)
        self.nodeStack.push(startNode)
        while not self.nodeStack.isEmpty():
            node = self.nodeStack.pop()
            self.addNode(node, nodeList)
            leftNode = self.getPathNode(LEFT, node.row, node.column-1, nodeList)
            rightNode = self.getPathNode(RIGHT, node.row, node.column+1, nodeList)
            upNode = self.getPathNode(UP, node.row-1, node.column, nodeList)
            downNode = self.getPathNode(DOWN, node.row+1, node.column, nodeList)
            node.neighbors[LEFT] = leftNode
            node.neighbors[RIGHT] = rightNode
            node.neighbors[UP] = upNode
            node.neighbors[DOWN] = downNode
            self.addNodeToStack(leftNode, nodeList)
            self.addNodeToStack(rightNode, nodeList)
            self.addNodeToStack(upNode, nodeList)
            self.addNodeToStack(downNode, nodeList)
        self.setupPortalNodes()

    def getNode(self, x, y, nodeList=[]):
        for node in nodeList:
            if node.position.x == x and node.position.y == y:
                return node
        return None

    def getNodeFromNode(self, node, nodeList):
        if node is not None:
            for inode in nodeList:
                if node.row == inode.row and node.column == inode.column:
                    return inode
        return node

    def getPathNode(self, direction, row, col, nodeList):
        tempNode = self.followPath(direction, row, col)
        self.checkIfOnRestriction(tempNode)
        return self.getNodeFromNode(tempNode, nodeList)

    def findFirstNode(self, rows, cols):
        nodeFound = False
        for row in range(rows):
            for col in range(cols):
                if self.grid[row][col] in self.nodeSymbols:
                    return Node(row, col)
        return None

    def addNode(self, node, nodeList):
        nodeInList = self.nodeInList(node, nodeList)
        if not nodeInList:
            nodeList.append(node)

    def addNodeToStack(self, node, nodeList):
        if node is not None and not self.nodeInList(node, nodeList):
            self.nodeStack.push(node)

    def nodeInList(self, node, nodeList):
        for inode in nodeList:
            if (node.position.x == inode.position.x and 
                node.position.y == inode.position.y):
                return True
        return False

    def followPath(self, direction, row, col):
        if direction == LEFT and col >= 0:
            return self.pathToFollow(LEFT, row, col, "-")
        elif direction == RIGHT and col < self.grid.shape[1]:
            return self.pathToFollow(RIGHT, row, col, "-")
        elif direction == UP and row >= 0:
            return self.pathToFollow(UP, row, col, "|")
        elif direction == DOWN and row < self.grid.shape[0]:
            return self.pathToFollow(DOWN, row, col, "|")
        else:
            return None

    def pathToFollow(self, direction, row, col, path):
        if (self.grid[row][col] == path or
            self.grid[row][col] == "p" or
            self.grid[row][col] == "P" or
            self.grid[row][col] == "+"):
            while self.grid[row][col] not in self.nodeSymbols:
                if direction is LEFT: col -= 1
                elif direction is RIGHT: col += 1
                elif direction is UP: row -= 1
                elif direction is DOWN: row += 1
            self.updateMazeData(self.grid[row][col], row, col)
            return Node(row, col)
        else:
            return None

    def updateMazeData(self, symbol, row, col):
        if symbol == "M":
            MAZEDATA[self.level]["start"]["pacman"] = (col*WIDTH, row*HEIGHT)
        elif symbol == "H":
            MAZEDATA[self.level]["home"] = (col*WIDTH, row*HEIGHT)
        elif symbol == "F":
            MAZEDATA[self.level]["fruit"] = (col*WIDTH, row*HEIGHT)

    def setupPortalNodes(self):
        for pos1 in MAZEDATA[self.level]["portal"].keys():
            node1 = self.getNode(*pos1, nodeList=self.nodeList)
            node2 = self.getNode(*MAZEDATA[self.level]["portal"][pos1], 
                                 nodeList=self.nodeList)
            node1.portalNode = node2
            node2.portalNode = node1

    def moveHomeNodes(self):
        nodeA = self.getNode(*MAZEDATA[self.level]["home"],
                             nodeList=self.nodeList)
        nodeB = nodeA.neighbors[LEFT]

        mid = (nodeA.position + nodeB.position) / 2.0
        mid = Vector2D(int(mid.x), int(mid.y))
        vec = Vector2D(self.homeList[0].position.x,
                       self.homeList[0].position.y)
        for node in self.homeList:
            node.position -= vec
            node.position += mid

        nodeA.neighbors[LEFT] = self.homeList[0]
        nodeB.neighbors[RIGHT] = self.homeList[0]
        self.homeList[0].neighbors[RIGHT] = nodeA
        self.homeList[0].neighbors[LEFT] = nodeB
        self.homeList[0].home = True
        ghostHome = self.homeList[0].neighbors[DOWN]
        MAZEDATA[self.level]["start"]["ghost"] = ghostHome.position.toTuple()

    def checkIfOnRestriction(self, node):
        if node is not None:
            for tup in MAZEDATA[self.level]["restrictUp"].values():
                if node.position.x == tup[0] and node.position.y == tup[1]:
                    node.nowayUp = True
                    
    def setupTestNodes(self):
        nodeA = Node(5, 5)
        nodeB = Node(5, 10)
        nodeC = Node(10, 5)
        nodeD = Node(10, 10)
        nodeE = Node(10, 13)
        nodeF = Node(20, 5)
        nodeG = Node(20, 13)
        nodeA.neighbors[RIGHT] = nodeB
        nodeA.neighbors[DOWN] = nodeC
        nodeB.neighbors[LEFT] = nodeA
        nodeB.neighbors[DOWN] = nodeD
        nodeC.neighbors[UP] = nodeA
        nodeC.neighbors[RIGHT] = nodeD
        nodeC.neighbors[DOWN] = nodeF
        nodeD.neighbors[UP] = nodeB
        nodeD.neighbors[LEFT] = nodeC
        nodeD.neighbors[RIGHT] = nodeE
        nodeE.neighbors[LEFT] = nodeD
        nodeE.neighbors[DOWN] = nodeG
        nodeF.neighbors[UP] = nodeC
        nodeF.neighbors[RIGHT] = nodeG
        nodeG.neighbors[UP] = nodeE
        nodeG.neighbors[LEFT] = nodeF
        self.nodeList = [nodeA, nodeB, nodeC, nodeD, nodeE, nodeF, nodeG]

    def render(self, screen):
        for node in self.nodeList:
            node.render(screen)
        for node in self.homeList:
            node.render(screen)
Exemplo n.º 26
0
class NodeGroup(object):
    def __init__(self, width, height):
        self.nodeList = []
        self.width = width
        self.height = height
        self.grid = None
        self.nodeStack = Stack()
        self.fRows = 0
        self.fCols = 0

        # Creates nodelist

    def getBoardNodes(self, filename):
        self.grid = loadtxt(filename, dtype=str)
        self.fRows, self.fCols = self.grid.shape
        startNode = self.initNodes(self.fRows, self.fCols)
        self.nodeStack.push(startNode)
        while not self.nodeStack.isEmpty():
            node = self.nodeStack.pop()
            self.addNode(node)
            leftNode = self.folDirect(LEFT, node.row, node.col)
            rightNode = self.folDirect(RIGHT, node.row, node.col)
            upNode = self.folDirect(UP, node.row, node.col)
            downNode = self.folDirect(DOWN, node.row, node.col)
            leftNode = self.getNodeFromNode(leftNode)
            rightNode = self.getNodeFromNode(rightNode)
            upNode = self.getNodeFromNode(upNode)
            downNode = self.getNodeFromNode(downNode)
            node.neighbors[LEFT] = leftNode
            node.neighbors[RIGHT] = rightNode
            node.neighbors[UP] = upNode
            node.neighbors[DOWN] = downNode
            if leftNode is not None and not self.listedNodes(leftNode):
                self.nodeStack.push(leftNode)
            if rightNode is not None and not self.listedNodes(rightNode):
                self.nodeStack.push(rightNode)
            if upNode is not None and not self.listedNodes(upNode):
                self.nodeStack.push(upNode)
            if downNode is not None and not self.listedNodes(downNode):
                self.nodeStack.push(downNode)

    def getNode(self, row, col):
        for node in self.nodeList:
            if node.row == row and node.col == col:
                return node
        return None

    def getNodeFromNode(self, node):
        if node is not None:

            for inode in self.nodeList:
                if node.row == inode.row and node.col == inode.col:
                    return inode
        return node

    def initNodes(self, rows, cols):
        nodeFound = False
        for row in range(rows):
            for col in range(cols):
                if self.grid[row][col] == "+":
                    return Node(col, row, self.width, self.height)
        return None

    # Add node to list
    def addNode(self, node):
        nodeInList = self.listedNodes(node)
        if not nodeInList:
            self.nodeList.append(node)

    # Checks if node is already in list
    def listedNodes(self, node):
        for inode in self.nodeList:
            if node.row == inode.row and node.col == inode.col:
                return True
        return False

    def folDirect(self, direction, row, col):
        if direction == LEFT and col - 1 >= 0:
            if self.grid[row][col - 1] == "-" or self.grid[row][col - 1] == "+":
                while self.grid[row][col - 1] != "+":
                    col -= 1
                return Node(col - 1, row, self.width, self.height)
            else:
                return None
        elif direction == RIGHT and col + 1 < self.fCols:
            if self.grid[row][col + 1] == "-" or self.grid[row][col + 1] == "+":
                while self.grid[row][col + 1] != "+":
                    col += 1
                return Node(col + 1, row, self.width, self.height)
            else:
                return None
        elif direction == UP and row - 1 >= 0:
            if self.grid[row - 1][col] == "|" or self.grid[row - 1][col] == "+":
                while self.grid[row - 1][col] != "+":
                    row -= 1
                return Node(col, row - 1, self.width, self.height)
            else:
                return None
        elif direction == DOWN and row + 1 < self.fRows:
            if self.grid[row + 1][col] == "|" or self.grid[row + 1][col] == "+":
                while self.grid[row + 1][col] != "+":
                    row += 1
                return Node(col, row + 1, self.width, self.height)
            else:
                return None
        else:
            return None

    def render(self, screen):
        for node in self.nodeList:
            node.render(screen)