From 5099fa7a21483ba78e3c4a4d1990ff4827d7b3a7 Mon Sep 17 00:00:00 2001 From: Andrii Zakharenko Date: Tue, 12 Nov 2024 14:00:56 +0200 Subject: [PATCH 1/2] Solution --- .github/workflows/test.yml-template | 23 ++++++++++++++++++ package-lock.json | 23 ++++++++++-------- package.json | 2 +- src/app.js | 36 +++++++++++++++++++++++++++- src/modules/checkIsValidUserInput.js | 27 ++++++++++++++++++++- src/modules/generateRandomNumber.js | 14 ++++++++++- src/modules/getBullsAndCows.js | 21 +++++++++++++++- 7 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/test.yml-template diff --git a/.github/workflows/test.yml-template b/.github/workflows/test.yml-template new file mode 100644 index 00000000..bb13dfc4 --- /dev/null +++ b/.github/workflows/test.yml-template @@ -0,0 +1,23 @@ +name: Test + +on: + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test diff --git a/package-lock.json b/package-lock.json index 185b2268..ec140f30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "license": "GPL-3.0", "devDependencies": { "@mate-academy/eslint-config": "latest", - "@mate-academy/scripts": "^1.8.6", + "@mate-academy/scripts": "^1.9.12", "eslint": "^8.57.0", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-node": "^11.1.0", @@ -1467,10 +1467,11 @@ } }, "node_modules/@mate-academy/scripts": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.8.6.tgz", - "integrity": "sha512-b4om/whj4G9emyi84ORE3FRZzCRwRIesr8tJHXa8EvJdOaAPDpzcJ8A0sFfMsWH9NUOVmOwkBtOXDu5eZZ00Ig==", + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.9.12.tgz", + "integrity": "sha512-/OcmxMa34lYLFlGx7Ig926W1U1qjrnXbjFJ2TzUcDaLmED+A5se652NcWwGOidXRuMAOYLPU2jNYBEkKyXrFJA==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/rest": "^17.11.2", "@types/get-port": "^4.2.0", @@ -6825,10 +6826,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -7239,10 +7241,11 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, + "license": "MIT", "dependencies": { "isarray": "0.0.1" } diff --git a/package.json b/package.json index 216da526..5847534c 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "license": "GPL-3.0", "devDependencies": { "@mate-academy/eslint-config": "latest", - "@mate-academy/scripts": "^1.8.6", + "@mate-academy/scripts": "^1.9.12", "eslint": "^8.57.0", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-node": "^11.1.0", diff --git a/src/app.js b/src/app.js index e89a2d97..5d6278ff 100644 --- a/src/app.js +++ b/src/app.js @@ -1,3 +1,37 @@ 'use strict'; -// Write your code here +const readline = require('readline'); + +const { getBullsAndCows } = require('./modules/getBullsAndCows'); +const { checkIsValidUserInput } = require('./modules/checkIsValidUserInput'); +const { generateRandomNumber } = require('./modules/generateRandomNumber'); + +const terminal = readline.createInterface(process.stdin, process.stdout); +const randomNumber = generateRandomNumber(); + +function tryGuess() { + terminal.question('Enter a 4-digit number: ', (userInput) => { + const userNumber = Number(userInput.trim()); + const isValid = checkIsValidUserInput(userNumber); + + if (isValid) { + if (userNumber === randomNumber) { + // eslint-disable-next-line no-console + console.log('Congratulations! You guessed the number.'); + + terminal.close(); + + return; + } else { + const result = getBullsAndCows(userNumber, randomNumber); + + // eslint-disable-next-line no-console + console.log(`Result: \nbulls: ${result.bulls} \ncows: ${result.cows}`); + } + } + + return tryGuess(); + }); +} + +tryGuess(); diff --git a/src/modules/checkIsValidUserInput.js b/src/modules/checkIsValidUserInput.js index 40979664..769d5a64 100644 --- a/src/modules/checkIsValidUserInput.js +++ b/src/modules/checkIsValidUserInput.js @@ -9,7 +9,32 @@ * @return {boolean} - True if the user input is valid, false otherwise */ function checkIsValidUserInput(userInput) { - /* Write your code here */ + if (isNaN(userInput)) { + // eslint-disable-next-line no-console + console.log('Invalid input. Please enter a 4-digit number.'); + + return false; + } + + const numbers = String(userInput) + .split('') + .map((n) => Number(n)); + + if (numbers[0] === 0 || numbers.length !== 4) { + // eslint-disable-next-line no-console + console.log('Error. Enter a 4-digit number that doesnt start with 0.'); + + return false; + } + + if (new Set(numbers).size !== numbers.length) { + // eslint-disable-next-line no-console + console.log('Error. Enter a 4-digit number that has only unique digits.'); + + return false; + } + + return true; } module.exports = { diff --git a/src/modules/generateRandomNumber.js b/src/modules/generateRandomNumber.js index 14ad1e2b..2180644e 100644 --- a/src/modules/generateRandomNumber.js +++ b/src/modules/generateRandomNumber.js @@ -7,7 +7,19 @@ * @return {number} A random 4-digit number */ function generateRandomNumber() { - /* Write your code here */ + const digits = []; + + digits.push(Math.floor(Math.random() * 9) + 1); + + while (digits.length < 4) { + const randomDigit = Math.floor(Math.random() * 10); + + if (!digits.includes(randomDigit)) { + digits.push(randomDigit); + } + } + + return Number(digits.join('')); } module.exports = { diff --git a/src/modules/getBullsAndCows.js b/src/modules/getBullsAndCows.js index 3f0b39a6..bab9e521 100644 --- a/src/modules/getBullsAndCows.js +++ b/src/modules/getBullsAndCows.js @@ -13,7 +13,26 @@ * Example: { bulls: 1, cows: 2 } */ function getBullsAndCows(userInput, numberToGuess) { - /* Write your code here */ + let bulls = 0; + let cows = 0; + + const userArray = String(userInput).split(''); + const guessArray = String(numberToGuess).split(''); + + for (let i = 0; i < userArray.length; i++) { + if (guessArray.includes(userArray[i])) { + if (guessArray[i] === userArray[i]) { + bulls++; + } else { + cows++; + } + } + } + + return { + bulls, + cows, + }; } module.exports = { From 95c65c661d81ceb15b5804aec5ecc002db327600 Mon Sep 17 00:00:00 2001 From: Andrii Zakharenko <82187654+AndriiZakharenko@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:51:04 +0200 Subject: [PATCH 2/2] Update readme.md --- readme.md | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/readme.md b/readme.md index b0d82156..8740583a 100644 --- a/readme.md +++ b/readme.md @@ -1,23 +1,19 @@ # The "Bulls & Cows" game -**Read [the guideline](https://github.com/mate-academy/js_task-guideline/blob/master/README.md) before start** - -Implement `Bulls and cows` game so the user can run and play it using command line. - -- the program randomly generates a number of 4 different digits -- and asks a player to guess -- the player enters a number of 4 different digits -- the program check the entered number (if it has exactly 4 different digits) -- then computer compares a try with the generated number and shows a result of 'bulls' and 'cows' -- `bull` - guessed digit is on its place (index) -- `cow` - guessed digit exists in the number but the place (index) is wrong -- the game ends when the numbers is found -- write a solution using separate modules for generating a number, calculating bulls and cows, validate user input, input/output operations -**(corresponding files are already created)** -- use `npm run test` command to test your modules -- use `npm run play` to run the game - -## Example -Computer makes `1234`, user prints `1345`. The result is one `bull` (guessed -digit `1` is on it's place) and 2 `cows` (digits `3` and `4` are present but on -wrong places). +### Description + +- Implemented `Bulls and cows` game so the user can run and play it using command line + +### Stack + +- Node + +### Tools + +- ESlint +- Prettier +- Jest + +### Example + +- Computer makes `1234`, user prints `1345`. The result is one `bull` (guessed digit `1` is on it's place) and 2 `cows` (digits `3` and `4` are present but on wrong places)