From e5235c43762525f97807a9649e4e75f29bb53472 Mon Sep 17 00:00:00 2001 From: Ido-Barnea Date: Tue, 20 Feb 2024 13:50:19 +0200 Subject: [PATCH 1/4] [#111] Added double queen resource --- development/code/ui/Resources.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/development/code/ui/Resources.ts b/development/code/ui/Resources.ts index 80593d9a..172fb4a8 100644 --- a/development/code/ui/Resources.ts +++ b/development/code/ui/Resources.ts @@ -10,7 +10,9 @@ export const knightResource = ''; export const pawnResource = ''; - +export const doubleQueenResource = + ''; + export const piggyBankResource = ''; export const trapResource = From d35f17cc4ff38b19ebeacabfa57399f0634aa704 Mon Sep 17 00:00:00 2001 From: Ido-Barnea Date: Tue, 20 Feb 2024 15:19:07 +0200 Subject: [PATCH 2/4] [#111] Created DoubleQueen piece class --- development/code/logic/pieces/DoubleQueen.ts | 70 +++++++++++++++++++ development/code/logic/pieces/Piece.ts | 18 ++--- .../code/logic/pieces/PiecesUtilities.ts | 12 ---- development/code/logic/pieces/Queen.ts | 3 + 4 files changed, 82 insertions(+), 21 deletions(-) create mode 100644 development/code/logic/pieces/DoubleQueen.ts diff --git a/development/code/logic/pieces/DoubleQueen.ts b/development/code/logic/pieces/DoubleQueen.ts new file mode 100644 index 00000000..01d828a0 --- /dev/null +++ b/development/code/logic/pieces/DoubleQueen.ts @@ -0,0 +1,70 @@ +import { doubleQueenResource } from '../../ui/Resources'; +import { Piece } from './Piece'; +import { Player, PlayerColors } from '../Players'; +import { Position } from './PiecesUtilities'; +import { getPieceByPosition } from '../Utilities'; + +export class DoubleQueen extends Piece { + constructor(position: Position, player: Player) { + const icon = player.color === PlayerColors.WHITE + ? '♕x2' + : '♛x2'; + + super(doubleQueenResource, icon, 'Double Queen', player, position); + + this.actions = 2; + this.price = 5; + } + + getLegalMoves(): Array { + const validMoves: Array = []; + const currentCoordinates = this.position.coordinates; + + // Iterate over all possible directions for the queen + const directions = [ + { deltaX: 1, deltaY: 0 }, + { deltaX: -1, deltaY: 0 }, + { deltaX: 0, deltaY: 1 }, + { deltaX: 0, deltaY: -1 }, + { deltaX: 1, deltaY: 1 }, + { deltaX: -1, deltaY: -1 }, + { deltaX: 1, deltaY: -1 }, + { deltaX: -1, deltaY: 1 }, + ]; + + for (const direction of directions) { + let stepX = direction.deltaX; + let stepY = direction.deltaY; + + // Iterate until the edge of the board + while (true) { + const nextX = currentCoordinates[0] + stepX; + const nextY = currentCoordinates[1] + stepY; + + // Check if the next position is within the board boundaries + if (nextX < 0 || nextX >= 8 || nextY < 0 || nextY >= 8) { + break; + } + + const nextPosition: Position = { + coordinates: [nextX, nextY], + boardId: this.position.boardId, + }; + + // Add the position to the list of valid moves + validMoves.push(nextPosition); + + // If the move encounters another piece, stop iterating in this direction + if (getPieceByPosition(nextPosition)) { + break; + } + + // Move further in the current direction + stepX += direction.deltaX; + stepY += direction.deltaY; + } + } + + return validMoves; + } +} \ No newline at end of file diff --git a/development/code/logic/pieces/Piece.ts b/development/code/logic/pieces/Piece.ts index e79468a7..264ef1f6 100644 --- a/development/code/logic/pieces/Piece.ts +++ b/development/code/logic/pieces/Piece.ts @@ -1,15 +1,16 @@ import { Player } from '../Players'; import { Item } from '../items/Items'; -import { PieceType, Position, Square } from './PiecesUtilities'; +import { Position, Square } from './PiecesUtilities'; -export class Piece implements PieceType { +export class Piece { resource: string; pieceIcon: string; name: string; player: Player; position: Position; - upgrades: Array; + actions: number; price: number; + upgrades: Array Piece>; equipedItem: Item | undefined; hasMoved: boolean; killCount: number; @@ -20,18 +21,17 @@ export class Piece implements PieceType { name: string, player: Player, position: Position, - upgrades: Array = [], - price = 1, - equipedItem: Item | undefined = undefined, ) { this.resource = resource; this.pieceIcon = pieceIcon; this.name = name; this.player = player; this.position = position; - this.upgrades = upgrades; - this.price = price; - this.equipedItem = equipedItem; + + this.actions = 1; + this.price = 1; + this.upgrades = []; + this.equipedItem = undefined; this.hasMoved = false; this.killCount = 0; } diff --git a/development/code/logic/pieces/PiecesUtilities.ts b/development/code/logic/pieces/PiecesUtilities.ts index 19e0859a..191c9945 100644 --- a/development/code/logic/pieces/PiecesUtilities.ts +++ b/development/code/logic/pieces/PiecesUtilities.ts @@ -1,5 +1,4 @@ import { Piece } from './Piece'; -import { Player } from '../Players'; import { Item } from '../items/Items'; import { comparePositions } from '../Utilities'; import { game } from '../../Game'; @@ -14,17 +13,6 @@ export type Square = { occupent?: Piece; }; -export interface PieceType { - resource: string; - pieceIcon: string; - name: string; - player: Player; - position: Position; - upgrades: Array; - hasMoved: boolean; - killCount: number; -} - export function getItemByPosition( position: Position, ): Item | undefined { diff --git a/development/code/logic/pieces/Queen.ts b/development/code/logic/pieces/Queen.ts index b34e1132..a56ffc13 100644 --- a/development/code/logic/pieces/Queen.ts +++ b/development/code/logic/pieces/Queen.ts @@ -3,6 +3,7 @@ import { Piece } from './Piece'; import { Player, PlayerColors } from '../Players'; import { Position } from './PiecesUtilities'; import { getPieceByPosition } from '../Utilities'; +import { DoubleQueen } from './DoubleQueen'; export class Queen extends Piece { constructor(position: Position, player: Player) { @@ -11,6 +12,8 @@ export class Queen extends Piece { : '♛'; super(queenResource, icon, 'Queen', player, position); + + this.upgrades = [DoubleQueen]; } getLegalMoves(): Array { From fea3d714f5045d4ca8d65b4e8735895391defac8 Mon Sep 17 00:00:00 2001 From: Ido-Barnea Date: Tue, 20 Feb 2024 15:36:34 +0200 Subject: [PATCH 3/4] [#111] Implemented actions-per-turn logic --- development/code/Game.ts | 58 +++++++++++++++++++--------- development/code/logic/PieceLogic.ts | 25 ++++++------ 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/development/code/Game.ts b/development/code/Game.ts index 6eea2494..306ec6e7 100644 --- a/development/code/Game.ts +++ b/development/code/Game.ts @@ -13,6 +13,7 @@ import { RulesManager } from './logic/rules/RulesManager'; import { showWinningAlert as showGameEndAlert } from './ui/Screen'; import { Logger } from './ui/logs/Logger'; import { initialiseInventoryUI } from './ui/InventoriesUI'; +import { DoubleQueen } from './logic/pieces/DoubleQueen'; let rulesManager: RulesManager; const whitePlayer = new Player(PlayerColors.WHITE); @@ -46,7 +47,7 @@ let pieces: Array = [ new Rook({ coordinates: [0, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new Knight({ coordinates: [1, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new Bishop({ coordinates: [2, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), - new Queen({ coordinates: [3, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), + new DoubleQueen({ coordinates: [3, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new King({ coordinates: [4, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new Bishop({ coordinates: [5, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new Knight({ coordinates: [6, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), @@ -62,6 +63,7 @@ let isFriendlyFire = false; let isPieceKilled = false; let wasItemPlacedThisTurn = false; let fellOffTheBoardPiece: Piece | undefined; +let actionsLeft = 0; let isGameFinished = false; function initializeGame() { @@ -72,12 +74,36 @@ function initializeGame() { }); } -function endTurn() { +function endMove(canRecover = true) { rulesManager.activeRules.forEach((rule) => { rule.trigger(); }); + Logger.logMessages(); + + // element.remove() is scheduled to run in the next event sycle while alert() runs immedietely. + // To make sure the element is removed before displaying the winning alert, we need to add + // a small delay before displaying the alert. + setTimeout(() => { + if (isGameFinished) { + const livingKingPlayer = pieces.filter(piece => piece instanceof King)[0].player; + + showGameEndAlert(livingKingPlayer.color); + window.location.reload(); + } + }, 10); + resetVariables(); + + + actionsLeft--; + if (!canRecover) actionsLeft = 0; + if (actionsLeft !== 0) return; + + endTurn(); +} + +function endTurn() { updatePlayerDetails(); currentPlayerIndex = currentPlayerIndex + 1 < players.length ? currentPlayerIndex + 1 : 0; @@ -87,26 +113,11 @@ function endTurn() { roundCounter++; } - Logger.logMessages(); - players.forEach((player) => { switchInventory(player); }); renderScreen(); - wasItemPlacedThisTurn = false; - - // element.remove() is scheduled to run in the next event sycle while alert() runs immedietely. - // To make sure the element is removed before displaying the winning alert, we need to add - // a small delay before displaying the alert. - setTimeout(() => { - if (isGameFinished) { - const livingKingPlayer = pieces.filter(piece => piece instanceof King)[0].player; - - showGameEndAlert(livingKingPlayer.color); - window.location.reload(); - } - }, 10); } function resetVariables() { @@ -114,6 +125,7 @@ function resetVariables() { isFriendlyFire = false; isPieceKilled = false; fellOffTheBoardPiece = undefined; + wasItemPlacedThisTurn = false; pieces.forEach((piece) => { if (piece.player !== getCurrentPlayer() && piece instanceof Pawn) { @@ -212,6 +224,14 @@ function setFellOffTheBoardPiece(_fellOffTheBoardPiece: Piece | undefined) { fellOffTheBoardPiece = _fellOffTheBoardPiece; } +function getActionsLeft() { + return actionsLeft; +} + +function setActionsLeft(actions: number) { + actionsLeft = actions; +} + function endGame() { isGameFinished = true; } @@ -227,7 +247,9 @@ function getWasItemPlacedThisTurn(){ export const game = { initialize: initializeGame, end: endGame, - endTurn, + endMove, + getActionsLeft, + setActionsLeft, getCurrentPlayer, switchIsCastling, getPlayers, diff --git a/development/code/logic/PieceLogic.ts b/development/code/logic/PieceLogic.ts index bcd707cd..6f1031c9 100644 --- a/development/code/logic/PieceLogic.ts +++ b/development/code/logic/PieceLogic.ts @@ -75,6 +75,13 @@ function revertPieceMoveOnBoard(piece: Piece) { movePieceOnBoard(piece, piece.position); } +export function onPieceFellOffTheBoard(draggedPiece: Piece) { + draggedPiece.position.boardId = VOID_BOARD_ID; + killPieceByGame(draggedPiece, 'gravity'); + game.setFellOffTheBoardPiece(draggedPiece); + game.endMove(false); +} + export function onPlayerAction( draggedPiece: Piece, target: Piece | Square | Item, @@ -91,6 +98,9 @@ export function onPlayerAction( // If it did, return. if (pieceBoard !== newPieceBoard) return; + if (game.getActionsLeft() === 0) { + game.setActionsLeft(draggedPiece.actions); + } if (target instanceof Piece) { onActionAttackMove(draggedPiece, target); @@ -110,13 +120,6 @@ function onActionNonAttackMove( onActionPieceToSquare(draggedPiece, targetSquare); } -export function onPieceFellOffTheBoard(draggedPiece: Piece) { - draggedPiece.position.boardId = VOID_BOARD_ID; - killPieceByGame(draggedPiece, 'gravity'); - game.setFellOffTheBoardPiece(draggedPiece); - game.endTurn(); -} - function onActionAttackMove( draggedPiece: Piece, targetPiece: Piece, @@ -206,7 +209,7 @@ function move( }; draggedPiece.hasMoved = true; - if (shouldEndTurn) game.endTurn(); + if (shouldEndTurn) game.endMove(); } function killPieceByAnotherPiece( @@ -215,7 +218,7 @@ function killPieceByAnotherPiece( ): boolean { if (targetPiece.equipedItem instanceof Shield) { revertPieceMoveOnBoard(draggedPiece); - game.endTurn(); + game.endMove(); return false; } @@ -235,7 +238,7 @@ function killPieceByGame( killCause: string, ): boolean { if (targetPiece.equipedItem instanceof Shield) { - game.endTurn(); + game.endMove(); return false; } @@ -329,7 +332,7 @@ function pieceMovedOnTrap( destroyItemOnBoard(trap); if (!isSuccessfulKill) return; - game.endTurn(); + game.endMove(false); } export function pieceMovedOnPiggyBank( From 083b34c761723f6f508335a6f47a7c2c248b7893 Mon Sep 17 00:00:00 2001 From: Ido-Barnea Date: Tue, 20 Feb 2024 15:42:30 +0200 Subject: [PATCH 4/4] [trivial] Minor fix --- development/code/Game.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/development/code/Game.ts b/development/code/Game.ts index 306ec6e7..f6641b48 100644 --- a/development/code/Game.ts +++ b/development/code/Game.ts @@ -13,7 +13,6 @@ import { RulesManager } from './logic/rules/RulesManager'; import { showWinningAlert as showGameEndAlert } from './ui/Screen'; import { Logger } from './ui/logs/Logger'; import { initialiseInventoryUI } from './ui/InventoriesUI'; -import { DoubleQueen } from './logic/pieces/DoubleQueen'; let rulesManager: RulesManager; const whitePlayer = new Player(PlayerColors.WHITE); @@ -47,7 +46,7 @@ let pieces: Array = [ new Rook({ coordinates: [0, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new Knight({ coordinates: [1, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new Bishop({ coordinates: [2, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), - new DoubleQueen({ coordinates: [3, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), + new Queen({ coordinates: [3, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new King({ coordinates: [4, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new Bishop({ coordinates: [5, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer), new Knight({ coordinates: [6, 7], boardId: OVERWORLD_BOARD_ID }, whitePlayer),