我正在为我的入门编程课程编写一个控制台环境Hangman游戏。玩家选择他们想要的单词长度和猜测次数"简易模式"足够简单。。。生成一个随机数用作列表的索引,并检查所选单词的长度是否正确。然而,"硬模式"需要随着游戏的进行对列表进行细化,根据猜测的字母选择最大的可能性列表。
我应该注意,我们没有使用C#List类,而是创建基于数组的结构:
struct ListType
{
public type[] items;
public int count;
}
//defined as:
ListType myList = new ListType();
myList.items = new type[max value];
myList.count = 0;
无论如何,这里有一个"硬模式"应该走的方式的例子:
Word List:
hole
airplane
lame
photos
cart
mole
(player chooses word length of 4)
Word List (refined):
hole
lame
cart
mole
(player guesses "l", then "e")
Word List (refined):
hole
mole
省略"Lame"是因为更多的单词具有"…le…"模式。对我来说有意义的技术(但并没有按照我想要的方式工作)是将每个单词的模式存储到一个数组中(即:"摩尔"one_answers"洞"=0011,"跛脚"=1001),并对重复的单词进行计数以确定更大的列表。
我应该这样做吗?我是编程新手,有不到一年的编程经验,所以我想答案是这样的。
谢谢!!
有几种方法可以解决这个问题。一个简单的方法是跟踪所有候选单词的列表,计算该单词的匹配序列数量,并记录最佳匹配序列。这样,当单独的最佳序列不是一个足够好的测量工具时,您既可以对最佳序列进行排序,也可以对序列数量进行排序。我希望如何修改这段代码以便只按最佳顺序排序变得显而易见。
首先,我设置了一个测试用例,比如:
// mimic the scenario given by the QA
string[] wordList = new string[] { "hole", "airplane", "lame", "photos", "cart", "mole" };
int wordLength = 4;
List<char> requiredCharacters = new List<char>{ 'l', 'e'};
之后,我过滤单词列表并计算最佳匹配,最后将其组合在一起以产生所需结果:
// filter all words that dont match the required length
var candidateWords = wordList.Where(x => x.Length == wordLength);
// define a result set holding all the words and all their matches
Dictionary<string, List<int>> refinedWordSet = new Dictionary<string, List<int>>();
foreach (string word in candidateWords)
{
List<int> matches = new List<int>() { 0 };
int currentMatchCount = 0;
foreach (char character in word)
{
if (requiredCharacters.Contains(character))
{
currentMatchCount++;
}
else
{
// if there were previous matches
if (currentMatchCount > 0)
{
// save the current match
matches.Add(currentMatchCount);
currentMatchCount = 0;
}
}
}
// if there was a match at the end
if (currentMatchCount > 0)
{
// save the last match
matches.Add(currentMatchCount);
}
refinedWordSet.Add(word, matches);
}
// sort by a combination of the total amount of matches as well as the highest match
var goupedRefinedWords = from entry in refinedWordSet
group entry.Key by new { Max = entry.Value.Max(), Total = entry.Value.Sum() } into grouped
select grouped;
foreach (var entry in goupedRefinedWords)
{
Console.WriteLine("Word list with best match: {0} and total match {1}: {2}",
entry.Key.Max,
entry.Key.Total,
entry.Aggregate("", (result, nextWord) => result += nextWord + ", "));
}
Console.ReadLine();
注意代码中的注释
因此,您可以在数组中查找与猜测模式匹配的字符串。
在"le"的特定情况下,您可以简单地使用String.IndexOf()
。如果您需要更多的cmplex模式。。比如"*le?"(其中*和?遵循类似DOS的通配符模式),您可以使用动态结构化的regex模式(如果在接近实时的系统中使用,则很容易,但性能很高)或字符扫描(从屏幕上读取每个字符并与您的模式相匹配)(在接近RT的系统中,对于少量元素来说,更困难、更难维护、性能更好)。
由于这是家庭作业,我现在根本不担心性能评测。
此外,这个结构看起来非常愚蠢。对于这种类型的东西,肯定有更好的构造。就像List<String>
,或者只是String[]
。。。两者都具有CCD_ 4性质。