Skip to content
Snippets Groups Projects
Commit 81ca76be authored by Sean Paeglis's avatar Sean Paeglis
Browse files

update3

parent 87d88a28
Branches
No related tags found
No related merge requests found
class Block:
def __init__(self, pos):
self.pos = pos
self.visited = []
import Tile
class Board:
# List of exit tiles. Only red at the moment
exit_tiles = [(3,-3), (3,-2), (3,-1), (3,0)]
"""
directions = ['l', 'tl', 'tr', 'r', 'br', 'bl']
moves = {'l':(-1,0), 'tl':(0,-1), 'tr':(1,-1), 'r':(1,0),
'br':(0,1), 'bl':(-1,1)}
"""
# List of move directions
moves = [(-1,0), (0,-1), (1,-1), (1,0), (0,1), (-1,1)]
def __init__(self):
# Create board state array
# None means an empty tile and 0 means a tile not on the board
self.tiles = [[None for i in range(7)] for j in range(7)]
self.tiles[0][0] = 0
self.tiles[0][1] = 0
......@@ -26,9 +31,12 @@ class Board:
self.f = 0
self.parent = None
# Returns a list of valid moves for this board state in the form: ((pos_from),(pos_to))
def getMoves(self):
valid_moves = []
for piece in self.pieces:
# If the piece is on an exit tile, return that piece
if piece.pos in self.exit_tiles:
return piece
p_r = piece.pos[1]+3
......@@ -46,12 +54,14 @@ class Board:
return valid_moves
# Moves a pice from one position to another
def move(self, t_from, t_to):
piece = self.tiles[t_from[1]+3][t_from[0]+3]
self.tiles[t_from[1]+3][t_from[0]+3] = None
self.tiles[t_to[1]+3][t_to[0]+3] = piece
self.tiles[t_to[1]+3][t_to[0]+3].pos = t_to
# Calculate the distance from one position to another
def distance(self, start, end):
q1 = start[0]
q2 = end[0]
......
......@@ -10,8 +10,12 @@ exit_tiles = {'red':[(3,-3),(3,-2),(3,-1),(3,0)]}
def main():
with open(sys.argv[1]) as file:
# Load initial board state
data = json.load(file)
bdict = {}
# Add pieces and blocks to the board
for p in data['pieces']:
piece = Piece.Piece(tuple(p), data['colour'])
board.tiles[piece.pos[1]+3][piece.pos[0]+3] = piece
......@@ -21,6 +25,7 @@ def main():
block = Block.Block(tuple(b))
board.tiles[block.pos[1]+3][block.pos[0]+3] = block
# Run a* search and print solution if one exists
path = A_Star(board)
if path is None:
print("No path found")
......@@ -31,56 +36,69 @@ def main():
def A_Star(start):
# Initialise open and closed sets
closedSet = []
openSet = [start]
# Initial path length and heuristic
start.g = 0
start.f = heuristic(start)
while openSet:
# Find node in open set with lowest f value and set it as the "current" node
minF = 1000000
for node in openSet:
if node.f <= minF:
current = node
minF = current.f
# If found node is the goal, retrace the path, and return the solution
if checkGoal(current):
return retrace(current)
# Remove the current node from the open set and add it to the closed set
openSet.remove(current)
closedSet.append(current)
#Find all neighbors of the current node
neighbors = getNeighbors(current)
# Iterate through the neighbors of the current node
for neighbor in neighbors:
"""
# If the neighbor is already in the closed set, skip it
inClosed = False
for node in closedSet:
if listCompare(neighbor.tiles, node.tiles):
inClosed = True
if inClosed:
continue
"""
#if neighbor.tiles == node.tiles:
# continue
tentative_gScore = current.g + 1
# Check if the neighbor is in the open set
inOpen = False
for node in openSet:
if listCompare(neighbor.tiles, node.tiles):
inOpen = True
# If not, add it
if not inOpen:
openSet.append(neighbor)
# If it is, but the neighbor has a higher g score than the node already in the list, skip it
elif tentative_gScore >= neighbor.g:
continue
# Set the parent and g and f scores of the node
neighbor.parent = current
neighbor.g = tentative_gScore
neighbor.f = neighbor.g + heuristic(neighbor)
# Compare two board states
def listCompare(list1, list2):
for i in range(0,7):
for j in range(0,7):
......@@ -89,6 +107,7 @@ def listCompare(list1, list2):
return True
# Calculates the heuristic for a given board state
def heuristic(node):
h = 0
for piece in node.pieces:
......@@ -99,12 +118,14 @@ def heuristic(node):
h += (min_dist + 1) / 2
return h
# Check if the goal has been reached
def checkGoal(state):
if not state.pieces:
return True
else:
return False
# Retrace the path from the goal state to the initial state
def retrace(goal):
path = []
cur = goal
......@@ -114,10 +135,13 @@ def retrace(goal):
path.insert(0,cur)
return path
# Find the neighbor states of a given board state
def getNeighbors(current):
neighbors = []
moves = current.getMoves()
# getMoves returns only a Piece object if a piece is on an exit tile
# In that case, the only neighbor is the same board with that piece removed
if isinstance(moves, Piece.Piece):
neighbor = copy.deepcopy(current)
......@@ -131,12 +155,15 @@ def getNeighbors(current):
neighbors.append(neighbor)
return neighbors
# Otherwise, it returns a list of possible moves
# In that case, return a list of board states with those moves applied
for move in moves:
neighbor = copy.deepcopy(current)
neighbor.move(move[0], move[1])
neighbors.append(neighbor)
return neighbors
# Functions for printing board state
def make_bdict(state):
bdict = {}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment