Compare commits

...

1 Commits

Author SHA1 Message Date
Neerka
2e383d95f1 ogarnięte A* 2024-06-13 00:11:59 +02:00

103
main.py
View File

@ -0,0 +1,103 @@
import heapq
from itertools import chain
class Puzzle:
def __init__(self, board, moves=0):
self.board = board
self.moves = moves
self.sequence = []
self.parent = None
self.cost = 0
self.mode = 0 # 0 - Manhattan, 1 - Na dobrych miejscach
def ustal_koszt(self):
if self.mode == 0:
self.cost = self.moves + self.manhattan_distance()
elif self.mode == 1:
self.cost = self.moves + self.na_dobrych_miejscach()
return self.cost
def dodaj_ruch(self, ruch):
if self.parent is not None:
for move in self.parent.sequence:
self.sequence.append(move)
if ruch == (1, 0):
self.sequence.append("D")
elif ruch == (-1, 0):
self.sequence.append("U")
elif ruch == (0, 1):
self.sequence.append("R")
elif ruch == (0, -1):
self.sequence.append("L")
def znajdz_puste(self):
for i in range(4):
for j in range(4):
if self.board[i][j] == 0:
return i, j
def manhattan_distance(self):
distance = 0
for i in range(4):
for j in range(4):
if self.board[i][j] != 0:
x, y = divmod(self.board[i][j]-1, 4)
distance += abs(x - i) + abs(y - j)
return distance
def na_dobrych_miejscach(self):
heurystyka = 16
for i in range(4):
for j in range(4):
if self.board[i][j] != 0:
x, y = divmod(self.board[i][j]-1, 4)
if x == i and y == j:
heurystyka -= 1
return heurystyka
def sasiedzi(self):
i, j = self.znajdz_puste()
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
x, y = i + dx, j + dy
if 0 <= x < 4 and 0 <= y < 4:
board_copy = [row.copy() for row in self.board]
board_copy[i][j], board_copy[x][y] = board_copy[x][y], board_copy[i][j]
sasiad = Puzzle(board_copy, self.moves + 1)
sasiad.parent = self
sasiad.dodaj_ruch((dx, dy))
yield sasiad
def cel(self):
return self.board == [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]]
def __lt__(self, other):
return self.ustal_koszt() < other.ustal_koszt()
def solve(puzzle):
heap = [puzzle]
visited = {tuple(chain(*puzzle.board))}
while heap:
node = heapq.heappop(heap)
if node.cel():
return node.moves, node.sequence
for sasiad in node.sasiedzi():
flat_board = tuple(chain(*sasiad.board))
# print(flat_board not in visited)
if flat_board not in visited:
visited.add(flat_board)
# print("pushuje sąsiada")
heapq.heappush(heap, sasiad)
return -1
tablica = [
[2, 11, 8, 3],
[1, 6, 4, 12],
[5, 0, 14, 7],
[9, 10, 13, 15]
]
puzzle = Puzzle(tablica)
print(solve(puzzle))