1

我正在尝试为学校完成这个 boggle 游戏 Python 挑战,我创建了一个绘图板函数,该函数创建一个包含 16 个随机字母的板。如何使用 def 函数要求用户输入一个单词,然后根据单词的长度对其进行评分?完成后,游戏应该可以正常运行。任何帮助将不胜感激 :)

import random

def loadwords ():
    print "Loading word list from file.. "
    wordList = []
    inFile = open ('words.txt','r')
    for line in inFile:
        wordList.append(line.strip().lower())
    #inFile : locates file in the folder, opens it
    #wordlist: list of the words (strings)
    print " " , len(wordList), "words loaded"
    inFile.close()
    return wordList

def spellCheck (word, wordList):
    if (word in wordList) == True:
        return True
    else:
        return False

def drawBoard (randomLetters):

    '''Takes a randomList of 16 characters
    Prints out a 4 x 4 grid'''

    print " %s %s %s %s " %(randomLetters [0], randomLetters [1], randomLetters [2], randomLetters [3])
    print " %s %s %s %s " %(randomLetters [4], randomLetters [5], randomLetters [6], randomLetters [7])
    print " %s %s %s %s " %(randomLetters [8], randomLetters [9], randomLetters [10], randomLetters [11])
    print " %s %s %s %s " %(randomLetters [12], randomLetters [13], randomLetters [14], randomLetters [15])

def wordinput ():
    #asks user to input the longest word they can from grid
    wordinput = raw_input ("Enter a word made up of the letters in the 4x4 table")
    for letters in wordinput:
        letters == randomLetters

def randomLetters ():
    letters = []
    alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','v','w','x','y','z']
    for i in range (0,16,1):
        letters.append(random.choice(alphabet))
    return letters

dictionary = loadwords()
letterList = randomLetters()
drawBoard(letterList)
wordinput(randomLetters)
4

3 回答 3

2

raw_input(在 Python 2 中)或input(在 Python 3 中)允许读取字符串。

然后你需要检查所有字母是否都包含在字母表中......

def wordInLetter(word, letters):
    for i in range(word):
        if word[i] not in letters:
             return False
    return True

或更短:

def wordInLetter(word, letters):
    return all(letter in letters for letter in word)

但是等等,你不想让一个字母多次使用成为可能!

让我们使用Counter来跟踪每个字母在信袋中出现的次数并以此为基础进行计算:

from collections import Counter
def wordInLetter(word, letters):
    available = Counter(letters)
    for letter in word:
        if available[letter] == 0:
             return False
        available[letter] -= 1
    return True

这似乎工作得很好。我希望这是你需要的。

In [3]: wordInLetter('kos','akos')
Out[3]: True

In [4]: wordInLetter('kos','ako')
Out[4]: False

In [5]: wordInLetter('koss','akos')
Out[5]: False

编辑

所以我们不仅关心是否word可以组合 in letters,还想知道是否可以通过匹配相邻的字母来完成。所以再试一次:

import math
def wordInLetterSearch(word, letters, startX, startY):
    # Assume: letters is a list of X letters, where X is a k*k square
    k = int(len(letters) ** 0.5)

    if len(word) == 0:
        return True

    def letter(x, y):
        return letters[x + y*k]

    def adjacent(x, y):
        if x > 0:
           yield x-1, y
        if x < k-1:
           yield x+1, y
        if y > 0:
           yield x, y-1
        if y < k-1:
           yield x, y+1

    # try to move in all 4 directions
    return any(letter(x2, y2) == word[0] and wordInLetterSearch(word[1:], letters, x2, y2)
               for x2, y2 in adjacent(startX, startY))

def wordInLetter(word, letters):
    k = int(len(letters) ** 0.5)

    def coords(i):
        return i%k, i/k

    # look for a starting point
    return any(letter == word[0]
                    and wordInLetterSearch(word[1:], letters,
                                           coords(i)[0], coords(i)[1])
               for i, letter in enumerate(letters)) coords(i)[1])
                   for i, letter in enumerate(letters))

这有点复杂。基本上这是一个两步搜索:首先我们寻找一个起点(letters字母与单词的第一个字符匹配的位置),然后我们尽可能递归地将蛇形移动到相邻的字段。

只需少量修改即可完全匹配 Boggle 规则:

  • 修改adjacent以允许对角线(简单),
  • 防止两次访问同一地点(中等;提示:向 中添加参数wordInLetterSearch,使用 a set)。

我会把这些留作练习。

于 2012-11-20T14:50:07.553 回答
1

这是另一个变体。它应该更容易阅读,但想法是一样的:简单回溯。有时,更容易在调用方中止迭代(不执行下一步),有时在被调用方(在每次迭代中,检查前置条件并在无效时中止)。

def wordInBoardIter(letters, word, x, y):
    n = int(len(letters)**0.5)
    if word == "": return True # empty - all letters are found
    if x<0 or y<0 or x>=n or y>= n: return False #outside of board
    if letters[x+y*n] != word[0]: return False # we are looking at the wrong position
    # one step further:
    return any(wordInBoardIter(letters, word[1:], x+dx,y+dy) for dx,dy in [(1,0), (0,1), (-1,0), (0,-1)])


def wordInBoard(letters, word):
    n = int(len(letters)**0.5)
    return any(any(wordInBoardIter(letters, word, x,y) for x in range(n)) for y in range(n))

if __name__ == '__main__':
    letters = ['a', 'h', 'e', 'l',
               'x', 'd', 'l', 'l',
               'y', 'v', 'r', 'o',
               'z', 'w', 'o', 'w']
    print "hello     : %s" % ("found" if wordInBoard(letters, "hello") else "not found")
    print "helloworld: %s" % ("found" if wordInBoard(letters, "helloworld") else "not found")
    print "foobar    : %s" % ("found" if wordInBoard(letters, "foobar") else "not found")

在这个版本中有相同的练习(对角线瓷砖和不允许重复使用相同的字母两次)。

于 2012-11-20T17:01:44.677 回答
0

我没有玩太多 myslef,但是您可以用来执行此操作的解决方案是获取用户输入的单词并使用len()命令返回单词的长度。然后取那个长度并得分。这是一个基本示例(修改它以适应游戏规则):

def wordinput ():
    #asks user to input the longest word they can from grid
    wordinput = raw_input ("Enter a word made up of the letters in the 4x4 table")
    for letters in wordinput:
        letters == randomLetters
    scoreWord(wordInput)

def scoreWord(word)
    #finds the amount of characters in the word
    wordLength = len(word)
    #multiplies the maunt of letters in the word by two to get the score
    #(not sure how boggle scoring works)
    score = wordLength * 2
于 2012-11-20T14:49:33.150 回答