问题描述
我制作了这个程序。它在网格中找到单词。
如果网格的尺寸相等,它会起作用,但是当我给网格不相等的尺寸时,它将不起作用。
使用grid.txt
作为
WEDJCIOSDC
PVCEWOMNVU
VOWNRYCOWM
CJIMQPLDIW
QNIEOCMOFJ
FEWMQOPCNE
CIENWMEQBV
IVMENBSPLD
NOEFOQMFIE
JSCNIUSCGP
我的程序将单词显示为红色。但是grid.txt
为
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)):
self.input_Box = pygame.Rect(x,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,size,letters,0)):
rows = len(letters)
cols = len(letters[0])
self.grid = [[Cell(i*size+x,j*size+y,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,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,word)
for lst in lstlst:
if ''.join([c.text for c in lst]) == word:
for c in lst:
c.color = (255,0)
wn.fill((255,255,200))
grid.draw()
pygame.display.flip()
解决方法
您的网格是行主要订单网格,而不是列主要订单网格。因此,网格索引需要通过除以列数而不是行数来计算:
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,wrd)
,
代码中的问题是x和y轴之间的经典混淆,并且错误地将x轴与行等价。
这是确切的问题:
x,y = self.cells.index(cell) % self.rows,self.cells.index(cell) // self.rows
编辑:: @ Rabbid76正确指出,我们需要按列而不是行进行划分:
x,self.cells.index(cell) % self.cols
请支持@ Rabbid76的答案,而不是我的答案。
解决了突出显示问题,因为我们现在能够找到具有正确(x,y)坐标的实际单元格。在某种程度上,这也解释了为什么它可以用于正方形。
但是,话虽如此,我认为使用DFS算法查找word
可能需要一些改进。
对于初学者来说,我无法弄清楚为什么您从idx=1
开始:
grid.adj(cell,1,word)
但是,由于这实际上不是这个问题的一部分,因此我将留给您。