このセクションでは、Mastermind というゲームを JavaScript で実装します。このゲーム開発では、これまでに説明した多くの概念がカバーされます。関数を定義し、関数に引数を渡し、変数を使用し、ループと if ステートメントを使用します。 IIFE (即時呼び出し関数式) として知られる、関数に関する別の概念を簡単に説明します。コマンドライン経由でユーザー入力を取得する方法についても説明します。現時点では、これは単なるコンソール アプリケーションです。
Python のマスターマインドで同様の実装を参照できます
マスターマインドは色を使用するシンプルなボード ゲームですが、代わりに数字を使用します。
概要: バーの後ろには、1 人のプレイヤーが配置した 4 つの色があります。他のプレイヤーは最初のプレイヤーの色を見ることができません。最初のプレイヤーの色はコードメーカーと呼ばれ、他のプレイヤーの色はコードブレイカーと呼ばれます。コード ブレーカーは、コード作成者の推測を合計 2 回から 12 回試行します。試行回数は偶数である必要があります。
PC (またはプロジェクトを配置する場所) 上に mastermind というフォルダーを作成し、mastermind で npm init -y (コマンド ラインで) を使用してノード プロジェクトを初期化します。 。私は Linux マシンを使用しているので、これがプロジェクトをセットアップする方法です。
このゲームの開始 (エントリ) ポイントは アプリ という関数になります。 App という関数を作成し、console.log("App") を追加しましょう。次に、App() を呼び出し、ノード app.js でコードを実行します。コードを実行するようにとは言いませんが、コードを書きながら実行する必要があります。これは私の app.js ファイルの現在の内容です。
console.log("Mastermind"); function App() { console.log("App"); } App();
ゲーム開始時
コード作成用に乱数を生成する関数を実装して、コード作成者にランダムな値を設定しましょう。
まず、乱数を生成する方法が必要です。 app.js のコードを妨げないように、scratch_pad.js という名前の別のファイルを作成し、このファイルで実験してみましょう。
JavaScript には、Math.random() を呼び出して乱数を生成する簡単な方法があります。スクラッチ パッドで、ループ構造を使用して 4 つの乱数を記録しましょう。
console.log("Mastermind"); function App() { console.log("App"); } App();
私たちが必要とするのは、小数ではなく、0、1、2、...、9 のような整数 (数値) です。 Math.random() から返された値を 10 で乗算すると、x.something が得られ、x は 1,2,3,...,9 になります。これらの実験はすべてスクラッチパッド上で行われることに注意してください。ぜひ試してみてください。
必要なのは、ドットの前の数字、つまり整数部分です。数値を文字列に変換し、それを「.」で分割するコードを作成できます。そして最初の要素を取得します。ただし、フロアと呼ばれる機能があり、それを使用できます。
for (let i = 0; i < 4; i++) { console.log(Math.random()); } // 0.10037268097853191 // 0.20981624777230534 // 0.47828165742292583 // 0.8160883929470153
for (let i = 0; i < 4; i++) { console.log(Math.floor(Math.random() * 10)); } // 4 // 7 // 3 // 4
この時点で、app.js に戻り、コード メーカー用の乱数を生成する上記の関数を追加できます。 App 関数の上に配置します。
要約すると、使用される色の数は 4 です。したがって、コード メーカー用に 4 つの数値を生成する必要があります。重複が許可されているかどうかも処理する必要があります。スクラッチパッドに戻ります。
関数、if ステートメントと else ステートメント、for ループと while ループなどがあります。これらの構造はすべてブロックまたは本体を持っています。これらのブロック内で初期化された変数は、ブロック内では使用できますが、ブロック外では使用できません。これは変数のスコープとして知られています。したがって、変数はグローバル スコープ内に存在できます。これは、その変数がどこでも使用または評価できることを意味します。ブロック内で変数を宣言するとき。変数は内部的になるか、そのスコープ内で制限されます。これをスクラッチパッドで実行します。
console.log("Mastermind"); function App() { console.log("App"); } App();
for (let i = 0; i < 4; i++) { console.log(Math.random()); } // 0.10037268097853191 // 0.20981624777230534 // 0.47828165742292583 // 0.8160883929470153
この時点で、スコープについての考え方に注目してもらいたいと思います。
for (let i = 0; i < 4; i++) { console.log(Math.floor(Math.random() * 10)); } // 4 // 7 // 3 // 4
function generateRandomNumbersBetween(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); } for (let i = 0; i < 4; i++) { console.log(generateRandomNumbersBetween(0, 9)); }
const HP = 100; if (true) { console.log("IF BLOCK::", HP); } console.log("End::", HP); // IF BLOCK:: 100 // End:: 100
ユーザー入力を取得するこのアプローチには問題はありません。コールバック関数を使用する必要があるだけで、入力された入力を readlineOInstance.question.
何を考えていますか? 「スクラッチパッド」で試してみてください。 readlineOInstance.question の外側のスコープで変数を宣言し、それに入力された入力を割り当てることを考えている場合、それは良いアプローチですが...それでも試してみてください。
約束という概念を覚えていますか?ここでpromiseを使用して入力を解決できます。ただし、プロセス全体を関数でラップする必要があります。 readlineOInstance.question にはいくつかの部分がありますが、question(query: string, callback: (answer: string) => void に似たヘッダーがあります。クエリはユーザーへのクエリ (またはプロンプト) であり、コールバックはユーザーへのクエリ (またはプロンプト) です。入力コレクションを処理します。同じ関数を後でどこかで再利用する可能性があるため、クエリを引数として渡します。
console.log("Mastermind"); function App() { console.log("App"); } App();
for (let i = 0; i < 4; i++) { console.log(Math.random()); } // 0.10037268097853191 // 0.20981624777230534 // 0.47828165742292583 // 0.8160883929470153
for (let i = 0; i < 4; i++) { console.log(Math.floor(Math.random() * 10)); } // 4 // 7 // 3 // 4
function generateRandomNumbersBetween(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); } for (let i = 0; i < 4; i++) { console.log(generateRandomNumbersBetween(0, 9)); }
app.js を実行し、操作します。これは、インタラクション中の同様の出力です。
const HP = 100; if (true) { console.log("IF BLOCK::", HP); } console.log("End::", HP); // IF BLOCK:: 100 // End:: 100
IF BLOCK:: 100 /home/Projects/mastermind/scratch_pad.js:8 console.log(x) ^ ReferenceError: x is not defined at Object.<anonymous> (/home/Projects/mastermind/scratch_pad.js:8:13) at Module._compile (node:internal/modules/cjs/loader:1469:14) at Module._extensions..js (node:internal/modules/cjs/loader:1548:10) at Module.load (node:internal/modules/cjs/loader:1288:32) at Module._load (node:internal/modules/cjs/loader:1104:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12) at node:internal/main/run_main_module:28:49 Node.js v20.17.0
// a global code maker that is accessible inside any other scope let CODE_MAKER = []; function generateRandomNumbersBetween(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); } function generateCodeMaker(isDuplicatesAllowed = false) { let counter = 0; while (counter < 4) { let code = generateRandomNumbersBetween(0, 9); if (isDuplicatesAllowed) { CODE_MAKER.push(code); counter += 1; } else if (!CODE_MAKER.includes(code)) { CODE_MAKER.push(code); counter += 1; } } } console.log(CODE_MAKER); generateCodeMaker(true); console.log(CODE_MAKER); // reset the code maker CODE_MAKER = []; generateCodeMaker(false); console.log(CODE_MAKER); // [] // [ 6, 6, 0, 9 ] // [ 2, 5, 0, 8 ]
これで、HINTS 関数と CompareCode 関数を app.js に追加できます。 App 関数の上で app.js を実行するのに最適な時期です。
コード メーカーとコード ブレーカーを比較する関数を実装したので、これをループに入れてラウンド (ラウンド = ゲームをプレイする回数) を考慮できるようになります。したがって、ラウンド数が 6 の場合、ゲームは 6 回プレイされますが、ユーザーがすべてのコードを正しく推測したとき、つまりヒントの値がすべて 0 になったとき、ゲームを終了する必要があります。したがって、HINTS 内の 0 の数を数えて 4 になった場合、ゲームを終了してユーザーが勝ったと言えます。
console.log("Mastermind"); function App() { console.log("App"); } App();
for (let i = 0; i < 4; i++) { console.log(Math.random()); } // 0.10037268097853191 // 0.20981624777230534 // 0.47828165742292583 // 0.8160883929470153
for (let i = 0; i < 4; i++) { console.log(Math.floor(Math.random() * 10)); } // 4 // 7 // 3 // 4
function generateRandomNumbersBetween(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); } for (let i = 0; i < 4; i++) { console.log(generateRandomNumbersBetween(0, 9)); }
これまでの苦労を楽しむことができそうです。約130行あります。何個持っていますか?
これは完全なコードです
const HP = 100; if (true) { console.log("IF BLOCK::", HP); } console.log("End::", HP); // IF BLOCK:: 100 // End:: 100
これは単純なコンソール/ターミナル/テキストベースのアプリですが、できることはまだたくさんあります。
IF BLOCK:: 100 /home/Projects/mastermind/scratch_pad.js:8 console.log(x) ^ ReferenceError: x is not defined at Object.<anonymous> (/home/Projects/mastermind/scratch_pad.js:8:13) at Module._compile (node:internal/modules/cjs/loader:1469:14) at Module._extensions..js (node:internal/modules/cjs/loader:1548:10) at Module.load (node:internal/modules/cjs/loader:1288:32) at Module._load (node:internal/modules/cjs/loader:1104:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12) at node:internal/main/run_main_module:28:49 Node.js v20.17.0
// a global code maker that is accessible inside any other scope let CODE_MAKER = []; function generateRandomNumbersBetween(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); } function generateCodeMaker(isDuplicatesAllowed = false) { let counter = 0; while (counter < 4) { let code = generateRandomNumbersBetween(0, 9); if (isDuplicatesAllowed) { CODE_MAKER.push(code); counter += 1; } else if (!CODE_MAKER.includes(code)) { CODE_MAKER.push(code); counter += 1; } } } console.log(CODE_MAKER); generateCodeMaker(true); console.log(CODE_MAKER); // reset the code maker CODE_MAKER = []; generateCodeMaker(false); console.log(CODE_MAKER); // [] // [ 6, 6, 0, 9 ] // [ 2, 5, 0, 8 ]
// a global code maker that is accessible inside any other scope let CODE_MAKER = []; function generateRandomNumbersBetween(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); } function generateCodeMaker(isDuplicatesAllowed = false) { let counter = 0; let codeMaker = []; while (counter < 4) { let code = generateRandomNumbersBetween(0, 9); if (isDuplicatesAllowed) { codeMaker.push(code); counter += 1; } else if (!codeMaker.includes(code)) { codeMaker.push(code); counter += 1; } } return codeMaker; } console.log(CODE_MAKER); CODE_MAKER = generateCodeMaker(true); console.log(CODE_MAKER); CODE_MAKER = generateCodeMaker(false); console.log(CODE_MAKER); // [] // [ 6, 6, 0, 9 ] // [ 2, 5, 0, 8 ]
私たちはこのプロジェクトで学んだすべてを活用しましたが、さらに多くのことがあります。いくつかの関数をグループ化してエクスポートできると述べました。このために、JavaScript でインポートおよびエクスポートする方法について説明します。役立つと思われる別のプロジェクトを提供します。これでマスターマインド ゲームは終了です。リファクタリングが必要な箇所がたくさんあるので、リファクタリングも行ってください。幸運を祈ります...
const readline = require("readline"); const readlineOInstance = readline.createInterface({ input: process.stdin, output: process.stdout, }); readlineOInstance.question("Enter code maker: ", (userInput) => { console.clear(); console.log(`INPUT: ${userInput}`); readlineOInstance.close(); });
以上がJavaScript Essentials: JavaScript のマスターマインドの一部)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。