2012-03-29 7 views
1

私は初級プログラミングクラスのためにコンソール環境のハングマンゲームを書いています。プレーヤーは、単語の長さと好きな推測の数を選択します。 '簡単モード'は簡単です...リストのインデックスとして使用する乱数を生成し、選択した単語が適切な長さであることを確認します。しかし、「ハードモード」では、ゲームが進むにつれてリストが洗練され、推測された文字が与えられている可能性の中で最大のリストを選択する必要があります。文字の頻度と位置に基づいてリストの内容(単語)を絞り込む最も簡単な方法は何ですか? (C#)

私たちは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 

"ラメ"は、より多くの単語が "... le ..."パターンを持つため省略されます。私にとって理にかなっているテクニックは、各単語のパターンを配列(つまり、 "mole"と "hole" = 0011、 "lame" = 1001)に格納することです。重複を数えて大きなリストを決定する。

これは私がそれを行うべきである方法ですか?私はプログラミングに慣れていないし、1年分の経験があるので、私はそのように答えていると思います。

ありがとうございます!

+0

あなたは何を試してみることができますか? –

+2

あなたはどのバージョンのC#を使用していますか? LINQはあなたを大きく助けるでしょうから。 –

+0

お返事ありがとうございました!私はバックアップを保存し、chooseWordメソッドを完全に傷つけました。これらの回答のアドバイスを使って再作成しようとしています。 – nvillec

答えて

1

これにはいくつかの方法があります。簡単な方法は、すべての候補単語のリストを追跡し、その単語の一致する配列の量を計算することと、最も一致するシーケンスを記録することです。この方法では、最良のシーケンスだけでも十分な測定ツールではない場合でも、最良のシーケンスとシーケンスの量を並べ替えることができます。最良のシーケンスだけをソートするために、このコードをどのように変更するのが明らかになったのではないかと思います。

まずセットアップ私のテストケースのように:私はワードリストフィルタと一緒に望ましい結果を生成するために、私は最終的にグループのベストマッチ計算

// 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(); 

ご注意をコードのコメント

0

したがって、推測パターンと一致する文字列の配列を調べます。

"le"の特定のケースでは、単純にString.IndexOf()を使用します。よりcmplexパターンが必要な場合は、「* le?」と言ってください。 (*や?はDOSのようなワイルドカードパターンに従う)、ダイナミックにcnstructされた正規表現パターンを使うことができます(これは、ほぼリアルタイムシステムで使用すると簡単ですが、パフォーマンスが重くなります)、または文字スキャンあなたのパターンに合わせて)(より難しく、維持するのが難しく、RTに近いシステムでは少数の要素でより良いパフォーマンスが得られます)。

これは宿題なので、私は今パフォーマンスのプロファイリングを心配しません。

また、この構造体は巨大なグーフィーに見えます。確かにこのタイプのもののためのより良い構成があります。 List<String>のように、またはちょうどString[] ...どちらも.Countプロパティを持っています。

関連する問題