Я работал над созданием алгоритма поиска для игры Akari (Light Up) с ограничением python, и я должен сделать его CSP. Я определил мои переменные как x и y, а домены - это длина доски соответственно.
Вот ссылка на игру, если вы хотите ее проверить: https://www.puzzle -light-up.com /
Вот моя проблема.
Мне удалось получить решения для случаев:
- При наличии нулевого тайла я не включаю соседей этого тайла в решение.
- Если есть пронумерованные плитки, получить координаты соседних плиток (все 4 из них).
Проблема:
- Несмотря на то, что у меня есть 4 соседа, я должен сделать так, чтобы пронумерованный 4 тайл должен был получить всех соседей, а номер 3 - 3 соседа, пронумерованные 2 и 1 плитки должны получить 2 и 1 соседний тайл соответственно.
- Также я не мог решить, как сделать ограничение для блоков белых плиток, которые соединены горизонтально и вертикально, где должен быть размещен только один источник света. В основном нет двух огней, которые могут видеть друг друга. Черные плитки и пронумерованные плитки блокируют свет.
Вот мой код и решение, которое я получаю. Если вы можете дать какие-либо советы о том, как думать о проблеме или показать мои ошибки, это было бы здорово. Я искал достаточно и не смог найти никакой полезной информации, которая могла бы заставить меня двигаться вперед в коде.
from constraint import *
# -1 for Black Tiles
# 0 for 0
# _ for W
# 1 for 1
# 2 for 2
# 3 for 3
# 4 for 4
board = [
["_", "_", "_", "_", "_", "_", "-1"],
["_", "_", "4", "_", "_", "_", "_"],
["0", "_", "_", "_", "1", "-1", "_"],
["_", "_", "_", "1", "_", "_", "_"],
["_", "-1", "1", "_", "_", "_", "-1"],
["_", "_", "_", "_", "-1", "_", "_"],
["1", "_", "_", "_", "_", "_", "_"]
]
problem = Problem()
# Variable and Domains
rows = range(len(board))
cols = range(len(board[0]))
problem.addVariables("y", rows)
problem.addVariables("x", cols)
# Constraints
# not including around of 0
problem.addConstraint(
lambda y, x: not ((0 <= y + 1 <= 6 and board[y + 1][x] == "0") or (0 <= y - 1 <= 6 and board[y - 1][x] == "0") or
(0 <= x + 1 <= 6 and board[y][x + 1] == "0") or (0 <= x - 1 <= 6 and board[y][x - 1] == "0")),
["y", "x"])
# do not include 0 tile
problem.addConstraint(lambda y, x: board[y][x] != "-1", ["y", "x"])
# including numbered tiles
problem.addConstraint(lambda y, x:
# add for 1
(0 <= y + 1 <= 6 and board[y + 1][x] == "1") or (0 <= y - 1 <= 6 and board[y - 1][x] == "1")
or (0 <= x + 1 <= 6 and board[y][x + 1] == "1") or (0 <= x - 1 <= 6 and board[y][x - 1] == "1")
# add for 2
or (0 <= y + 1 <= 6 and board[y + 1][x] == "2") or (0 <= y - 1 <= 6 and board[y - 1][x] == "2")
or (0 <= x + 1 <= 6 and board[y][x + 1] == "2") or (0 <= x - 1 <= 6 and board[y][x - 1] == "2")
# add for 3
or (0 <= y + 1 <= 6 and board[y + 1][x] == "3") or (0 <= y - 1 <= 6 and board[y - 1][x] == "3")
or (0 <= x + 1 <= 6 and board[y][x + 1] == "3") or (0 <= x - 1 <= 6 and board[y][x - 1] == "3")
# add for 4
or (0 <= y + 1 <= 6 and board[y + 1][x] == "4") or (0 <= y - 1 <= 6 and board[y - 1][x] == "4")
or (0 <= x + 1 <= 6 and board[y][x + 1] == "4") or (0 <= x - 1 <= 6 and board[y][x - 1] == "4"),
["y", "x"])
# check if there is a light source neighbour of a dedicated light source for 4
problem.addConstraint(lambda y, x:
not ((0 <= y + 2 <= 6 and board[y + 2][x] == "4")
or (0 <= y - 1 <= 6 and board[y - 2][x] == "4")
or (0 <= x + 2 <= 6 and board[y][x + 2] == "4")
or (0 <= x - 1 <= 6 and board[y][x - 2] == "4")), ["y", "x"])
# check if there is a light source diagonal of a dedicated light source for 4
problem.addConstraint(lambda y, x:
not ((x + 1 in cols and y + 1 in rows and board[y + 1][x + 1] == "4")
or ( x + 1 in cols and y - 1 in rows and board[y - 1][x + 1] == "4")
or (x - 1 in cols and y + 1 in rows and board[y + 1][x - 1] == "4")
or (x - 1 in cols and y - 1 in rows and board[y - 1][x - 1] == "4")), ["y", "x"])
solutions = problem.getSolutions()
print()
print(len(solutions))
print()
for item in solutions:
print(item)
board[item["y"]][item["x"]] = "L"
print()
for row in rows:
print(board[row])
Вот решение, которое я получаю для координат для размещения источников света:
9
{'x': 4, 'y': 3}
{'x': 3, 'y': 1}
{'x': 3, 'y': 4}
{'x': 2, 'y': 2}
{'x': 2, 'y': 0}
{'x': 2, 'y': 5}
{'x': 1, 'y': 6}
{'x': 1, 'y': 1}
{'x': 0, 'y': 5}
['_', '_', 'L', '_', '_', '_', '-1']
['_', 'L', '4', 'L', '_', '_', '_']
['0', '_', 'L', '_', '1', '-1', '_']
['_', '_', '_', '1', 'L', '_', '_']
['_', '-1', '1', 'L', '_', '_', '-1']
['L', '_', 'L', '_', '-1', '_', '_'][enter image description here][1]
['1', 'L', '_', '_', '_', '_', '_']
EDIT:
Вот так выглядит доска (а) и результат должен быть (б)
https://i.stack.imgur.com/IIXoc.png