import pygame
from pygame.locals import*
class Square(pygame.sprite.Sprite):
def __init__(self, letter, (x , y)):
pygame.sprite.Sprite.__init__(self)
self.rect = pygame.Rect(x,y,32,32)
self.image = pygame.Surface((32,32))
self.image.fill((255,0,0))
pygame.draw.rect(self.image, (200,0,0), (1,1,30,30), 2)
self.letter = letter
t = font.render(letter, 1, (0,0,0))
self.image.blit(t, (10,6))
self.corect_pos = goal[self.letter]
def clockwise(pos):
if pos[0]== 0 and pos[1] <=32:
return pos[0], pos[1]+32
elif pos[0] >=32 and pos[1] == 0:
return pos[0]-32, pos[1]
elif pos[0] == 64 and pos[1] >= 32:
return pos[0], pos[1]-32
elif pos[0] <=32 and pos[1] ==64:
return pos[0]+32, pos[1]
def test_combinacion(squares):
h = 0
moves = 0
for s in squares:
distance = abs(s.rect.left-s.corect_pos[0])+ abs(s.rect.top-s.corect_pos[1])
if distance !=0:
distance = distance/32
moves += distance
if s.rect.topleft !=(32,32):
if s.letter != 'A':
letter_check = chr(ord(s.letter)-1)
else:
letter_check = 'H'
pos_check = clockwise(s.rect.topleft)
for s in squares:
if s.letter == letter_check:
if s.rect.topleft != pos_check:
h+=2
if space_pos != (32,32):
h+=1
h = h*3 + moves
return h+g
def move(square):
enable_pos= [(square.rect.left-32, square.rect.top),
(square.rect.right, square.rect.top),
(square.rect.left, square.rect.top-32),
(square.rect.left, square.rect.bottom)]
if space_pos in enable_pos:
return space_pos,square.rect.topleft
else:
return -1
def make_moves(sq):
global space_pos
returning =[]
for s in sq:
t = move(s)
if t!= -1:
temp = s.rect.topleft,space_pos
s.rect.topleft,space_pos = t
comb = make_combinacion(squares)
if comb not in closedlist and comb not in openlist:
returning.append(comb)
s.rect.topleft,space_pos = temp
return returning
def check(combinacion):
c =[]
for l, pos in combinacion:
if goal.values()[goal.keys().index(l)] == pos:
c.append(1)
else:
c.append(0)
return all(c)
def broji():
global counter
if counter < 6:
counter+=1
else:
counter = 0
g = 0
pygame.init()
font = pygame.font.Font('freesansbold.ttf', 18)
screen = pygame.display.set_mode((160,96))
start_button= pygame.Rect(112,16, 32,16)
goal = {'A':(0,0),'B':(32,0),'C':(64,0),'D':(64,32),'E':(64,64),'F':(32,64),'G':(0,64),'H':(0,32),'space':(32,32)}
squares= []
for letter, pos in goal.items():
if letter != 'space':
squares.append(Square(letter, pos))
else:
space_pos = pos
make_combinacion = lambda sq:[(s.letter,s.rect.topleft) for s in sq]+[('space',space_pos)]
make_squares = lambda combinacion: [Square(l, pos) for l, pos in combinacion if l!='space']
openlist =[]
closedlist=[]
clock = pygame.time.Clock()
ch = False
counter = 0
solve =0
while 1:
clock.tick(40)
for event in pygame.event.get():
if event.type == QUIT:
raise SystemExit()
#Crtanje svega
screen.fill((0,0,255))
pygame.draw.rect(screen, (255,255,255), start_button)
for s in squares:
screen.blit(s.image,s.rect)
pygame.display.flip()
#Program
if solve:
#Algoritam
broji()
if ch != True and counter ==5:
openlist = make_moves(squares)
g+=1
fs =[]
for x in openlist:
squares = make_squares(x)
space_pos = x[-1][1]
fs.append(test_combinacion(squares))
c = openlist[fs.index(min(fs))]
space_pos = c[-1][1]
ch = check(c)
squares = make_squares(c)
closedlist.extend(openlist)
if ch == True:
solve =0
closedlist =[]
else:
#Postavljaj kockice
mstate = pygame.mouse.get_pressed()
if mstate[0]:
mpos = pygame.mouse.get_pos()
for s in squares:
if s.rect.collidepoint(mpos):
t = move(s)
if t != -1:
s.rect.topleft, space_pos = t
if start_button.collidepoint(mpos):
ch =check(make_combinacion(squares))
openlist = [make_combinacion(squares)]
g = 0
solve = 1
Need help with python and A*
Hi, people I'm new here, and I have problem with my program that need to solve puzzle usnig A* algorithm. In some cases program can't solve puzzle.
Exzample:
H A B
G D C
F E
Here is a source:
[edit: formatting -SiCrane]
It looks like you're appending the entire open list to the closed list instead of just the state that was expanded.
You're also assuming that A*'s first guess is always correct, but that is not the case. If you always make the move that looks best then you have to backtrack sometimes. A* needs to find a complete solution path, not just one move at a time.
You're also assuming that A*'s first guess is always correct, but that is not the case. If you always make the move that looks best then you have to backtrack sometimes. A* needs to find a complete solution path, not just one move at a time.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement