Maison > Article > interface Web > JavaScript Essentials : partie Mastermind en Javascript)
Dans cette section, nous allons implémenter un jeu appelé Mastermind en JavaScript. Ce développement de jeu couvrirait un grand nombre des concepts dont nous avons discuté jusqu'à présent. Nous définirons des fonctions, leur passerons des arguments, utiliserons des variables et utiliserons des boucles et des instructions if. Nous examinerions brièvement un autre concept autour des fonctions, connu sous le nom d'IIFE, Immédiatement Invoked Function Expression. Nous verrons également comment prendre en compte les entrées de l'utilisateur via la ligne de commande. À ce stade, il ne s’agit que d’applications console.
Vous pouvez référencer une implémentation similaire ici, Master mind in python
Mastermind est un jeu de société simple qui utilise des couleurs mais nous utiliserions plutôt des chiffres.
Résumé : Derrière une barre se trouvent quatre couleurs proposées par un seul joueur. L'autre joueur ne peut pas voir les couleurs du premier joueur. Les couleurs du premier joueur sont appelées le créateur de code et les couleurs de l'autre joueur sont le briseur de code. Le déchiffreur de code a, inclusivement, entre 2 et 12 tentatives pour deviner les créateurs du code. Le nombre de tentatives doit être pair.
Créez un dossier appelé mastermind sur votre PC (ou là où vous mettez vos projets) et dans mastermind, initialisez un projet de nœud en utilisant npm init -y (sur la ligne de commande) . Je suis sur une machine Linux donc c'est ainsi que je vais mettre en place mon projet.
Le point de départ (d'entrée) de ce jeu sera dans App, une fonction. Créons une fonction appelée App et ajoutons console.log("App"). On peut alors appeler App() et exécuter le code avec le nœud app.js. Je ne vous dirai pas d'exécuter votre code, mais c'est quelque chose que vous devriez faire pendant que vous codez. Ceci est le contenu actuel de mon fichier app.js.
console.log("Mastermind"); function App() { console.log("App"); } App();
Quand le jeu commence
Implémentons une fonction pour générer des nombres aléatoires pour la création du code, définissant ainsi des valeurs aléatoires pour le créateur de code.
Tout d’abord, nous avons besoin d’un moyen de générer des nombres aléatoires. Pour ne pas interférer avec le code dans app.js, créons un autre fichier appelé scratch_pad.js et dans ce fichier nous expérimentons.
JavaScript propose un moyen simple de générer des nombres aléatoires en appelant Math.random(). Dans le bloc-notes, enregistrons 4 nombres aléatoires à l'aide d'une construction en boucle.
console.log("Mastermind"); function App() { console.log("App"); } App();
ce que nous voulons, ce sont des entiers (des nombres comme) 0, 1, 2, ..., 9 et non des décimaux. Nous pouvons multiplier la valeur renvoyée par Math.random() par 10 et nous aurions x.something où x sera désormais dans 1,2,3,...,9. N'oubliez pas que ces expériences sont toutes réalisées sur le bloc-notes. Essayez-le.
Ce que nous voulons, c'est un nombre avant le point, la partie entière du nombre. Nous pouvons écrire du code pour convertir le nombre en chaîne, puis le diviser par le "." et obtenez le premier élément. Cependant, il existe une fonctionnalité pour cela appelée étage que nous pouvons utiliser.
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
À ce stade, nous pouvons maintenant retourner dans notre app.js et ajouter la fonction ci-dessus pour générer les nombres aléatoires pour le créateur de code. Placez-le au-dessus de la fonction App.
D'après le résumé, le nombre de couleurs utilisées est de 4. Nous devons donc générer 4 nombres pour le créateur de code. Nous devons également déterminer si les doublons sont autorisés. Retour au bloc-notes.
Nous avons des fonctions, des instructions if et else, les boucles for et while, etc. Ces constructions ont toutes un bloc ou un corps. Les variables initialisées dans ces blocs peuvent être utilisées à l'intérieur du bloc et non à l'extérieur de celui-ci. C'est ce qu'on appelle la portée d'une variable. Une variable peut donc exister dans la portée globale, ce qui signifie que cette variable peut être utilisée ou évaluée partout. Quand on déclare une variable dans un bloc. La variable devient interne ou limitée dans cette portée. Exécutez ceci dans le bloc-notes.
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
À ce stade, je souhaite attirer votre attention sur l'idée des scopes.
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
Il n'y a aucun problème avec cette approche consistant à prendre en compte les commentaires des utilisateurs. C'est juste que nous devons utiliser une fonction de rappel et il n'y a aucun moyen de transmettre l'entrée saisie à la portée externe de la fonction de rappel de readlineOInstance.question.
A quoi penses-tu ? Essayez-le dans le "bloc-notes". Si vous envisagez de déclarer une variable dans la portée externe de readlineOInstance.question pour lui attribuer l'entrée saisie, alors c'est une bonne approche mais... Essayez-la quand même.
Vous souvenez-vous du concept de Promesses ? Nous pouvons utiliser la promesse ici et résoudre l'entrée. Cependant, nous devons mettre en pratique l’ensemble du processus. Il y a quelques parties de readlineOInstance.question qui a un en-tête similaire à question(query: string, callback: (answer: string) => void. La requête est la requête (ou l'invite) adressée à l'utilisateur et le rappel indique comment nous gérons la collection d'entrées. Puisque nous pourrions réutiliser la même fonction quelque part plus tard, nous passerions la requête en argument.
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)); }
Exécutez app.js et interagissez avec lui. Il s'agit d'un résultat similaire lors de l'interaction.
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 ]
Nous pouvons maintenant ajouter les fonctions HINTS et compareCode au app.js. C'est le moment idéal pour exécuter votre app.js, au-dessus de la fonction App.
Maintenant que nous avons implémenté une fonction pour comparer le créateur de code et le briseur de code, nous pouvons maintenant mettre cela en boucle pour tenir compte des tours (tours = nombre de fois pour jouer au jeu). Donc, si le nombre de tours est de 6, alors le jeu serait joué 6 fois mais nous devrons terminer le jeu lorsque l'utilisateur devine correctement tous les codes, c'est-à-dire lorsque les valeurs dans les HINTS sont toutes des 0. Ainsi, lorsque nous comptons le nombre de 0 dans HINTS et qu'il est 4, nous pouvons terminer le jeu et dire que l'utilisateur a gagné.
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)); }
Je suppose que nous pouvons profiter de notre travail acharné jusqu’à présent. J'ai environ 130 lignes. Combien en avez-vous ?
Voici le code complet
const HP = 100; if (true) { console.log("IF BLOCK::", HP); } console.log("End::", HP); // IF BLOCK:: 100 // End:: 100
Même s'il s'agit d'une simple application console/terminal/textuelle, nous pouvons faire plus à ce sujet.
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 ]
Nous avons utilisé tout ce que nous avons appris dans ce projet et il y a bien plus encore. J'ai mentionné que nous pourrions regrouper certaines fonctions et les exporter. Pour cela, nous verrons comment importer et exporter en Javascript. Je vais vous proposer un autre projet qui, je pense, vous sera utile. C'est la fin du jeu du cerveau et j'espère que vous ferez également du refactoring car il y a beaucoup d'endroits qui doivent être refactorisés. Bonne chance...
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(); });
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!