Commit 05c0bba8 authored by thomas.unsworth's avatar thomas.unsworth

Initial commit

parents
import pygame
#some colours to use
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 255, 0)
YELLOW = (255, 255, 0)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
PURPLE = (128, 0, 128)
ORANGE = (255, 165 ,0)
GREY = (128, 128, 128)
TURQUOISE = (64, 224, 208)
width = 400
window = pygame.display.set_mode((width, width))
class node:
def __init__(self, row, col, width, totalrows):
self.row = row
self.col = col
self.x = row * width
self.y = col * width
self.colour = WHITE
self.neighbors = []
self.width = width
self.totalrows = totalrows
self.value = 1000000
self.movesFromStart = 0
self.fromNode = self
def getPos(self):
return self.row, self.col
def isBarrier(self):
return self.colour == BLACK
def isWhiteOrPurple(self):
return self.colour == WHITE or self.colour == PURPLE
def makeWhite(self):
self.colour = WHITE
def makeClosed(self):
self.colour = RED
def makeOpen(self):
self.colour = GREEN
def makeStartNode(self):
self.colour = ORANGE
def makeGoal(self):
self.colour = PURPLE
def makeBarrier(self):
self.colour = BLACK
def makePath(self):
self.colour = TURQUOISE
def draw(self, win):
pygame.draw.rect(win, self.colour, (self.x, self.y, self.width, self.width))
def findNeighbors(self, grid):
self.neighbors = []
if(self.row < self.totalrows - 1 and not grid[self.row + 1][self.col].isBarrier() and grid[self.row + 1][self.col].isWhiteOrPurple()):# DOWN
self.neighbors.append(grid[self.row + 1][self.col])
if (self.row > 0 and not grid[self.row - 1][self.col].isBarrier() and grid[self.row - 1][self.col].isWhiteOrPurple()):# UP
self.neighbors.append(grid[self.row - 1][self.col])
if self.col < self.totalrows - 1 and not grid[self.row][self.col + 1].isBarrier() and grid[self.row][self.col + 1].isWhiteOrPurple(): # RIGHT
self.neighbors.append(grid[self.row][self.col + 1])
if self.col > 0 and not grid[self.row][self.col - 1].isBarrier() and grid[self.row][self.col - 1].isWhiteOrPurple(): # LEFT
self.neighbors.append(grid[self.row][self.col - 1])
def __lt__(self, other):
return False
def makeGrid(rows, width):
grid = []
gap = width / rows
for i in range(rows):
grid.append([])
for j in range(rows):
anode = node(i,j,gap,rows)
grid[i].append(anode)
return grid
#this makes a list of 10 lists which have each node in them
def Draw_grid(win, rows, width):
gap = width // rows
for i in range(rows):
pygame.draw.line(win,GREY,(0, i * gap), (width, i * gap))
for j in range(rows):
pygame.draw.line(win,GREY, (j * gap, 0), (j * gap, width))
def draw(win, grid, rows, width):
win.fill(WHITE)
for row in grid:
for node in row:
node.draw(win)
Draw_grid(win, rows, width)
pygame.display.update()
def findNodeFromMouse(x,y, rows):
gap = width // rows
row = y // gap
col = x // gap
return row,col
def any(item, list1, list2):
for element in list1:
if item == element:
return True
for el in list2:
if item == el:
return True
return False
def AStarAlgorithm(grid, startNode, endNode):
openNodes = []
closedNodes = []
moves = 0
lowestValueNode = startNode
openNodes.append(startNode)
closedNodes.append(endNode)
numberOfMoves = 40
startNode.makeStartNode()
while not(len(openNodes) == 0):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
openNodes[0].findNeighbors(grid)
closedNodes.append(openNodes[0])
for anode in openNodes[0].neighbors:
anode.fromNode = openNodes[0]
anode.movesFromStart = openNodes[0].movesFromStart + 20
pygame.time.wait(400)
anode.value = (workoutNodeValue(anode, endNode, numberOfMoves) + anode.movesFromStart)
if not any(anode, openNodes, closedNodes):
#DONT add
openNodes.append(anode)
anode.makeOpen()
draw(window, grid, 10, 400)
if anode == endNode:
#retrun the path
returnPath(anode, startNode, grid)
pygame.time.wait(4000)
# reset grid
for a in openNodes:
a.makeWhite()
for b in closedNodes:
b.makeWhite()
draw(window, grid, 10, 400)
pygame.display.update()
print(anode.movesFromStart)
return
openNodes[0].makeClosed()
closedNodes.append(openNodes[0])
openNodes.pop(0)
openNodes.sort(key = lambda x:x.value, reverse=False)
def returnPath(node, startNode, grid):
while(node != startNode):
node = node.fromNode
node.makePath()
draw(window, grid, 10, 400)
pygame.time.wait(600)
def workoutNodeValue(snode, gnode, numberOfMoves):
manhattan = abs(snode.x - gnode.x) + abs(snode.y - gnode.y) + numberOfMoves
return manhattan
def main(win, width):
ROWS = 10
start = False
goal = False
go = False
run = True
goalNodesList = []
grid = makeGrid(ROWS, width)
win.fill(WHITE)
Draw_grid(win, ROWS, width)
pygame.display.update()
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if pygame.mouse.get_pressed()[0]:
pos = pygame.mouse.get_pos()
pos2, pos1 = event.pos
row, col = findNodeFromMouse(pos1,pos2,ROWS)
anode = grid[row][col]
if(start == False):
anode.makeStartNode()
startNode = anode
draw(win, grid, ROWS, width)
start = True
elif(goal==False):
anode.makeGoal()
goalNodesList.append(anode)
endNode = anode
draw(win, grid, ROWS, width)
goal = True
elif(goal == True):
goalNodesList.append(anode)
anode.makeGoal()
draw(win, grid, ROWS, width)
if pygame.mouse.get_pressed()[2]:
pos = pygame.mouse.get_pos()
pos2, pos1 = event.pos
row, col = findNodeFromMouse(pos1,pos2,ROWS)
anode = grid[row][col]
anode.makeBarrier()
draw(win, grid, ROWS, width)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
go = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
defaultGrid = grid
if(goal == True and start == True and go == True):
#if start and end nodes are selected you may start the path finding algrithm
for i in goalNodesList:
startNode.makeStartNode()
AStarAlgorithm(grid, startNode, i)
for j in goalNodesList:
j.makeGoal()
draw(win, grid, ROWS, width)
pygame.display.update()
# sorts list by the length of the path
goalNodesList.sort(key = lambda x:x.movesFromStart, reverse=False)
AStarAlgorithm(grid, startNode, goalNodesList[0]) #prints the final path
run = False
pygame.display.update()
pygame.quit()
main(window, width)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment