generated from mate-academy/gulp-template
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Oleh Chernov
committed
Jan 14, 2025
1 parent
a6d3781
commit 0c6a2d5
Showing
23 changed files
with
813 additions
and
258 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
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 start & sleep 5 && npm test | ||
- name: Upload tests report(cypress mochaawesome merged HTML report) | ||
if: ${{ always() }} | ||
uses: actions/upload-artifact@v2 | ||
with: | ||
name: report | ||
path: reports |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,240 @@ | ||
'use strict'; | ||
|
||
/** | ||
* This class represents the game. | ||
* Now it has a basic structure, that is needed for testing. | ||
* Feel free to add more props and methods if needed. | ||
*/ | ||
class Game { | ||
/** | ||
* Creates a new game instance. | ||
* | ||
* @param {number[][]} initialState | ||
* The initial state of the board. | ||
* @default | ||
* [[0, 0, 0, 0], | ||
* [0, 0, 0, 0], | ||
* [0, 0, 0, 0], | ||
* [0, 0, 0, 0]] | ||
* | ||
* If passed, the board will be initialized with the provided | ||
* initial state. | ||
*/ | ||
export default class Game { | ||
constructor(initialState) { | ||
// eslint-disable-next-line no-console | ||
console.log(initialState); | ||
this.initialState = initialState || [ | ||
[0, 0, 0, 0], | ||
[0, 0, 0, 0], | ||
[0, 0, 0, 0], | ||
[0, 0, 0, 0], | ||
]; | ||
this.state = structuredClone(this.initialState); | ||
this.score = 0; | ||
this.status = 'idle'; | ||
} | ||
|
||
moveLeft() {} | ||
moveRight() {} | ||
moveUp() {} | ||
moveDown() {} | ||
|
||
/** | ||
* @returns {number} | ||
*/ | ||
getScore() {} | ||
|
||
/** | ||
* @returns {number[][]} | ||
*/ | ||
getState() {} | ||
|
||
/** | ||
* Returns the current game status. | ||
* | ||
* @returns {string} One of: 'idle', 'playing', 'win', 'lose' | ||
* | ||
* `idle` - the game has not started yet (the initial state); | ||
* `playing` - the game is in progress; | ||
* `win` - the game is won; | ||
* `lose` - the game is lost | ||
*/ | ||
getStatus() {} | ||
|
||
/** | ||
* Starts the game. | ||
*/ | ||
start() {} | ||
|
||
/** | ||
* Resets the game. | ||
*/ | ||
restart() {} | ||
|
||
// Add your own methods here | ||
} | ||
moveLeft() { | ||
if (this.status !== 'playing') { | ||
return; | ||
} | ||
|
||
const prevState = structuredClone(this.state); | ||
|
||
for (let i = 0; i < 4; i++) { | ||
const row = this.state[i].filter((cell) => cell !== 0); | ||
|
||
for (let j = 0; j < row.length - 1; j++) { | ||
if (row[j] === row[j + 1]) { | ||
row[j] *= 2; | ||
this.score += row[j]; | ||
row.splice(j + 1, 1); | ||
} | ||
} | ||
|
||
while (row.length < 4) { | ||
row.push(0); | ||
} | ||
this.state[i] = row; | ||
} | ||
|
||
if (prevState !== structuredClone(this.state)) { | ||
this.addRandomTile(); | ||
this.updateGameStatus(); | ||
} | ||
} | ||
|
||
moveRight() { | ||
if (this.status !== 'playing') { | ||
return; | ||
} | ||
|
||
const prevState = structuredClone(this.state); | ||
|
||
for (let i = 0; i < 4; i++) { | ||
const row = this.state[i].filter((cell) => cell !== 0); | ||
|
||
for (let j = row.length - 1; j > 0; j--) { | ||
if (row[j] === row[j - 1]) { | ||
row[j] *= 2; | ||
this.score += row[j]; | ||
row.splice(j - 1, 1); | ||
j--; | ||
} | ||
} | ||
|
||
while (row.length < 4) { | ||
row.unshift(0); | ||
} | ||
this.state[i] = row; | ||
} | ||
|
||
if (prevState !== structuredClone(this.state)) { | ||
this.addRandomTile(); | ||
this.updateGameStatus(); | ||
} | ||
} | ||
|
||
moveUp() { | ||
if (this.status !== 'playing') { | ||
return; | ||
} | ||
|
||
const prevState = structuredClone(this.state); | ||
|
||
for (let j = 0; j < 4; j++) { | ||
const column = []; | ||
|
||
for (let i = 0; i < 4; i++) { | ||
if (this.state[i][j] !== 0) { | ||
column.push(this.state[i][j]); | ||
} | ||
} | ||
|
||
for (let i = 0; i < column.length - 1; i++) { | ||
if (column[i] === column[i + 1]) { | ||
column[i] *= 2; | ||
this.score += column[i]; | ||
column.splice(i + 1, 1); | ||
} | ||
} | ||
|
||
while (column.length < 4) { | ||
column.push(0); | ||
} | ||
|
||
for (let i = 0; i < 4; i++) { | ||
this.state[i][j] = column[i]; | ||
} | ||
} | ||
|
||
if (prevState !== structuredClone(this.state)) { | ||
this.addRandomTile(); | ||
this.updateGameStatus(); | ||
} | ||
} | ||
|
||
moveDown() { | ||
if (this.status !== 'playing') { | ||
return; | ||
} | ||
|
||
const prevState = structuredClone(this.state); | ||
|
||
for (let j = 0; j < 4; j++) { | ||
const column = []; | ||
|
||
for (let i = 0; i < 4; i++) { | ||
if (this.state[i][j] !== 0) { | ||
column.push(this.state[i][j]); | ||
} | ||
} | ||
|
||
for (let i = column.length - 1; i > 0; i--) { | ||
if (column[i] === column[i - 1]) { | ||
column[i] *= 2; | ||
this.score += column[i]; | ||
column.splice(i - 1, 1); | ||
i--; | ||
} | ||
} | ||
|
||
module.exports = Game; | ||
while (column.length < 4) { | ||
column.unshift(0); | ||
} | ||
|
||
for (let i = 0; i < 4; i++) { | ||
this.state[i][j] = column[i]; | ||
} | ||
} | ||
|
||
if (prevState !== structuredClone(this.state)) { | ||
this.addRandomTile(); | ||
this.updateGameStatus(); | ||
} | ||
} | ||
|
||
getScore() { | ||
return this.score; | ||
} | ||
|
||
getState() { | ||
return this.state; | ||
} | ||
|
||
getStatus() { | ||
return this.status; | ||
} | ||
|
||
start() { | ||
this.state = structuredClone(this.initialState); | ||
this.status = 'playing'; | ||
this.addRandomTile(); | ||
this.addRandomTile(); | ||
} | ||
|
||
restart() { | ||
this.state = structuredClone(this.initialState); | ||
this.score = 0; | ||
this.status = 'idle'; | ||
this.addRandomTile(); | ||
this.addRandomTile(); | ||
} | ||
|
||
addRandomTile() { | ||
const arrayForEmptyCells = []; | ||
|
||
for (let i = 0; i < 4; i++) { | ||
for (let j = 0; j < 4; j++) { | ||
if (this.state[i][j] === 0) { | ||
arrayForEmptyCells.push([i, j]); | ||
} | ||
} | ||
} | ||
|
||
if (arrayForEmptyCells.length > 0) { | ||
const [row, col] = | ||
arrayForEmptyCells[ | ||
Math.floor(Math.random() * arrayForEmptyCells.length) | ||
]; | ||
|
||
this.state[row][col] = Math.random() < 0.9 ? 2 : 4; | ||
} | ||
} | ||
|
||
hasWon() { | ||
return this.state.some((row) => row.some((cell) => cell === 2048)); | ||
} | ||
|
||
canMove() { | ||
for (let i = 0; i < 4; i++) { | ||
for (let j = 0; j < 4; j++) { | ||
if (this.state[i][j] === 0) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
for (let i = 0; i < 4; i++) { | ||
for (let j = 0; j < 4; j++) { | ||
const current = this.state[i][j]; | ||
|
||
if ( | ||
(i < 3 && current === this.state[i + 1][j]) || | ||
(j < 3 && current === this.state[i][j + 1]) | ||
) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
updateGameStatus() { | ||
if (this.hasWon()) { | ||
this.status = 'win'; | ||
} else if (!this.canMove()) { | ||
this.status = 'lose'; | ||
} | ||
} | ||
} |
Oops, something went wrong.