如何在令人难以置信的游戏中递归检查答案

发布于 2024-11-03 10:00:19 字数 2051 浏览 4 评论 0原文

作为练习,我一直在尝试用 python 构建一个非 GUI 类型的游戏。到目前为止,用户可以输入板尺寸(4x4、5x5 等)。字母“数组”出现,然后用户可以输入他们认为有效的单词。

我想使用递归函数检查输入的单词是否有效。在小板上我的解决方案似乎工作得很好。然而,在较大的板上,具有相似开头和多个路径的单词不会被记录。我有一种感觉,这是因为如果当前路径在没有找到正确单词的情况下结束,我的函数的最后一部分就无法后退足够远。

这是我到目前为止所得到的:

def isAdjacent(word, wordLetter, possibleStarts, arrayDict, currWord, start):

  #'word' is the word entered. 'wordLetter' is the current letter being looked for.
  #'possibleStarts' is a list of tuples of the possible starting locations and subsequent positions of each found letter.
  #'arrayDict' is a dictionary associating each position ((0,1), etc) with a game letter.
  #'currWord' is used to check whether or not a word has been found.
  #'start' is the tuple in possibleStarts that should be used.

  if currWord == word:
    return 1
  x = possibleStarts[start][0]
  y = possibleStarts[start][1]
  arrayDict[x,y] = 0
  optionsList = [(x - 1, y - 1), (x - 1, y), (x - 1, y + 1), (x, y - 1), (x, y + 1), (x + 1, y - 1), (x + 1, y), (x + 1, y + 1)]
  newStarts = []
  count = 0
  count2 = 0
  for option in optionsList: 
    count += 1
    if option in arrayDict:
      if arrayDict[option] == word[wordLetter]:
        if count2 < 1:
          currWord += word[wordLetter]
          arrayDict[option] = 0
          count2 += 1
        newStarts.append(option) 
    if count == 8 and newStarts:                                                        
      return isAdjacent(word, wordLetter + 1, newStarts, arrayDict, currWord, start)    
  try:
    if currWord != word:
      if wordLetter > 2:
        return isAdjacent(word, wordLetter - 1, possibleStarts, arrayDict, currWord[:-1], start - 1) 
      else:
        return isAdjacent(word, wordLetter, possibleStarts, arrayDict, currWord, start - 1) 
  except:
    pass

我相信至少部分问题在于函数末尾的 try 块。如果单词不太长或者没有太多可能性,它就有效。例如,尝试在下面找到“raws”,即使它在那里,也是行不通的:

W T S V
A X A H
S R T S
A B A W

我确信这可以通过一个相当简单的递归函数来完成,但几个小时后,我迷失了。 哦,我宁愿不预先生成所有可能的单词。其目标是使用递归来查找输入的单词。

非常感谢任何帮助!

As an exercise, I have been trying to build a non-GUI boggle type game in python. So far, the user is able to enter a board size (4x4,5x5,etc). The 'array' of letters appears and then the user may type in a word that they think is a valid option.

I wanted to check if the entered word was valid by using a recursive function. On small boards my solution seems to work fine. On larger boards however, words with similar starts and multiple paths don't register. I have a feeling that it is because the last part of my function is not able to step back far enough if the current path ends without finding a correct word.

Here is what I have so far:

def isAdjacent(word, wordLetter, possibleStarts, arrayDict, currWord, start):

  #'word' is the word entered. 'wordLetter' is the current letter being looked for.
  #'possibleStarts' is a list of tuples of the possible starting locations and subsequent positions of each found letter.
  #'arrayDict' is a dictionary associating each position ((0,1), etc) with a game letter.
  #'currWord' is used to check whether or not a word has been found.
  #'start' is the tuple in possibleStarts that should be used.

  if currWord == word:
    return 1
  x = possibleStarts[start][0]
  y = possibleStarts[start][1]
  arrayDict[x,y] = 0
  optionsList = [(x - 1, y - 1), (x - 1, y), (x - 1, y + 1), (x, y - 1), (x, y + 1), (x + 1, y - 1), (x + 1, y), (x + 1, y + 1)]
  newStarts = []
  count = 0
  count2 = 0
  for option in optionsList: 
    count += 1
    if option in arrayDict:
      if arrayDict[option] == word[wordLetter]:
        if count2 < 1:
          currWord += word[wordLetter]
          arrayDict[option] = 0
          count2 += 1
        newStarts.append(option) 
    if count == 8 and newStarts:                                                        
      return isAdjacent(word, wordLetter + 1, newStarts, arrayDict, currWord, start)    
  try:
    if currWord != word:
      if wordLetter > 2:
        return isAdjacent(word, wordLetter - 1, possibleStarts, arrayDict, currWord[:-1], start - 1) 
      else:
        return isAdjacent(word, wordLetter, possibleStarts, arrayDict, currWord, start - 1) 
  except:
    pass

I believe that at least part of the problem lies in the try block at the end of the function. It works if the word is not too long or if there are not too many possibilites. For example, attempting to find 'raws' in the following, will not work, even though it is there:

W T S V
A X A H
S R T S
A B A W

I am certain that this can be done with a rather simple recursive function, but after many hours, I am lost.
Oh, I would rather not generate all of the possible words beforehand. The goal of this was to use recursion to find an entered word.

Any help is greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不打扰别人 2024-11-10 10:00:19

有趣的练习,我已经尝试过了。我发布了下面的代码,因此请将此视为剧透警报。对于一般提示:

  • 将代码分解为更小的块 - 一个函数来统治所有这些块并不会让您走得太远。
  • 在进行递归时,首先找到基本情况,即。函数何时递归。
  • 让每个子功能只知道它需要知道的内容。

就是这样。我对 Boggle 的完整规则有点生疏,而且我不完全确定你一直在做什么,但这就是我的想法:


def paths(grid, x, y, l):
    """Returns a list of positions that the required letter is at"""

    positions = [(x - 1, y - 1), (x - 1, y), (x - 1, y + 1), (x, y - 1), (x, y + 1), (x + 1, y - 1), (x + 1, y), (x + 1, y + 1)]
    return [p for p in positions if p in grid and grid[p] == l]

def matchWord(grid, pos, word):
    """Returns true if the word was found in the grid starting from pos"""
    if word == "" : return True
    pos_paths = paths(grid, pos[0], pos[1], word[0])
    if pos_paths == [] : return False

    return any(matchWord(grid, the_pos, word[1:]) for the_pos in pos_paths)

def wordInGrid(grid, word):
    """returns true if the word is in the grid"""
    return any(matchWord(grid, key, word[1:]) for (key, val) in dict.iteritems(grid) if val == word[0])


gr_dict = {(0, 1): 'T', (1, 2): 'A', (3, 2): 'A', (0, 0): 'W', (3, 3): 'W', (3, 0): 'A', (3, 1): 'B', (2, 1): 'R', (0, 2): 'S', (2, 0): 'S', (1, 3): 'H', (2, 3): 'S', (2, 2): 'T', (1, 0): 'A', (0, 3): 'V', (1, 1): 'X'}

print wordInGrid(gr_dict, "RATS")
print wordInGrid(gr_dict, "WASABATAS")

Interesting exercise, I had a crack at it. I post the code below so consider this a spoiler alert. For general tips:

  • Break the code down into smaller chunks - one function to rule them all doesn't take you far.
  • When doing recursion, start by finding the base cases, ie. when will the function not recurse.
  • Let each subfunction know only what it needs to know.

That's about it. I'm a bit rusty on the complete rules of Boggle and I'm not completely sure what you are doing the entire time, but this what I've come up:


def paths(grid, x, y, l):
    """Returns a list of positions that the required letter is at"""

    positions = [(x - 1, y - 1), (x - 1, y), (x - 1, y + 1), (x, y - 1), (x, y + 1), (x + 1, y - 1), (x + 1, y), (x + 1, y + 1)]
    return [p for p in positions if p in grid and grid[p] == l]

def matchWord(grid, pos, word):
    """Returns true if the word was found in the grid starting from pos"""
    if word == "" : return True
    pos_paths = paths(grid, pos[0], pos[1], word[0])
    if pos_paths == [] : return False

    return any(matchWord(grid, the_pos, word[1:]) for the_pos in pos_paths)

def wordInGrid(grid, word):
    """returns true if the word is in the grid"""
    return any(matchWord(grid, key, word[1:]) for (key, val) in dict.iteritems(grid) if val == word[0])


gr_dict = {(0, 1): 'T', (1, 2): 'A', (3, 2): 'A', (0, 0): 'W', (3, 3): 'W', (3, 0): 'A', (3, 1): 'B', (2, 1): 'R', (0, 2): 'S', (2, 0): 'S', (1, 3): 'H', (2, 3): 'S', (2, 2): 'T', (1, 0): 'A', (0, 3): 'V', (1, 1): 'X'}

print wordInGrid(gr_dict, "RATS")
print wordInGrid(gr_dict, "WASABATAS")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文