Python 之 使用Tkinter 做GUI 研究机器人走迷宫

这本是课程的一个作业研究搜索算法,当时研究了一下Tkinter,然后写了个很简单的机器人走迷宫的界面,并且使用了各种搜索算法来进行搜索,如下图:

使用A*寻找最优路径:

由于时间关系,不分析了,我自己贴代码吧。希望对一些也要用Tkinter的人有帮助。

from Tkinter import *
from random import *
import time
import numpy as np
import util

class Directions:
    NORTH = ‘North‘
    SOUTH = ‘South‘
    EAST = ‘East‘
    WEST = ‘West‘

# Detect elements in the map

window = Tk()
window.title(‘CityBusPlanner‘)
window.resizable(0,0)
width = 25
(x, y) = (22, 22)

totalsteps = 0

buidings = [(0, 0), (1, 0), (2, 0), (3, 0), (7, 0), (8, 0), (11, 0), (12, 0), (13, 0),
            (17, 0), (18, 0), (21, 0), (21, 1), (2, 2), (5, 2), (8, 2), (9, 2), (12, 2),
            (14, 2), (15, 2), (16, 2), (17, 2), (21, 2), (2, 3), (4, 3), (5, 3), (7, 3),
            (8, 3), (11, 3), (17, 3), (18, 3), (19, 3), (2, 4), (4, 4), (5, 4), (8, 4),
            (9, 4), (14, 4), (15, 4),(17, 4), (18, 4), (19, 4), (0, 6), (2, 6), (4, 6),
            (7, 6), (8, 6), (11, 6), (12, 6), (14, 6), (15, 6),(16, 6), (18, 6), (19, 6),
            (2, 7), (5, 7), (21, 7), (0, 8), (2, 8), (11, 8), (14, 8), (15, 8), (17, 8),
            (18, 8), (21, 8), (4, 9), (5, 9), (7, 9), (9, 9), (11, 9), (14, 9), (21, 9),
            (2, 10), (7, 10), (14, 10), (17, 10), (19, 10), (0, 11), (2, 11), (4, 11),
            (5, 11), (7, 11), (8, 11), (9, 11), (11, 11), (12, 11), (14, 11), (15, 11),
            (16, 11), (17, 11), (18, 11), (19, 11), (0, 13), (2, 13), (3, 13), (5, 13),
            (7, 13), (8, 13), (9, 13), (14, 13), (17, 13), (18, 13), (21, 13), (2, 14),
            (3, 14), (5, 14), (7, 14),(9, 14), (12, 14), (14, 14), (15, 14), (17, 14),
            (18, 14), (21, 14), (2, 15), (3, 15), (5, 15), (7, 15), (9, 15), (12, 15),
            (15, 15), (19, 15), (21, 15), (0, 16), (21, 16), (0, 17), (3, 17), (5, 17),
            (7, 17),(9, 17), (11, 17), (14, 17), (15, 17), (17, 17), (18, 17), (21, 17),
            (2, 18), (3, 18), (5, 18), (7, 18),(9, 18), (11, 18), (14, 18), (17, 18),
            (18, 18), (3, 19), (5, 19), (7, 19), (9, 19), (11, 19), (12, 19), (14, 19),
            (17, 19), (18, 19), (0, 21), (1, 21), (2, 21), (5, 21), (6, 21), (9, 21),
            (10, 21), (11, 21), (12, 21), (15, 21), (16, 21), (18, 21), (19, 21), (21, 21)]

walls = [(10, 0), (0, 12), (21, 12), (14, 21)]
park = [(14, 0), (15, 0), (16, 0)]
robotPos = (21, 12)

view = Canvas(window, width=x * width, height=y * width)
view.grid(row=0, column=0)
searchMapButton = Button(window,text = ‘search‘)
searchMapButton.grid(row = 0,column = 1)
robotView = Canvas(window,width=x * width, height=y * width)
robotView.grid(row = 0,column = 2)

def formatColor(r, g, b):
    return ‘#%02x%02x%02x‘ % (int(r * 255), int(g * 255), int(b * 255))

def cityMap():
    global width, x, y, buidings,walls,park,robot
    for i in range(x):
        for j in range(y):
            view.create_rectangle(
                i * width, j * width, (i + 1) * width, (j + 1) * width, fill=‘white‘, outline=‘gray‘, width=1)
    for (i, j) in buidings:
        view.create_rectangle(
            i * width, j * width, (i + 1) * width, (j + 1) * width, fill=‘black‘, outline=‘gray‘, width=1)
    for (i,j) in walls:
        view.create_rectangle(
            i * width, j * width, (i + 1) * width, (j + 1) * width, fill=‘blue‘, outline=‘gray‘, width=1)
    for (i,j) in park:
        view.create_rectangle(
            i * width, j * width, (i + 1) * width, (j + 1) * width, fill=‘red‘, outline=‘gray‘, width=1)

def robotCityMap():
    global width, x, y, buidings,walls,park,robot,robotPos
    for i in range(x):
        for j in range(y):
            robotView.create_rectangle(
                i * width, j * width, (i + 1) * width, (j + 1) * width, fill=‘black‘, width=1)
    robotView.create_rectangle(
                robotPos[0] * width, robotPos[1] * width, (robotPos[0] + 1) * width, (robotPos[1] + 1) * width, fill=‘white‘, outline=‘gray‘, width=1)
# Create City Map
cityMap()

# Create Robot View
robotCityMap()
# Create a robot
robot = view.create_rectangle(robotPos[0] * width + width * 2 / 10, robotPos[1] * width + width * 2 / 10,
                            robotPos[0] * width + width * 8 / 10, robotPos[1] * width + width * 8 / 10, fill="orange", width=1, tag="robot")
robotSelf = robotView.create_rectangle(robotPos[0] * width + width * 2 / 10, robotPos[1] * width + width * 2 / 10,
                            robotPos[0] * width + width * 8 / 10, robotPos[1] * width + width * 8 / 10, fill="orange", width=1, tag="robot")

visited = [robotPos]

def move(dx,dy):
    global robot,x,y,robotPos,robotSelf,view
    global totalsteps
    totalsteps = totalsteps + 1
    newX = robotPos[0] + dx
    newY = robotPos[1] + dy
    if (not isEdge(newX, newY)) and (not isBlock(newX, newY)):
        #print "move %d" % totalsteps
        view.coords(robot, (newX) * width + width * 2 / 10, (newY) * width + width * 2 / 10,
                     (newX) * width + width * 8 / 10, (newY) * width + width * 8 / 10)
        robotView.coords(robotSelf, (newX) * width + width * 2 / 10, (newY) * width + width * 2 / 10,
                     (newX) * width + width * 8 / 10, (newY) * width + width * 8 / 10)
        robotPos = (newX, newY)
        if robotPos not in visited:
            visited.append(robotPos)
            visitedPanel = robotView.create_rectangle(
                robotPos[0] * width, robotPos[1] * width, (robotPos[0] + 1) * width, (robotPos[1] + 1) * width, fill=‘white‘, outline=‘gray‘, width=1)
            robotView.tag_lower(visitedPanel,robotSelf)
    else:
        print "move error"

def callUp(event):
    move(0,-1)

def callDown(event):
    move(0, 1)

def callLeft(event):
    move(-1, 0)

def callRight(event):
    move(1, 0)

def isBlock(newX,newY):
    global buidings,x,y

    for (i,j) in buidings:
        if (i == newX) and (j == newY):
            return True
    return False

def isEdge(newX,newY):
    global x,y

    if newX >= x or newY >= y or newX < 0 or newY < 0 :
        return True
    return False

def getSuccessors(robotPos):
    n = Directions.NORTH
    w = Directions.WEST
    s = Directions.SOUTH
    e = Directions.EAST
    successors = []
    posX = robotPos[0]
    posY = robotPos[1]

    if not isBlock(posX - 1, posY) and not isEdge(posX - 1,posY):
        successors.append(w)
    if not isBlock(posX, posY + 1) and not isEdge(posX,posY + 1):
        successors.append(s)
    if not isBlock(posX + 1, posY) and not isEdge(posX + 1,posY):
        successors.append(e)
    if not isBlock(posX, posY -1) and not isEdge(posX,posY - 1):
        successors.append(n)

    return successors

def getNewPostion(position,action):
    posX = position[0]
    posY = position[1]
    n = Directions.NORTH
    w = Directions.WEST
    s = Directions.SOUTH
    e = Directions.EAST
    if action == n:
        return (posX,posY - 1)
    elif action == w:
        return (posX - 1,posY)
    elif action == s:
        return (posX,posY + 1)
    elif action == e:
        return (posX + 1,posY)

delay = False
def runAction(actions):
    global delay
    n = Directions.NORTH
    w = Directions.WEST
    s = Directions.SOUTH
    e = Directions.EAST
    for i in actions:
        if delay:
            time.sleep(0.05)
        if i == n:
            #print "North"
            move(0, -1)
        elif i == w:
            #print "West"
            move(-1, 0)
        elif i == s:
            #print "South"
            move(0, 1)
        elif i == e:
            #sprint "East"
            move(1, 0)
        view.update()

def searchMapTest(event):
    global robotPos
    actions = []
    position = robotPos
    for i in range(100):
        successors = getSuccessors(position)
        successor = successors[randint(0, len(successors) - 1)]
        actions.append(successor)
        position = getNewPostion(position, successor)
    print actions
    runAction(actions)

def reverseSuccessor(successor):
    n = Directions.NORTH
    w = Directions.WEST
    s = Directions.SOUTH
    e = Directions.EAST
    if successor == n:
        return s
    elif successor == w:
        return e
    elif successor == s:
        return n
    elif successor == e:
        return w

roads = set()

detectedBuildings = {}
blockColors = {}
blockIndex = 0

def updateBuildings(detectedBuildings):
    global robotView,width
    for block,buildings in detectedBuildings.items():
        color = blockColors[block]
        for building in buildings:
            robotView.create_rectangle(
                building[0] * width, building[1] * width, (building[0] + 1) * width, (building[1] + 1) * width, fill=color, outline=color, width=1)

def addBuilding(position):
    global blockIndex,detectedBuildings
    isAdd = False
    addBlock = ‘‘
    for block,buildings in detectedBuildings.items():
        for building in buildings:
            if building == position:
                return
            if util.manhattanDistance(position, building) == 1:
                if not isAdd:
                    buildings.add(position)
                    isAdd = True
                    addBlock = block
                    break
                else:
                    #merge two block
                    for building in detectedBuildings[block]:
                        detectedBuildings[addBlock].add(building)
                    detectedBuildings.pop(block)

    if not isAdd:
        newBlock = set([position])
        blockIndex = blockIndex + 1
        detectedBuildings[‘Block %d‘ % blockIndex] = newBlock
        color = formatColor(random(), random(), random())
        blockColors[‘Block %d‘ % blockIndex] = color
    updateBuildings(detectedBuildings)

def addRoad(position):
    global robotView,width,robotSelf
    visitedPanel = robotView.create_rectangle(
                position[0] * width, position[1] * width, (position[0] + 1) * width, (position[1] + 1) * width, fill=‘white‘, outline=‘gray‘, width=1)
    robotView.tag_lower(visitedPanel,robotSelf)

def showPath(positionA,positionB,path):
    global robotView,width,view
    view.create_oval(positionA[0] * width + width * 3 / 10, positionA[1] * width + width * 3 / 10,
                       positionA[0] * width + width * 7 / 10, positionA[1] * width + width * 7 / 10, fill=‘yellow‘, width=1)
    nextPosition = positionA
    for action in path:
        nextPosition = getNewPostion(nextPosition, action)
        view.create_oval(nextPosition[0] * width + width * 4 / 10, nextPosition[1] * width + width * 4 / 10,
                       nextPosition[0] * width + width * 6 / 10, nextPosition[1] * width + width * 6 / 10, fill=‘yellow‘, width=1)
    view.create_oval(positionB[0] * width + width * 3 / 10, positionB[1] * width + width * 3 / 10,
                       positionB[0] * width + width * 7 / 10, positionB[1] * width + width * 7 / 10, fill=‘yellow‘, width=1)
hasDetected = set()

def detectLocation(position):
    if position not in hasDetected:
        hasDetected.add(position)
        if isBlock(position[0],position[1]):
            addBuilding(position)
        elif not isEdge(position[0],position[1]):
            addRoad(position)

def detect(position):
    posX = position[0]
    posY = position[1]

    detectLocation((posX,posY + 1))
    detectLocation((posX,posY - 1))
    detectLocation((posX + 1,posY))
    detectLocation((posX - 1,posY))

def heuristic(positionA,positionB):
    return util.manhattanDistance(positionA,positionB)

def AstarSearch(positionA,positionB):
    "Step 1: define closed: a set"
    closed = set()
    "Step 2: define fringe: a PriorityQueue "
    fringe = util.PriorityQueue()
    "Step 3: insert initial node to fringe"
    "Construct node to be a tuple (location,actions)"
    initialNode = (positionA,[])
    initCost = 0 + heuristic(initialNode[0],positionB)
    fringe.push(initialNode,initCost)
    "Step 4: Loop to do search"
    while not fringe.isEmpty():
        node = fringe.pop()
        if node[0] == positionB:
            return node[1]
        if node[0] not in closed:
            closed.add(node[0])
            for successor in getSuccessors(node[0]):
                actions = list(node[1])
                actions.append(successor)
                newPosition = getNewPostion(node[0], successor)
                childNode = (newPosition,actions)
                cost = len(actions) + heuristic(childNode[0],positionB)
                fringe.push(childNode,cost)
    return []

def AstarSearchBetweenbuildings(building1,building2):
    "Step 1: define closed: a set"
    closed = set()
    "Step 2: define fringe: a PriorityQueue "
    fringe = util.PriorityQueue()
    "Step 3: insert initial node to fringe"
    "Construct node to be a tuple (location,actions)"
    initialNode = (building1,[])
    initCost = 0 + heuristic(initialNode[0],building2)
    fringe.push(initialNode,initCost)
    "Step 4: Loop to do search"
    while not fringe.isEmpty():
        node = fringe.pop()
        if util.manhattanDistance(node[0],building2) == 1:
            return node[1]
        if node[0] not in closed:
            closed.add(node[0])
            for successor in getSuccessors(node[0]):
                actions = list(node[1])
                actions.append(successor)
                newPosition = getNewPostion(node[0], successor)
                childNode = (newPosition,actions)
                cost = len(actions) + heuristic(childNode[0],building2)
                fringe.push(childNode,cost)
    return []

def calculatePositions(buildingA,path):
    positions = set()
    positions.add(buildingA)
    nextPosition = buildingA
    for action in path:
        nextPosition = getNewPostion(nextPosition, action)
        positions.add(nextPosition)
    return positions

def showRoad(fullRoad):
    global view,width
    for road in fullRoad:
        view.create_oval(road[0] * width + width * 4 / 10, road[1] * width + width * 4 / 10,
                       road[0] * width + width * 6 / 10, road[1] * width + width * 6 / 10, fill=‘yellow‘, width=1)
    view.update()

def search(node):
    successors = getSuccessors(node[0])
    detect(node[0])
    for successor in successors:
        nextPosition = getNewPostion(node[0], successor)
        if nextPosition not in roads:
            runAction([successor]) # to the next node
            roads.add(nextPosition)
            search((nextPosition,[successor],[reverseSuccessor(successor)]))
    runAction(node[2]) #back to top node

def searchConsiderTopVisit(node,topWillVisit):
    successors = getSuccessors(node[0])
    detect(node[0])
    newTopWillVisit = set(topWillVisit)
    for successor in successors:
        nextPosition = getNewPostion(node[0], successor)
        newTopWillVisit.add(nextPosition)
    for successor in successors:
        nextPosition = getNewPostion(node[0], successor)
        if nextPosition not in roads and nextPosition not in topWillVisit:
            runAction([successor]) # to the next node
            roads.add(nextPosition)
            newTopWillVisit.remove(nextPosition)
            searchConsiderTopVisit((nextPosition,[successor],[reverseSuccessor(successor)]),newTopWillVisit)
    runAction(node[2]) #back to top node

def searchShortestPathBetweenBlocks(block1,block2):
    shortestPath = []
    buildingA = (0,0)
    buildingB = (0,0)
    for building1 in block1:
        for building2 in block2:
            path = AstarSearchBetweenbuildings(building1, building2)
            if len(shortestPath) == 0:
                shortestPath = path
                buildingA = building1
                buildingB = building2
            elif len(path) < len(shortestPath):
                shortestPath = path
                buildingA = building1
                buildingB = building2
    return (buildingA,buildingB,shortestPath)

def addBuildingToBlocks(linkedBlock,buildingA):
    global detectedBuildings
    newLinkedBlock = linkedBlock.copy()
    for block,buildings in detectedBuildings.items():
        for building in buildings:
            if util.manhattanDistance(buildingA, building) == 1:
                    newLinkedBlock[block] = buildings
                    break
    return newLinkedBlock

def bfsSearchNextBlock(initBuilding,linkedBlock):
    global detectedBuildings
    closed = set()
    fringe = util.Queue()
    initNode = (initBuilding,[])
    fringe.push(initNode)
    while not fringe.isEmpty():
        node = fringe.pop()
        newLinkedBlock = addBuildingToBlocks(linkedBlock,node[0])
        if len(newLinkedBlock) == len(detectedBuildings):
            return node[1]
        if len(newLinkedBlock) > len(linkedBlock): # find a new block
            actions = list(node[1])
            ‘‘‘
            if len(node[1]) > 0:
                lastAction = node[1][len(node[1]) - 1]
                for successor in getSuccessors(node[0]):
                    if successor == lastAction:
                        nextPosition = getNewPostion(node[0], successor)
                        actions.append(successor)
                        return actions + bfsSearchNextBlock(nextPosition, newLinkedBlock)
            ‘‘‘
            return node[1] + bfsSearchNextBlock(node[0], newLinkedBlock)

        if node[0] not in closed:
            closed.add(node[0])
            for successor in getSuccessors(node[0]):
                actions = list(node[1])
                actions.append(successor)
                nextPosition = getNewPostion(node[0], successor)

                childNode = (nextPosition,actions)
                fringe.push(childNode)
    return []

def isGoal(node):
    global detectedBuildings,robotPos
    linkedBlock = {}
    positions = calculatePositions(robotPos, node[1])
    for position in positions:
        for block,buildings in detectedBuildings.items():
            for building in buildings:
                 if util.manhattanDistance(position, building) == 1:
                    linkedBlock[block] = buildings
    print len(linkedBlock)
    if len(linkedBlock) == 17:
        return True
    else:
        return False

def roadHeuristic(road):
    return 0

def AstarSearchRoad():
    global robotPos,detectedBuildings
    "Step 1: define closed: a set"
    closed = set()
    "Step 2: define fringe: a PriorityQueue "
    fringe = util.PriorityQueue()
    "Step 3: insert initial node to fringe"
    "Construct node to be a tuple (location,actions)"
    initRoad = (robotPos,[])
    initCost = 0 + roadHeuristic(initRoad)
    fringe.push(initRoad,initCost)
    "Step 4: Loop to do search"
    while not fringe.isEmpty():
        node = fringe.pop()
        if isGoal(node):
            print len(closed)
            return node[1]
        if node[0] not in closed:
            closed.add(node[0])
            for successor in getSuccessors(node[0]):
                actions = list(node[1])
                actions.append(successor)
                newPosition = getNewPostion(node[0], successor)
                childNode = (newPosition,actions)
                cost = len(actions) + roadHeuristic(childNode)
                fringe.push(childNode,cost)

    return []

def searchRoad(building):
    global detectedBuildings,robotPos
    linkedBlock = {}
    initBuilding = building

    return bfsSearchNextBlock(initBuilding,linkedBlock)

def searchShortestRoad():
    shortestRoad = []
    shortestPositions = set()
    for block,buildings in detectedBuildings.items():
        for building in buildings:
            road = searchRoad(building)
            positions = calculatePositions(building, road)
            if len(shortestPositions) == 0 or len(positions) < len(shortestPositions):
                shortestRoad = road
                shortestPositions = positions
    print len(shortestPositions)
    showRoad(shortestPositions)

def searchMap(event):
    print "Search Map"
    global robotPos,roads,detectedBuildings,delay
    actions = []
    #roads = set()s
    #roads.add(robotPos)
    #fringe = util.Stack()
    initNode = (robotPos,[],[])  # (position,forwardActions,backwarsdActions)
    #fringe.push(initNode)
    roads.add(robotPos)
    search(initNode)
    #searchConsiderTopVisit(initNode, set())
    print detectedBuildings
    print len(detectedBuildings)
    #path = AstarSearchBetweenbuildings((6,21), (2, 18))
    #showPath((6,21),(2,18), path)
    ‘‘‘
    shortestRoad = set()
    for block1 in detectedBuildings.values():
        roads = set()
        for block2 in detectedBuildings.values():
            if not block1 == block2:
                (buildingA,buildingB,path) = searchShortestPathBetweenBlocks(block1, block2)
                #showPath(buildingA,buildingB,path)
                positions = calculatePositions(buildingA,buildingB,path)
                roads = roads | positions
        if len(shortestRoad) == 0 or len(roads) < len(shortestRoad):
            shortestRoad = roads
        print len(shortestRoad)
    showRoad(shortestRoad)
    ‘‘‘
    ‘‘‘
    block1 = detectedBuildings.values()[3]
    print block1
    block2 = detectedBuildings.values()[5]
    print block2
    (buildingA,buildingB,path) = searchShortestPathBetweenBlocks(block1, block2)
    print buildingA,buildingB,path
    showPath(buildingA,buildingB,path)

    block1 = detectedBuildings.values()[10]
    print block1
    block2 = detectedBuildings.values()[20]
    print block2
    (buildingA,buildingB,path) = searchShortestPathBetweenBlocks(block1, block2)
    print buildingA,buildingB,path
    showPath(buildingA,buildingB,path)
    ‘‘‘
    searchShortestRoad()

    ‘‘‘
    path = searchRoad()
    #path = AstarSearchRoad()
    positions = calculatePositions(robotPos, path)
    print len(positions)
    showRoad(positions)
    delay = True
    #runAction(path)
    ‘‘‘

window.bind("<Up>", callUp)
window.bind("<Down>", callDown)
window.bind("<Right>", callRight)
window.bind("<Left>", callLeft)
window.bind("s", searchMap)
searchMapButton.bind("<Button-1>",searchMap)
window.mainloop()

下面的util.py使用的是加州伯克利的代码:

# util.py
# -------
# Licensing Information:  You are free to use or extend these projects for
# educational purposes provided that (1) you do not distribute or publish
# solutions, (2) you retain this notice, and (3) you provide clear
# attribution to UC Berkeley, including a link to http://ai.berkeley.edu.
#
# Attribution Information: The Pacman AI projects were developed at UC Berkeley.
# The core projects and autograders were primarily created by John DeNero
# ([email protected]) and Dan Klein ([email protected]).
# Student side autograding was added by Brad Miller, Nick Hay, and
# Pieter Abbeel ([email protected]).

import sys
import inspect
import heapq, random

"""
 Data structures useful for implementing SearchAgents
"""

class Stack:
    "A container with a last-in-first-out (LIFO) queuing policy."
    def __init__(self):
        self.list = []

    def push(self,item):
        "Push ‘item‘ onto the stack"
        self.list.append(item)

    def pop(self):
        "Pop the most recently pushed item from the stack"
        return self.list.pop()

    def isEmpty(self):
        "Returns true if the stack is empty"
        return len(self.list) == 0

class Queue:
    "A container with a first-in-first-out (FIFO) queuing policy."
    def __init__(self):
        self.list = []

    def push(self,item):
        "Enqueue the ‘item‘ into the queue"
        self.list.insert(0,item)

    def pop(self):
        """
          Dequeue the earliest enqueued item still in the queue. This
          operation removes the item from the queue.
        """
        return self.list.pop()

    def isEmpty(self):
        "Returns true if the queue is empty"
        return len(self.list) == 0

class PriorityQueue:
    """
      Implements a priority queue data structure. Each inserted item
      has a priority associated with it and the client is usually interested
      in quick retrieval of the lowest-priority item in the queue. This
      data structure allows O(1) access to the lowest-priority item.

      Note that this PriorityQueue does not allow you to change the priority
      of an item.  However, you may insert the same item multiple times with
      different priorities.
    """
    def  __init__(self):
        self.heap = []
        self.count = 0

    def push(self, item, priority):
        # FIXME: restored old behaviour to check against old results better
        # FIXED: restored to stable behaviour
        entry = (priority, self.count, item)
        # entry = (priority, item)
        heapq.heappush(self.heap, entry)
        self.count += 1

    def pop(self):
        (_, _, item) = heapq.heappop(self.heap)
        #  (_, item) = heapq.heappop(self.heap)
        return item

    def isEmpty(self):
        return len(self.heap) == 0

class PriorityQueueWithFunction(PriorityQueue):
    """
    Implements a priority queue with the same push/pop signature of the
    Queue and the Stack classes. This is designed for drop-in replacement for
    those two classes. The caller has to provide a priority function, which
    extracts each item‘s priority.
    """
    def  __init__(self, priorityFunction):
        "priorityFunction (item) -> priority"
        self.priorityFunction = priorityFunction      # store the priority function
        PriorityQueue.__init__(self)        # super-class initializer

    def push(self, item):
        "Adds an item to the queue with priority from the priority function"
        PriorityQueue.push(self, item, self.priorityFunction(item))

def manhattanDistance( xy1, xy2 ):
    "Returns the Manhattan distance between points xy1 and xy2"
    return abs( xy1[0] - xy2[0] ) + abs( xy1[1] - xy2[1] )

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 00:08:05

Python 之 使用Tkinter 做GUI 研究机器人走迷宫的相关文章

1021: 机器人走迷宫(2017年中南大学研究生复试机试题 )

1021: 机器人走迷宫 时间限制: 1 Sec  内存限制: 128 MB提交: 339  解决: 71[提交] [状态] [讨论版] [命题人:外部导入] 题目描述 有一个愚蠢的机器人走进一个w*h的迷宫,迷宫里有空地和陷阱.他想要访问迷宫的每个方格,但是它很笨,只会按照指令的方向走.当机器人不能走的时候,也就是下一步会遇到陷阱.迷宫边界或者访问过的格子,它会向右转90度(顺时针旋转90度,不能访问已经访问过的方格,且在原地只转一次,移动后可获得又一次旋转机会).请问这个机器人最多可以经过多

python中使用pyqt做GUI小试牛刀

import sys from PyQt4 import QtGui , QtCore class LIN(QtGui.QMainWindow): def _init_(self): QtGui.QMainWindoW._init_(self) self.setWindowTitle('lin') self.resize(300,300) app=QtGui.QApplication(sys.argv) mywindow=LIN() mywindow.show() app.exec_()

(动态规划)机器人走迷宫问题

题目一:https://www.nowcoder.com/practice/166eaff8439d4cd898e3ba933fbc6358?tpId=46&tqId=29117&tPage=1&rp=1&ru=/ta/leetcode&qru=/ta/leetcode/question-ranking 题目翻译: 机器人位于m x n网格的左上角(在下图中标记为"开始"). 机器人只能在任何时间点向下或向右移动. 机器人试图到达网格的右下角(在

python 3.6 tkinter+urllib+json 火车车次信息查询

--------blogs:  陈月白    http://www.cnblogs.com/chenyuebai    -------- 一.概述 妹子工作时需要大量地查询火车车次至南京的信息,包括该车次到达站(南京站or南京南站).到达时间.出发时间等,然后根据这些信息做下一步工作. 版本结束,趁着间歇期,帮她弄了个简易的批量查询工具,粉色的按钮是给她用的~哈哈哈! (?*?*?) 大概80行代码,主要是: 界面读取待查询车次 - - - - 调用车次信息接口- - - - 解析返回数据 -

用Python自动办公,做职场高手(完结)

教程目录: ┣━07.S2 Word自动化处理,又快又好做文档┃  ┣━36 本章介绍┣━08.[Word]S2-1 轻松用Python快速生成Word文档┃  ┣━45.[真实案例]S2-1-3 批量生成50份不同乙方的合同┃  ┣━38.[视频讲解]S2-1-1 用Python套用Word模版,再也不做重复工作┃  ┃  ┣━[视频讲解]S2-1-1 用Python套用Word模版,再也不做重复工作┃  ┣━42.[视频讲解]S2-1-2 用Python给Word添加图片和表格,神操作┃  

Python字符串的encode与decode研究心得——解决乱码问题

转~Python字符串的encode与decode研究心得——解决乱码问题 为什么Python使用过程中会出现各式各样的乱码问题,明明是中文字符却显示成“/xe4/xb8/xad/xe6/x96/x87”的形式?为什么会报错“UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)”?本文就来研究一下这个问题. 字符串在Python内部的表示是unico

python 中对list做减法操作

问题描述:假设我有这样两个list,          一个是list1,list1 = [1, 2, 3, 4, 5]          一个是list2,list2 = [1, 4, 5]           我们如何得到一个新的list,list3,          list3中包括所有不在list2中出现的list1中的元素.          即:list3 = list1 - list2          解决方案:我们可以用set(集合)操作          list3 = l

python主要用来做什么

python这门编程语言在国外极受欢迎,但在国内使用还不是极普遍. 由于python编程效率极高,现在国内的使用者也开始变得越来越多. python主要用来做什么?这个语言到底有哪些作用呢? 下面主是它的应用大全: 系统编程:提供API,能方便进行系统维护和管理,Linux下标志性语言之一,是很多系统管理员理想的编程工具,这也是国外为什么使用者这么多的原因,我们国内很少使用Linux. 图形处理:有PIL.Tkinter等图形库支持,能方便进行图形处理. 数学处理:NumPy扩展提供大量与许多标

python常用的几种GUI解析

在Python中,开始使用GUI编程的步骤并不复杂,但是它们要求用户开始做出一些选择.作为通用编程语言,每个常见操作系统都有可用的解释器,所以创建图形用户界面对于Python来说并不是难事.程序员可以有很多的选择,真正困难的是如何为用户创建一个简单的方式来与程序互动.在python中有几种常用的GUI,我们来解析下.1.Tkinter 如果有一个包可以被称为"Python的标准GUI工具包",那么它一定就是Tkinter.Tkinter是Tcl / Tk的封装,是90年代初推出的流行图