使用スイッチング-ブロックの解析を入力したテキストの冒険?
-
16-10-2019 - |
質問
大丈夫、私的な目標を持っくりの基本的なテキストの冒険をしました。このためにはしっていなければいけないと考えて/をしたい方はswitchステートメントでは、以下の
- された文字列は、単語のどこか。
- チェックを見れば文字列には二つの言葉を組み合わせのどこか。
方法を教えてください。)できるだ符号化のためにこの特定の例:
ユーザー入力を求められます。スイッチを算書のチェック"lookボックスの一つとして"、"睡眠"しています。そのプログラムにはきちんとケアをどのような順番で任意の言葉がないのです。
教えてくださいました。だから符号といいます。
編集:ありがとうございました。応答となります。私の理解であり、より良い、より複雑に、より有用な方法で取り扱うことがで名付けられたという私のレベルになった。
解決
これが別のアイデアです:
string input = "look at the sleep box";
bool caseA = input.Contains("sleep");
bool caseB = input.Contains("look") && input.Contains("box");
int scenarioId;
if (caseA && caseB)
scenarioId = 1;
else if (caseA)
scenarioId = 2;
else if (caseB)
scenarioId = 3;
// more logic?
else
scenarioId = 0;
switch (scenarioId)
{
case 1:
Console.WriteLine("Do scenario 1");
break;
case 2:
Console.WriteLine("Do scenario 2");
break;
case 3:
Console.WriteLine("Do scenario 3");
break;
// more cases
default:
Console.WriteLine("???");
break;
}
If/then/elseを使用して、入力などの潜在的な組み合わせを含む特定のシナリオを評価します "look at the sleep box"
次に、スイッチステートメントを使用してそれに応じて実行します。
他のヒント
人は時にお願いいかんを築きます。思お手軽にいったん帆.私が好きな人に出航するな造船でのご支出では、あなたのガレージビルボート前でセーリング場合には船の購入ります。場の構築を目指しボート、ボートです。
の場合の目標は、学習C#による文書をテキストの冒険好きが多く、勉強になりました。の場合は 書きテキストの冒険, しいスレッドセーフで、C#、利用Inform7.で習得が容易に特に設計された、スキーとは、おそらく最も高いレベルの"言語る。でもプログラミング言語とします。
お答えい:ることではないんです。のテキストの冒険プロセッサを実際に著作物が最初にするプログラムを書くの文字をユーザに トークン.いて検索する文字列の文字による文字を見たと言葉のように、空間、カンマ区切な時期です。一度、境界のその部分文字列の境界のみを認識すべての単語との比較で言葉を辞書で調べました。
きのシーケンスにトークンをおしてみ合わせ配列に対する 文法.それは、まだ配列をトークンに分類され、一言コマンドのような{"look"}または動詞-名詞句のような{"う","で","は","red","button"}.したい休憩の減少が"look"の動詞"に"の前置詞の"の赤いボタン"は、オブジェクトの動詞"the"は、"赤"の形容詞および"ボタン"が名詞の語尾.
いるように聞こえるよ、初心者なのでは字句解析;歩くより文字列に一文字の特定の単語境界をつくります List<string>
一枚配布します。技術と文法の分析でき、非常に複雑;の単純なものでは固体です。
あなたが始めていることを考えると、私たちは最初に簡単なケースでこれを見ることができますが、あなたは使用することはできません switch
これを達成するための声明。
シンプルさの目的のために、あなたのコマンドは1つか2つの単語に制限され、最初の単語は動詞であり、2番目の単語は存在が名詞である場合、2番目の単語が動詞であると仮定します。これにより、かなりの数の可能性が得られます。
North
South
Examine
Take
Drop
等...
入力文字列があることを考えると strInput
:
string strInput = "examine hat";
最初にこれを分割したいと思います。これを使用することができます String.Split
:
string[] arguments = strInput.Split(' ');
文字列アレイは次のとおりです。
引数[0]はです 診る
引数[1]はです 帽子
ユーザーが入力した場合、私たちは常に2番目のものを持っているとは限りません。
`North`
それから:
引数[0]はです 北
これを確認する必要があります!さて、これをチェックする恐ろしい(しかし単純な)方法は次のとおりです。
if(arguments[0] == "North")
{
// code to go North
}
else if(arguments[0] == "Take")
{
// code to work with Take. We'd check on arguments[1] here!
}
// etc...
残念ながら、このコードは長く、複雑で使用できなくなります。どんな段階でもできることとできないことをどうやって知るのですか?新しいコマンドをどのように追加しますか? C#のすばらしいデリゲート機能を使用し、 Dictionary
. 。辞書を使用すると、1つのタイプ(キー)を別のタイプ(この場合は代表者)にマッピングできます。この方法を使用して、さまざまな種類のコマンドを処理するためにデリゲートを作成できます。
public delegate void HandleCommand(string[] _input);
ここでは、代表者を委任しました。まだ心配しないでください。しかし、コマンドで動作するいくつかの機能を紹介しましょう。
public void Handle_North(string[] _input)
{
// code to go North. This function could just as easily be something that handles
// *all* directions and checks _input[0] to see where to go!
}
public void Handle_Take(string[] _input)
{
if(_input.Length > 1) // Did the user specify an object to take?
{
// code to handle Take.
}
}
等々。次に、コマンドをこれらの関数にマッピングするために辞書を作成する必要があります。
Dictionary<String, HandleCommand> map = new Dictionary<String, HandleCommand>();
ここでは、文字列をデリゲートタイプにマッピングする辞書を宣言します HandleCommand
. 。今、私たちはそれを住む必要があります!
map["north"] = Handle_North;
map["take"] = Handle_Take;
// and the rest of our commands
さて、以前の例を考慮して、以前のように文字列を分割して、右のハンドラーに電話しましょう!
string[] arguments = strInput.Split(' ');
if(arguments.Length > 0 && map.ContainsKey(arguments[0]))
map[arguments[0]](arguments); // calls our function!
これで、拡張可能なシステムがあります。新しいコマンドとハンドラーを簡単に追加できます!それはより複雑になりますが、本質的にこれはあなたが望むことをするのに良い方法です。
編集:私はあなたの質問が言葉の順序を気にしてはならないと言ったことを知っています。テキストアドベンチャーゲームを書いている場合は、物事をランダムに入力するのではなく、動詞/名詞のグラマーまたはそのようなものを形成するのに適しています。
これを使用することはできません switch
, 、if-else-ifタイプの構造を使用する必要があります。
string input=...
if(input.Contains("sleep")){ //contains sleep?
//do stuff for some word
}else if(input.Contains("look") && input.Contains("box")){ //contains look and box
//do stuff for the combination thing
}
と switch
各 case
静的で一意の値でなければなりません。だからあなたは使用できません .Contains
ケースとして。
使用できません switch
これは直接ですが、それでも、そうすべきではないと思います。あなたはおそらく、 switch
.
すべての可能なアクションを含むように列挙を使用することを検討してください。
public enum AdventureAction
{
LookBox,
Sleep
}
「解析」を行う方法を書くことを検討してください。
public static AdventureAction Parse(string text)
{
if (text.Contains("look") && text.Contains("box"))
return AdventureAction.LookBox;
if (text.Contains("sleep"))
return AdventureAction.Sleep;
}
そして、シンプルを使用できます switch
アクションを実行するための声明:
var action = Parse(input);
switch (action)
{
case AdventureAction.LookBox:
// do something interesting with the box
break;
case AdventureAction.Sleep:
// go to sleep
break;
}
私は現在、私を悩ませている致命的な欠陥をすべて情報提供/Adrift/Questのために、私自身のテキストアドベンチャーエンジンを書いています。初心者が可能)、Adriftのugい読者、およびAdrift/Questsの実際のクラス/オブジェクトのサポートの欠如。
それはそれを行うための最良の方法ではないかもしれませんが、これまでのところ正常に動作しています。私は正規表現を調べましたが、代わりにこのようにすることにしました。
最初にすることは、プレーヤーの入力/コマンド文字列をリストに分割することです。幸いなことに、これらのゲームでは、このリストの最初の要素はほとんど常に動詞です。
- 見る
- で
- 青い
- 本
「外観、検査、Ex」など、それに一致するすべての値を含む、キーによってアクセスできる動詞/オブジェクト/などのデータクラスが必要です。
class Verb
{
string uniqueID;
List<string> values;
}
class Object
{
public uniqueID; // Because this is shared with Verbs, you could do a better unique ID system, but hey...
public List<string> articles;
public List<string> adjectives;
public List<string> noun;
}
また、プレイヤーの入力から一致する「アクション」サブクラスの束も必要です。ここでは、プレイヤーの入力と一致する必要がある文構造を「構築」します。
- アクション(ベースクラス)
- 見る
- {at} [オブジェクト]を見る
- {at}本を見てください
- ジャンプ
- ジャンプ{オン/オンに} [オブジェクト
.
class Action
{
string uniqueID;
List<SentenceElement> sentence;
void Execute();
bool RestrictionsCheck();
}
class Look : Action
{
override void Execute();
override bool RestrictionsCheck();
}
class LookAtObject : Action
{
override void Execute();
override bool RestrictionsCheck();
}
class LookAtBook : Action
{
override void Execute();
override bool RestrictionsCheck();
}
ベースアクションクラスには、文のエレメントを使用した文ビルダーがあります。それは、文章一枚の文を説明するリストにすることができます。
class SentenceElement
{
List<string> values;
bool isOptional;
}
class VerbID : SentenceElement {}
class ObjectID : SentenceElement {}
class ObjectAny : SentenceElement {}
class CharacterID : SentenceElement {}
class CharacterAny : SentenceElement {}
class TextOptional : SentenceElement {}
class TextRequired : SentenceElement {}
class Parameter : SentenceElement {}
これで、「アクション」クラスを検索し、最初の文のエレメントを最初の入力動詞と比較し、一致するもののリストを「ポテンシャル」として保持できます。 「String.Contains」が機能します。
これで、プレイヤーの入力コマンドを介して踏み出し、それらを比較するすべての文のエレメントを踏むことにより、最も近い一致するアクションを見つける必要があります。それぞれにある場所のインデックスを保持します(playerinputindex、potentyactionsindex、denetelementindex)。
一致を見つけた場合は、PlayerInputIndexをincrement incentingelementに照合しなくなるまで、設定(ISOPTIONALなど)を確認し、次のDenteElementIndexに移動して比較を再度実行します。最終的には、プレーヤーの入力または文の要素のいずれかの最後に到達します。
「Isoptional」であるPenteElementsがある場合に複雑さが追加されるため、既存のものと一致するはずではないが、「どのオブジェクトが必要なオブジェクトを表示するかは想定されていないタイプオブジェクトの文のセントレメントがある」をチェックする必要があります。たべる?"メッセージ。また、オブジェクトには、動詞とは異なり、因数分解のプレフィックス/形容詞/名詞などの追加の一致パラメーターがあります。
また、このシステムには、アクションを行うことができるすべてのアクションに新しいクラスが必要です。各アクションには、「参照されたキャラクターは生きていますか?」など、実行する前に通過する必要があるカスタム「制限」があります。