Arvauspeli-Konsolisovelluksen Rakentaminen
Pyyhkäise näyttääksesi valikon
Tässä luvussa pääset kehittämään konsolisovellustaitojasi luomalla jännittävän Arvaa luku -pelin. Tämä interaktiivinen peli haastaa pelaajat käyttämään intuitiotaan arvaamalla satunnaisesti valitun luvun ennalta määritellyltä alueelta. Samalla tutustutaan keskeisiin käsitteisiin, kuten
- Satunnaislukujen generointi;
- Syötteen validointi;
- Käyttäjän vuorovaikutus;
- Pelitulosten tallentaminen tiedostoon.
Haaste
Kuvittele sovellus, joka lupaa jännitystä ja arvoituksellisuutta. Pelaajat kutsutaan arvaamaan salaperäisesti valittu luku ennalta määritellyltä alueelta. Sovellus antaa välitöntä palautetta jokaisesta arvauksesta ja pitää tarkkaa kirjaa yrityksistä.
Tämä käytännön esimerkki tarjoaa mahdollisuuden hioa taitoja CLI-sovellusten rakentamisessa ja esittelee interaktiivisten ohjelmien toteutuksen taidon.
Lopputulos
Katso, miten sovellus toimii! Alla oleva GIF havainnollistaa jännittävää Arvaa luku -peliä, jonka tulet rakentamaan:
Arvauspeli-konsolisovelluksen rakentaminen
Edessäsi on kaksi polkua. Ensimmäinen vaihtoehto kutsuu sinut aloittamaan matkan ilman apua, kun taas toinen tarjoaa hyödyllisen oppaan onnistumisesi varmistamiseksi. Valitsitpa rohkean hyppäyksen tai rakenteellisen ohjeen seuraamisen, edessäsi on kiehtova kokemus, jonka lopputuloksena on toimiva ja mukaansatempaava konsolisovellus.
Pääsuunnitelma
- Vaihe 1: Alustus ja valmistelut;
- Vaihe 2: Pelin parametrien määrittely;
- Vaihe 3: Apufunktioiden määrittely;
- Vaihe 4: Pelilogiikka;
- Vaihe 5: Pelituloksen tallennus;
- Vaihe 6: Pelin käynnistys;
- Yhteenveto;
- Koko sovelluksen koodi.
Vaihe 1: Alustus ja valmistelut
Valmistele pohja luomalla uusi hakemisto ja tiedosto nimeltä app.js. Tässä tiedostossa otetaan käyttöön tarvittavat moduulit:
const readline = require('readline');
const fs = require('fs').promises;
Luo Readline-rajapinta:
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
-
readline: tarjoaa käyttöliittymän syötteen lukemiseen ja tulosteen kirjoittamiseen konsoliin; -
readline.createInterface({ ... }): luoreadline.Interface-luokan instanssin. Ottaa vastaan olion, jossa oninput- jaoutput-ominaisuudet; -
input: process.stdin: asettaa syötevirraksiprocess.stdin, jolloin ohjelma voi lukea käyttäjän syötteen näppäimistöltä; -
output: process.stdout: asettaa tulostevirraksiprocess.stdout, jolloin ohjelma voi näyttää tekstiä konsolissa.
Selitys: Tuodaan tarvittavat moduulit: readline käyttäjän kanssa vuorovaikutukseen ja fs.promises tiedostojen käsittelyyn. Luodaan Readline-rajapinta nimeltä rl syötteen ja tulosteen hallintaan.
Vaihe 2: Pelin parametrien määrittely
Aseta pienin ja suurin numero:
const minNumber = 1;
const maxNumber = 100;
Salaisen numeron generointi:
const secretNumber =
Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
-
Math.random(): generoi satunnaisen liukuluvun väliltä0(sisällytetty) ja1(ei sisällytetty); -
maxNumber - minNumber + 1: laskee mahdollisten lukujen vaihteluvälin. Lisäämällä1varmistetaan, että sekäminNumberettämaxNumbersisältyvät vaihteluväliin; -
Math.random() * (maxNumber - minNumber + 1): generoi satunnaisen luvun väliltä0ja laskettu vaihteluväli; -
Math.floor(...): pyöristää generoidun liukuluvun alaspäin lähimpään kokonaislukuun, jolloin tulos on halutulla vaihteluvälillä oleva kokonaisluku; -
... + minNumber: siirtää generoidun luvun niin, että vaihteluväli alkaa arvostaminNumbereikä0.
Yritysten laskurin alustaminen:
let attempts = 0;
Selitys: Määritellään lukujen vaihteluväli (minNumber ja maxNumber), jonka sisällä salainen numero arvotaan. Salainen numero luodaan satunnaisesti käyttäen Math.random()-funktiota ja tallennetaan muuttujaan secretNumber. Muuttuja attempts alustetaan käyttäjän yritysten seuraamiseksi.
Vaihe 3: Apufunktioiden määrittely
Varustaudu apufunktiolla virheettömään validointiin:
function isValidGuess(guess) {
return !isNaN(guess)
&& guess >= minNumber
&& guess <= maxNumber;
}
-
!isNaN(guess): tarkistaa, onkoguesskelvollinen numero.isNaN()-funktio palauttaa arvonfalsekelvollisille numeroille, ja!-operaattori kääntää sen arvoksitrue; -
guess >= minNumber: varmistaa, ettäguesson suurempi tai yhtä suuri kuinminNumber, jolloin arvaus ei ole sallitun alueen alapuolella; -
guess <= maxNumber: varmistaa, ettäguesson pienempi tai yhtä suuri kuinmaxNumber, jolloin arvaus ei ole sallitun alueen yläpuolella; -
&&: yhdistää kaikki ehdot loogisella JA-operaattorilla. Kaikkien ehtojen tulee ollatrue, jotta koko lauseke palauttaa arvontrue.
Selitys: isValidGuess-funktio tarkistaa, onko käyttäjän arvaus kelvollinen numero määritellyllä välillä (minNumber–maxNumber).
Vaihe 4: Pelilogiikka
Pelin ydintoiminnallisuus playGame-funktion kautta:
function playGame() {
rl.question(`Guess a number between ${minNumber} and ${maxNumber}: `, guess => {
if (isValidGuess(guess)) {
attempts++;
const guessNumber = parseInt(guess);
if (guessNumber === secretNumber) {
console.log(`Congratulations! You guessed the number in ${attempts} attempts.`);
saveGameResult(`Player won in ${attempts} attempts.`);
rl.close();
} else if (guessNumber < secretNumber) {
console.log('Try higher.');
playGame();
} else {
console.log('Try lower.');
playGame();
}
} else {
console.log('Please enter a valid number within the specified range.');
playGame();
}
});
}
-
rl.question(\Guess a number between ${minNumber} and ${maxNumber}: `, guess => { ... }): prompts the user to enter a number within the specified range. The user's input is passed to the callback function as theguess`-argumenttina; -
if (isValidGuess(guess)) { ... }: tarkistaa, onko syötetty arvo kelvollinen arvaus käyttämälläisValidGuess()-funktiota; -
attempts++;: kasvattaaattempts-laskuria, joka seuraa pelaajan arvausten määrää; -
const guessNumber = parseInt(guess);: muuntaa käyttäjän syötteen merkkijonosta kokonaisluvuksiparseInt()-funktion avulla; -
if (guessNumber === secretNumber) { ... }: tarkistaa, vastaako pelaajan arvaus salaisuutta numeroa. Jos vastaus on oikea, peli näyttää onnistumisviestin, tallentaa tuloksen, sulkeereadline-rajapinnan ja lopettaa pelin; -
else if (guessNumber < secretNumber) { ... }: ilmoittaa pelaajalle, että salainen numero on suurempi, ja kutsuuplayGame()-funktiota uudelleen pelin jatkamiseksi; -
else { ... }: ilmoittaa pelaajalle, että salainen numero on pienempi, ja kutsuuplayGame()-funktiota uudelleen pelin jatkamiseksi; -
else { ... }(tarkistuksen jälkeen): käsittelee virheellisen syötteen pyytämällä pelaajaa syöttämään kelvollisen numeron sallitulla välillä ja kutsuu sittenplayGame()-funktiota uudelleen.
Selitys: playGame-funktio muodostaa pelin ydinsilmukan. Se käyttää rl.question-metodia pyytääkseen käyttäjältä arvausta. Jos arvaus on kelvollinen, funktio tarkistaa, vastaako arvaus salaisuusnumeroa. Muussa tapauksessa se antaa palautetta käyttäjälle ja jatkaa pelisilmukkaa rekursiivisesti.
Vaihe 5: Pelituloksen tallentaminen
Toteuta logiikka, jolla käyttäjän pelisaavutukset tallennetaan tiedostoon game_results.txt.
async function saveGameResult(result) {
try {
await fs.appendFile('game_results.txt', `${result}\n`);
console.log('Game result saved.');
} catch (err) {
console.log('Failed to save game result.');
}
}
-
async function saveGameResult(result) { ... }: määrittelee asynkronisen funktion nimeltäsaveGameResult(), joka ottaa vastaan parametrinresultja mahdollistaaawait-avainsanan käytön funktion sisällä; -
try { ... } catch (err) { ... }: käsittelee mahdolliset virheet, joita voi esiintyä asynkronisen tiedosto-operaation aikana; -
await fs.appendFile('game_results.txt', \${result}\n`);: appends the providedresultfollowed by a newline character to thegame_results.txtfile. Theawait`-avainsana pysäyttää suorituksen, kunnes tiedosto-operaatio on onnistuneesti suoritettu; -
console.log('Game result saved.');: näyttää vahvistusviestin, kun pelitulos on onnistuneesti kirjoitettu tiedostoon; -
console.log('Failed to save game result.');: näyttää virheilmoituksen, jos tiedosto-operaatio epäonnistuu ja poikkeus jää kiinnicatch-lohkoon.
Selitys: saveGameResult-funktio käyttää fs.promises-kirjastoa lisätäkseen pelituloksen tiedostoon nimeltä game_results.txt. Funktio antaa palautetta siitä, onnistuiko tuloksen tallennus vai ei.
Vaihe 6: Pelin käynnistäminen
Luo tervetuloviesti ja käynnistä peli:
console.log('Welcome to the Guess the Number game!');
playGame();
Selitys: Näytetään tervetuloviesti ja käynnistetään pelisilmukka kutsumalla playGame-funktiota.
Sovelluksen koko koodi
const readline = require("readline");
const fs = require("fs").promises;
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const minNumber = 1;
const maxNumber = 100;
const secretNumber =
Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
let attempts = 0;
function isValidGuess(guess) {
return !isNaN(guess) && guess >= minNumber && guess <= maxNumber;
}
function playGame() {
rl.question(
`Guess a number between ${minNumber} and ${maxNumber}: `,
(guess) => {
if (isValidGuess(guess)) {
attempts++;
const guessNumber = parseInt(guess);
if (guessNumber === secretNumber) {
console.log(
`Congratulations! You guessed the number in ${attempts} attempts.`
);
saveGameResult(`Player won in ${attempts} attempts.`);
rl.close();
} else if (guessNumber < secretNumber) {
console.log("Try higher.");
playGame();
} else {
console.log("Try lower.");
playGame();
}
} else {
console.log("Please enter a valid number within the specified range.");
playGame();
}
}
);
}
async function saveGameResult(result) {
try {
await fs.appendFile("game_results.txt", `${result}\n`);
console.log("Game result saved.");
} catch (err) {
console.log("Failed to save game result.");
}
}
console.log("Welcome to the Guess the Number game!");
playGame();
-
Rivit 1-2: tuodaan sisäänrakennettu
readline-moduuli sekäfs-moduulinpromises-rajapinta asynkronisia tiedostotoimintoja varten; -
Rivit 4-7: luodaan readline-rajapinta nimeltä
rlkäyttäjän syötteen lukemista ja tulosteen näyttämistä varten konsolissa; -
Rivit 9-10: määritellään arvattavan luvun pienin ja suurin arvo;
-
Rivit 12-13: arvotaan satunnainen salainen luku määritellyltä väliltä käyttäen
Math.random()-funktiota; -
Rivi 14: alustetaan
attempts-laskuri seuraamaan pelaajan arvausten määrää; -
Rivit 16-18: määritellään
isValidGuess()-funktio, joka tarkistaa, että syötetty arvo on sallituilla rajoilla oleva numero; -
Rivit 20-47: määritellään rekursiivinen
playGame()-funktio, joka:- pyytää pelaajaa arvaamaan luvun;
- tarkistaa syötetyn arvon;
- tarkistaa, vastaako arvaus salaista lukua;
- antaa palautetta, jos arvaus on liian suuri tai pieni;
- jatkaa peliä kutsumalla itseään uudelleen tarvittaessa;
- tallentaa tuloksen ja lopettaa pelin, kun oikea luku on arvattu;
-
Rivit 49-56: määritellään asynkroninen
saveGameResult()-funktio, joka tallentaa pelin tuloksen tiedostoongame_results.txtja käsittelee mahdolliset virheet; -
Rivi 58: näyttää tervetuloviestin pelaajalle;
-
Rivi 59: käynnistää pelin kutsumalla
playGame()-funktiota.
Yhteenveto
Tämä ohjelma toteuttaa numeronarvauspelin. Pelaaja yrittää arvata satunnaisesti arvotun luvun määritellyltä väliltä. Peli antaa palautetta jokaisen arvauksen jälkeen, seuraa arvausten määrää ja tallentaa onnistuneet tulokset tekstitiedostoon asynkronisesti.
Kiitos palautteestasi!
Kysy tekoälyä
Kysy tekoälyä
Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme