Моя индексация завершается с ошибкой, когда моя сетка не квадратная

#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. Ах, извините, я полностью пропустил эту часть. Извиняюсь, я согласен