#python #indexing #pygame
#python #индексирование #pygame
Вопрос:
Я создал эту программу. Он находит слова в сетке.
Это работает, если размеры сетки равны, но это не работает всякий раз, когда я даю сетке неравные размеры.
С grid.txt
помощью as
WEDJCIOSDC
PVCEWOMNVU
VOWNRYCOWM
CJIMQPLDIW
QNIEOCMOFJ
FEWMQOPCNE
CIENWMEQBV
IVMENBSPLD
NOEFOQMFIE
JSCNIUSCGP
Моя программа окрашивает слова в красный цвет. Но с grid.txt
as
WEDJCIOSDC
PVCEWOMNVU
VOWNRYCOWM
CJIMQPLDIW
QNIEOCMOFJ
FEWMQOPCNE
CIENWMEQBV
IVMENBSPLD
NOEFOQMFIE
Это не сработает.
Мой код:
import pygame
pygame.font.init()
wn = pygame.display.set_mode((600, 600))
class Cell():
def __init__(self, x, y, s, text=' ', color=(0, 0, 0)):
self.input_box = pygame.Rect(x, y, s, s)
self.x = x
self.y = y
self.s = s
self.color = color
self.text = text
self.active = False
self.font = pygame.font.Font(None, s)
def draw(self):
txt = self.font.render(self.text, True, self.color)
x, y = self.x (self.s-txt.get_width())//2, self.y (self.s-txt.get_height())*5//7
wn.blit(txt, (x, y))
pygame.draw.rect(wn, self.color, self.input_box, 2)
class Grid():
def __init__(self, x, y, size, letters, color=(0, 0, 0)):
rows = len(letters)
cols = len(letters[0])
self.grid = [[Cell(i*size x, j*size y, size, letter) for i, letter in enumerate(row)] for j, row in enumerate(letters)]
self.cells = [cell for row in self.grid for cell in row]
self.rows = rows
self.cols = cols
def adj(self, cell, idx, lstlst, wrd):
x, y = self.cells.index(cell) // self.rows, self.cells.index(cell) % self.rows
y1 = x - 1 if x else 0
y2 = self.rows 2 if x > self.rows 2 else x 2
x1 = y - 1 if y else 0
x2 = self.cols 2 if y > self.cols 2 else y 2
adjs = []
for row in self.grid[y1:y2]:
for c in row[x1:x2]:
if c != cell:
adjs.append(c)
taillst = lstlst[-1]
for cell in adjs:
if len(wrd) > idx:
if cell.text == wrd[idx]:
lst = taillst[:]
lst.append(cell)
lstlst.append(lst)
self.adj(cell, idx 1, lstlst, wrd)
def draw(self):
for cell in self.cells:
cell.draw()
with open('grid.txt', 'r') as r:
letters = [row.strip() for row in r]
grid = Grid(50, 50, 32, letters)
word = 'NEW'
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
for cell in grid.cells:
lstlst = [[cell]]
grid.adj(cell, 1, lstlst, word)
for lst in lstlst:
if ''.join([c.text for c in lst]) == word:
for c in lst:
c.color = (255, 0, 0)
wn.fill((255, 255, 200))
grid.draw()
pygame.display.flip()
Комментарии:
1. Добавьте свою точную ошибку в свой вопрос.
2. @PM77-1 Ошибки нет, просто ничего не будет выделено.
3.
for j, row in enumerate(letters)
Должно ли это бытьenumerate(cols)
?4. @SerialLazer Нет,
cols
это целое число.
Ответ №1:
Ваша сетка — это сетка основного порядка строк, а не сетка основного порядка столбцов. Поэтому индексы сетки необходимо вычислять путем деления на количество столбцов, а не на количество строк:
x, y = self.cells.index(cell) // self.rows, self.cells.index(cell) % self.rows
x, y = self.cells.index(cell) // self.cols, self.cells.index(cell) % self.cols
С этими изменениями также работает исходное вычисление дополнительных ячеек:
adjs = [cell for row in self.grid[y1:y2] for cell in row[x1:x2] if cell != self.grid[x][y]]
Фактически, первый индекс для подписки — это строка ( y
), а второй — столбец ( x
), поэтому я рекомендую переименовать и поменять местами переменные ( x
/ y
):
class Grid():
# [...]
def adj(self, cell, idx, lstlst, wrd):
y, x = self.cells.index(cell) // self.cols, self.cells.index(cell) % self.cols
x1, x2 = max(0, x - 1), min(x 2, self.cols 2)
y1, y2 = max(0, y - 1), min(y 2, self.rows 2)
adjs = [cell for row in self.grid[y1:y2] for cell in row[x1:x2] if cell != self.grid[y][x]]
taillst = lstlst[-1]
for cell in adjs:
if len(wrd) > idx:
if cell.text == wrd[idx]:
lstlst.append(taillst[:] [cell])
self.adj(cell, idx 1, lstlst, wrd)
Ответ №2:
Проблема в коде заключается в классической путанице между осями x и y и неправильном приравнивании оси x к строкам.
Вот точная проблема:
x, y = self.cells.index(cell) % self.rows, self.cells.index(cell) // self.rows
Редактировать:: @Rabbid76 правильно указал, что нам нужно делить по столбцам, а не по строкам:
x, y = self.cells.index(cell) // self.cols, self.cells.index(cell) % self.cols
Пожалуйста, поддержите ответ @Rabbid76 вместо моего.
исправлена проблема с подсветкой, поскольку теперь мы можем найти фактическую ячейку с правильными координатами (x, y). В некотором смысле это также объясняет, почему это сработало для квадрата.
Однако, сказав это, я думаю, что могут потребоваться некоторые улучшения для алгоритма DFS для поиска word
.
Для начала, я не мог понять, почему вы начинаете с idx=1
here:
grid.adj(cell, 1, lstlst, word)
Но поскольку на самом деле это не было частью этого вопроса, я оставлю это вам.
Комментарии:
1. Вы пробовали это решение? Это вообще не работает. Ваш результат неверен.
2. Вопрос OP был о том, почему подсветка отсутствовала. Я уже указывал, что в любом случае существуют проблемы с алгоритмом DFS, которые не входят в сферу действия этого qn
3. Нет, вы неправильно ответили на вопрос. Четко указано, что результат должен быть таким же, как у квадрата. Разве вы не видите разницы на картинках? Цель состоит в том, чтобы найти строку
'NEW'
4. Нет, это не другая проблема. Это потому, что вы нырнули,
rows
а неcols
. Ошибка исправлена простым изменением одной строки кода. Вы ошибочно поменяли/
местами и%
вместоcols
того, чтобы использовать вместоrows
5. Ах, извините, я полностью пропустил эту часть. Извиняюсь, я согласен