DQXでハロウィンの季節イベントが始まりましたね~。
イベントクエストを受ける際、白チャットで「トリック・オア・トリート」と挨拶することが求められます。
他の季節イベントでもそのイベントに応じた「挨拶」を求められるものがありますが、毎回奇抜な発言で突破しているフレンドのあんよさん。
今回も天才的な発言で無事、突破したようですw
「たどりつく迄お寿司、あと一貫借りといて」
という白チャに対し、ジャックが「!」と見事に反応していますw
いや、ウソみたいな話なんですけどホントに通りますw
一体なぜ、こんなチャットに反応するのでしょう?
その仕組みについて、考察してみました。
キーワードと入力の揺らぎ
まず大前提として、この挨拶の入力はゲーム進行上、大した意味はありません。
なので運営としてはどんなプレイヤーでも、迷わず、悩まず、詰まらず、簡単に答えられるように作らなきゃいけません。
開発側の視点からこれを見ると、ちょっと面倒な問題があります。
今回の正解のキーワードは「トリック・オア・トリート」だと思われますが、ですが、白チャを入力するプレイヤーが多ければ多いほど、この入力される白チャのキーワードに揺らぎが発生します。
あるプレイヤーは、「トリックオアトリート」と、「・」がない状態で発言するかもしれません。
また、カタカナに変換せずにひらがなのまま言う方もいるだろうし、ひらがなとカタカナがごちゃ混ぜになったまま発言いる方もいるかもしれません。
また、うっかり変なところに濁点がついてしまったり、「ッ」が誤って「ツ」と入力されていたなどのタイプミスもあり得ます。
開発としてはこれらを厳密に不正解と判定してやり直させるのが一番楽なんですけど、プレイヤーとしてはこんなどうでもいいところに厳密に正解するまで何度も突き返されていたのでは面倒な事この上ありませんw
なのでこうした入力の揺らぎに対して、割と緩く対応できる仕組みが組み込まれているっぽいんですよね。
その仕組みがどう作られているのか?
という考察になりますが、ここからの内容はただの想像であり、実際のものとは一ミリもかすっていないかもしれませんので、あらかじめご承知おきくださいねw
揺らぎ対策1、使用する文字
プレイヤーの入力揺らぎにどう対応するのか。
一番単純な手段は、想定される揺らぎのパターン全てを正解キーワードとして設定する、です。
ですが、総数何パターンになるのか考えてみれば、とてもでないですけどやってられませんw
なのでプログラミングによって判断させる仕組みを作ります。
まずは正解キーワードで使われる各1文字に対して、何処までズレてても正解と判定させるのかを決めましょう。
正解キーワードに最初に出てくる文字は「ト」ですよね。
入力パターンとして想定されるのは、ひらがなの「と」、カタカナの「ト」、または半角カタカナ「ト」の3種です。
さらに何らかのタイプミスも想定して「どド」も正解としちゃいましょう。
半角カタカナへの濁点については「ト」と「゙」がそれぞれ個別の文字で、2文字となるので入れません。
これをキーワード「トリックオアトリト」全文字に対して設定しちゃいます。
「トリート」の所の伸ばし棒は、省いても正解できるようにキーワードから外しちゃいます。
一覧にするとこんな感じ~。
'[と|ト|ト|ど|ド]',
'[り|リ|リ]',
'[っ|ッ|ッ|つ|ツ|ツ|づ|ヅ]',
'[く|ク|ク|ぐ|グ]',
'[お|オ|オ|ぉ|ォ|ォ]',
'[あ|ア|ア|ぁ|ァ|ァ]',
'[と|ト|ト|ど|ド]',
'[り|リ|リ]',
'[と|ト|ト|ど|ド]',
JavaScript揺らぎ対策2、誤タイプ対策
想定される入力揺らぎとして、慌ててタイピングしたときに出てしまう、誤タイプの可能性があります。
キーボードで「ト」と打とうとして、キーボードの「T」「O」を押す際に、隣のpのキーにも指が当たって「とp」とかになってしまうアレですw
「とpリックオアトリート」みたいになってしまってやり直し・・・、なんてのも面倒じゃないですか!
なのでここもゆるく判定したいと判断されたのではないかな~。
どう対策すればいいのでしょう。
「とpリックオアトリート」と入力された白チャの中から、「とリックオアトリト」という正解キーワードだけを抜き出したい。つまりは「p」と「-」はお邪魔なので消し去りたい。
というわけで消しちゃいましょう。
お邪魔文字はどんなパターンで発生するかなんて考えていたらきりがありません。
なので先程の揺らぎ対策1で設定した使用する文字以外の文字を、全部綺麗さっぱりそぎ落としちゃいます!
その後で生き残った文字とキーワードの文字を照会すれば完成!
そうした工程をJavascriptで書いてみたのがこちらです。
var input = 'たどりつく迄お寿司、あと一貫借りといて';
var keyword = [
'[と|ト|ト|ど|ド]',
'[り|リ|リ]',
'[っ|ッ|ッ|つ|ツ|ツ|づ|ヅ]',
'[く|ク|ク|ぐ|グ]',
'[お|オ|オ|ぉ|ォ|ォ]',
'[あ|ア|ア|ぁ|ァ|ァ]',
'[と|ト|ト|ど|ド]',
'[り|リ|リ]',
'[と|ト|ト|ど|ド]',
];
// 動的な正規表現を構築
const dynamicRegex = new RegExp(keyword.join(''), 'i');
// 正規表現で使用されている文字のセットを作成
const validChars = new Set(keyword.join('').replace(/[\[\]|]/g, ''));
// inputから無効な文字を削除
const cleanedInput = input.split('').filter(char => validChars.has(char)).join('');
// クリーンされた入力を一文字ずつ正規表現で照会
let matchedChars = false;
for (let i = 0; i < keyword.length; i++) {
const partialRegex = new RegExp(keyword[i], 'i');
const char = cleanedInput.slice(i,i + 1);
var match = char.match(partialRegex);
if (match != null && match[0] != '') {
matchedChars = true;
} else {
matchedChars = false;
break;
}
console.log(`入力 "${cleaneInput}" はキーワードにマッチ${res ? 'します' : 'しません'}`);
JavaScriptこれで一応、実際のゲーム上のものと似たような挙動が実現します。
きちんとデバックとかはしてないのでバグとかあるかもしれませんけども‥w
その辺の事は緩いお遊びなのでご容赦をw
実装してみた
上のコードを実装してみたので、気が向いたら遊んでみてくださいw
お礼
最後になりますが、あんよさんにこのネタをブログ記事にしてもいいかな~?
とお聞きしたところ、快くお許しいただきました。
あんよさん、ありがとうございました~!
コメント