diff --git a/package-lock.json b/package-lock.json index 03a5cc0..1021170 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3114,6 +3114,33 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "copy-webpack-plugin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-7.0.0.tgz", + "integrity": "sha512-SLjQNa5iE3BoCP76ESU9qYo9ZkEWtXoZxDurHoqPchAFRblJ9g96xTeC560UXBMre1Nx6ixIIUfiY3VcjpJw3g==", + "dev": true, + "requires": { + "fast-glob": "^3.2.4", + "glob-parent": "^5.1.1", + "globby": "^11.0.1", + "loader-utils": "^2.0.0", + "normalize-path": "^3.0.0", + "p-limit": "^3.0.2", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1" + }, + "dependencies": { + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + } + } + }, "core-js": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", diff --git a/package.json b/package.json index 6da8b61..1c3fded 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "babel-jest": "^26.6.3", "babel-plugin-transform-class-properties": "^6.24.1", "clean-webpack-plugin": "^3.0.0", + "copy-webpack-plugin": "^7.0.0", "css-loader": "^5.0.1", "eslint": "^7.18.0", "eslint-config-prettier": "^7.2.0", diff --git a/src/controllers/GameController.ts b/src/controllers/GameController.ts index 1488d5e..deeddf0 100644 --- a/src/controllers/GameController.ts +++ b/src/controllers/GameController.ts @@ -3,18 +3,21 @@ import { Square } from '../models/Square'; import { GameEngine } from '../services/game-logic/GameEngine'; import { Piece } from '../services/game-logic/pieces/Piece'; import { BoardView } from '../views/BoardView'; +import { Sound } from '../services/game-logic/Sound'; class GameController { boardView: BoardView; gameEngine: GameEngine; activeSquare: Square | null; currentPlayer: Colors; + sound: Sound; constructor() { this.activeSquare = null; this.gameEngine = new GameEngine(); this.boardView = new BoardView(this.handleUserClick); this.currentPlayer = Colors.WHITE; + this.sound = new Sound(); this.updateBoard(); } @@ -26,6 +29,7 @@ class GameController { const isLegalMove = legalMoves.some((move) => square?.row === move.row && square?.column === move.column); if (isLegalMove) { + this.playSound(this.activeSquare, square); this.gameEngine.movePiece(this.activeSquare, square); this.boardView.render(this.gameEngine.board); this.changePlayer(); @@ -39,6 +43,17 @@ class GameController { } }; + private playSound(location: Square, destination: Square): void { + const locationPiece = this.gameEngine.board.getPiece(location); + const destinationPiece = this.gameEngine.board.getPiece(destination); + + if (locationPiece && destinationPiece) { + this.sound.playCapturingMoveSound(); + } else { + this.sound.playNormalMoveSound(); + } + } + private isCurrentPlayer(selectedPiece: Piece | null): boolean { return this.currentPlayer === selectedPiece?.color; } diff --git a/src/controllers/SoundController.ts b/src/controllers/SoundController.ts deleted file mode 100644 index 3b4c8e0..0000000 --- a/src/controllers/SoundController.ts +++ /dev/null @@ -1,43 +0,0 @@ -const sound0 = require('../../static/sounds/0.mp3'); -const sound1 = require('../../static/sounds/1.mp3'); -const sound2 = require('../../static/sounds/2.mp3'); -const soundCapture = require('../../static/sounds/capture.mp3'); - -import { SoundTypes } from '../enums/SoundTypes'; - -class SoundController { - private lastPlayedMoveSound: number = 0; - - public makeSound(soundType: SoundTypes) { - switch (soundType) { - case SoundTypes.NORMAL_MOVE: - this.playNormalMoveSound(); - break; - case SoundTypes.CAPTURING_MOVE: - this.playCapturingMoveSound(); - break; - default: - break; - } - } - - private playCapturingMoveSound(): void { - let sound = new Audio('./static/sounds/capture.mp3'); - sound.play(); - } - - private playNormalMoveSound(): void { - const generateRandomNumber = () => Math.floor(Math.random() * 3); - let randomNumber = generateRandomNumber(); - - // avoid playing same sound as before - while (this.lastPlayedMoveSound === randomNumber) { - randomNumber = generateRandomNumber(); - } - let sound = new Audio(`/static/sounds/${randomNumber}.mp3`); - sound.play(); - this.lastPlayedMoveSound = randomNumber; - } -} - -export { SoundController }; diff --git a/src/enums/SoundTypes.ts b/src/enums/SoundTypes.ts deleted file mode 100644 index 2689688..0000000 --- a/src/enums/SoundTypes.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum SoundTypes { - NORMAL_MOVE, - CAPTURING_MOVE -} diff --git a/src/enums/index.ts b/src/enums/index.ts index e9b9f94..d4c1f4f 100644 --- a/src/enums/index.ts +++ b/src/enums/index.ts @@ -1,4 +1,3 @@ export * from './PieceNames'; export * from './Colors'; export * from './Constants'; -export * from './SoundTypes'; diff --git a/src/services/game-logic/GameEngine.ts b/src/services/game-logic/GameEngine.ts index 504ed22..a719c53 100644 --- a/src/services/game-logic/GameEngine.ts +++ b/src/services/game-logic/GameEngine.ts @@ -1,16 +1,13 @@ -import { PieceNames, Constants, SoundTypes } from '../../enums'; +import { PieceNames, Constants } from '../../enums'; import { Square } from '../../models/Square'; import { Board } from './Board'; import { Piece } from './pieces/Piece'; -import { SoundController } from '../../controllers/SoundController'; class GameEngine { board: Board; - soundController: SoundController; constructor() { this.board = new Board(); - this.soundController = new SoundController(); } getLegalMoves = (square: Square): Square[] => { @@ -27,24 +24,12 @@ class GameEngine { public movePiece(location: Square, destination: Square): void { //can be useful when saving moves const piece = this.board.getPiece(location); - this.playSound(location, destination); this.board.movePiece(location, destination); if (piece?.name === PieceNames.KING) { this.performCastling(location, destination); } } - private playSound(location: Square, destination: Square): void { - const locationPiece = this.board.getPiece(location); - const destinationPiece = this.board.getPiece(destination); - - if (locationPiece && destinationPiece) { - this.soundController.makeSound(SoundTypes.CAPTURING_MOVE); - } else { - this.soundController.makeSound(SoundTypes.NORMAL_MOVE); - } - } - private performCastling(location: Square, destination: Square): void { if (destination.column - location.column === Constants.KINGSIDE_CASTLING) { this.board.movePiece( diff --git a/src/services/game-logic/Sound.ts b/src/services/game-logic/Sound.ts new file mode 100644 index 0000000..6921a59 --- /dev/null +++ b/src/services/game-logic/Sound.ts @@ -0,0 +1,24 @@ +class Sound { + private lastPlayedMoveSound = 0; + private AMOUNT_OF_NORMAL_MOVE_SOUNDS = 3; + + public playCapturingMoveSound(): void { + const sound = new Audio('/static/sounds/capture.mp3'); + sound.play(); + } + + public playNormalMoveSound(): void { + const generateRandomNumber = () => Math.floor(Math.random() * this.AMOUNT_OF_NORMAL_MOVE_SOUNDS); + let randomNumber = generateRandomNumber(); + + // avoid playing same sound as before + while (this.lastPlayedMoveSound === randomNumber) { + randomNumber = generateRandomNumber(); + } + const sound = new Audio(`/static/sounds/${randomNumber}.mp3`); + sound.play(); + this.lastPlayedMoveSound = randomNumber; + } +} + +export { Sound }; diff --git a/src/services/game-logic/pieces/Pawn.ts b/src/services/game-logic/pieces/Pawn.ts index 98ed639..5b957db 100644 --- a/src/services/game-logic/pieces/Pawn.ts +++ b/src/services/game-logic/pieces/Pawn.ts @@ -42,7 +42,7 @@ class Pawn extends Piece { return moves; } - private prepareMove(rowStep: number, colStep: number = 0): Square | null { + private prepareMove(rowStep: number, colStep = 0): Square | null { const move = new Square(this.position.row + rowStep, this.position.column + colStep); // Check if out of boundaries diff --git a/webpack.common.config.js b/webpack.common.config.js index 961d45b..239b2bf 100644 --- a/webpack.common.config.js +++ b/webpack.common.config.js @@ -1,5 +1,6 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const CopyPlugin = require('copy-webpack-plugin'); const path = require('path'); module.exports = { @@ -24,10 +25,7 @@ module.exports = { }, { test: /\.(png|jpe?g|svg|mp3)$/i, - loader: 'file-loader', - options: { - name: '[path][name].[ext]' - } + use: 'file-loader' } ] }, @@ -38,5 +36,11 @@ module.exports = { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, - plugins: [new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: './src/index.html', scriptLoading: 'defer' })] + plugins: [ + new CleanWebpackPlugin(), + new HtmlWebpackPlugin({ template: './src/index.html', scriptLoading: 'defer' }), + new CopyPlugin({ + patterns: [{ from: 'static', to: 'static' }] + }) + ] };