Skip to content

Commit

Permalink
refactor(web): handle pieces management
Browse files Browse the repository at this point in the history
  • Loading branch information
Neosoulink committed Oct 5, 2024
1 parent f40b606 commit db47129
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 198 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"instanceds",
"Linvel",
"mrdoob",
"queenside",
"timestep",
"tsyringe",
"turborepo"
Expand Down
90 changes: 66 additions & 24 deletions apps/web/src/core/engine/engine.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import { Module } from "@quick-threejs/reactive";
import { EngineComponent } from "./engine.component";
import { PiecesComponent } from "../pieces/pieces.component";
import { EngineController } from "./engine.controller";
import { getOppositeColor, PieceType } from "../../shared";
import {
getOppositeColor,
MatrixPieceModel,
MoveFlags,
ObservablePayload,
PieceType
} from "../../shared";

@singleton()
export class EngineModule implements Module {
Expand All @@ -14,32 +20,68 @@ export class EngineModule implements Module {
@inject(EngineController) private readonly controller: EngineController
) {}

public init() {
this.controller.pieceMoved$?.subscribe((payload) => {
const { piece, cell, intersection, nextMoveIndex, nextMove } = payload;

if (!intersection || !cell || !(nextMoveIndex >= 0) || !nextMove)
return this.pieceComponent.movePieceByCoord(piece, piece.coord);

if (nextMove.captured) {
const pieceToDelete = this.pieceComponent.getPieceByCoord(
nextMove.captured as PieceType,
getOppositeColor(piece.color),
nextMove.flags === "e"
? {
...cell.coord,
row: cell.coord.row + (nextMove.color === "w" ? -1 : 1)
}
: cell.coord
);

if (pieceToDelete) this.pieceComponent.dropPiece(pieceToDelete);
private _pieceMovedHandler(
payload: ObservablePayload<EngineController["pieceMoved$"]>
) {
const { piece, cell, intersection, nextMoveIndex, nextMove } = payload;
const flags = nextMove?.flags as MoveFlags;
const oppositeColor = getOppositeColor(piece.color);

let pieceToDrop: MatrixPieceModel | undefined = undefined;

if (!intersection || !cell || !(nextMoveIndex >= 0) || !nextMove)
return this.pieceComponent.movePieceByCoord(piece, piece.coord);

if (nextMove.captured)
pieceToDrop = this.pieceComponent.getPieceByCoord(
nextMove.captured as PieceType,
oppositeColor,
nextMove.flags === "e"
? {
...cell.coord,
row: cell.coord.row + (nextMove.color === "w" ? -1 : 1)
}
: cell.coord
);

if (
flags === MoveFlags.kingside_castle ||
flags === MoveFlags.queenside_castle
) {
const rockCoord = {
...cell.coord,
col: flags === MoveFlags.kingside_castle ? 7 : 0
};
const rock = this.pieceComponent.getPieceByCoord(
PieceType.rock,
oppositeColor,
rockCoord
);

if (rock) {
const newRockCoord = {
...cell.coord,
col: flags === MoveFlags.kingside_castle ? 5 : 3
};

this.pieceComponent.movePieceByCoord(rock, newRockCoord);
}
}

// if (nextMove.promotion) {
// const
// }

if (payload.nextMove) this.component.game.move(payload.nextMove);
if (pieceToDrop) {
this.pieceComponent.dropPiece(pieceToDrop);
}

this.pieceComponent.movePieceByCoord(piece, cell.coord);
});
this.pieceComponent.movePieceByCoord(piece, cell.coord);
this.component.game.move(nextMove);
}

public init() {
this.controller.pieceMoved$?.subscribe(this._pieceMovedHandler.bind(this));
}

public dispose() {}
Expand Down
154 changes: 88 additions & 66 deletions apps/web/src/core/pieces/pieces.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import {
ColorVariant,
BOARD_MATRIX_RANGE_SIZE,
MatrixPieceModel,
BoardCoord
BoardCoord,
DroppedPiecesGroups
} from "../../shared";
import { BoardComponent } from "../board/board.component";
import { ResourceComponent } from "../resource/resource.component";

@singleton()
export class PiecesComponent {
public groups?: PiecesGroups;
public droppedGroups?: DroppedPiecesGroups;

constructor(
@inject(BoardComponent)
Expand All @@ -33,13 +35,10 @@ export class PiecesComponent {
BOARD_MATRIX_RANGE_SIZE,
this.resourceComponent.getGeometryByPieceType(PieceType.pawn)
);
const isBlack = color === ColorVariant.black;

Object.keys(group.pieces).forEach((id, index) => {
const piece = group.pieces[parseInt(id)];
if (!piece) return;
const isBlack = piece.color === ColorVariant.black;

group.setPieceCoord(piece.id, this.boardComponent.instancedCell, {
group.pieces.forEach((piece, index) => {
group.setPieceCoord(piece.instanceId, this.boardComponent.instancedCell, {
col: isBlack ? BOARD_MATRIX_RANGE_SIZE - 1 - index : index,
row: isBlack ? BOARD_MATRIX_RANGE_SIZE - 2 : 1
});
Expand All @@ -55,12 +54,10 @@ export class PiecesComponent {
2,
this.resourceComponent.getGeometryByPieceType(PieceType.rock)
);
const isBlack = color === ColorVariant.black;

Object.keys(group.pieces).forEach((id, index) => {
const piece = group.pieces[parseInt(id)];
if (!piece) return;
const isBlack = piece.color === ColorVariant.black;
group.setPieceCoord(piece.id, this.boardComponent.instancedCell, {
group.pieces.forEach((piece, index) => {
group.setPieceCoord(piece.instanceId, this.boardComponent.instancedCell, {
col: index === 0 ? 0 : BOARD_MATRIX_RANGE_SIZE - 1,
row: isBlack ? BOARD_MATRIX_RANGE_SIZE - 1 : 0
});
Expand All @@ -69,20 +66,17 @@ export class PiecesComponent {
return group;
}

private _initBishops<Color extends ColorVariant>(color: Color) {
private _initKnights<Color extends ColorVariant>(color: Color) {
const group = this.createGroup(
PieceType.bishop,
PieceType.knight,
color,
2,
this.resourceComponent.getGeometryByPieceType(PieceType.bishop)
this.resourceComponent.getGeometryByPieceType(PieceType.knight)
);
const isBlack = color === ColorVariant.black;

Object.keys(group.pieces).forEach((id, index) => {
const piece = group.pieces[parseInt(id)];
if (!piece) return;
const isBlack = piece.color === ColorVariant.black;

group.setPieceCoord(piece.id, this.boardComponent.instancedCell, {
group.pieces.forEach((piece, index) => {
group.setPieceCoord(piece.instanceId, this.boardComponent.instancedCell, {
col: isBlack
? index === 0
? BOARD_MATRIX_RANGE_SIZE - 2
Expand All @@ -97,20 +91,17 @@ export class PiecesComponent {
return group;
}

private _initKnights<Color extends ColorVariant>(color: Color) {
private _initBishops<Color extends ColorVariant>(color: Color) {
const group = this.createGroup(
PieceType.knight,
PieceType.bishop,
color,
2,
this.resourceComponent.getGeometryByPieceType(PieceType.knight)
this.resourceComponent.getGeometryByPieceType(PieceType.bishop)
);
const isBlack = color === ColorVariant.black;

Object.keys(group.pieces).forEach((id, index) => {
const piece = group.pieces[parseInt(id)];
if (!piece) return;
const isBlack = piece.color === ColorVariant.black;

group.setPieceCoord(piece.id, this.boardComponent.instancedCell, {
group.pieces.forEach((piece, index) => {
group.setPieceCoord(piece.instanceId, this.boardComponent.instancedCell, {
col: isBlack
? index === 0
? BOARD_MATRIX_RANGE_SIZE - 3
Expand All @@ -132,14 +123,11 @@ export class PiecesComponent {
1,
this.resourceComponent.getGeometryByPieceType(PieceType.queen)
);
const isBlack = color === ColorVariant.black;

Object.keys(group.pieces).forEach((id) => {
const piece = group.pieces[parseInt(id)];
if (!piece) return;
const isBlack = piece.color === ColorVariant.black;

group.setPieceCoord(piece.id, this.boardComponent.instancedCell, {
col: isBlack ? BOARD_MATRIX_RANGE_SIZE - 4 : 3,
group.pieces.forEach((piece) => {
group.setPieceCoord(piece.instanceId, this.boardComponent.instancedCell, {
col: 3,
row: isBlack ? BOARD_MATRIX_RANGE_SIZE - 1 : 0
});
});
Expand All @@ -154,14 +142,11 @@ export class PiecesComponent {
1,
this.resourceComponent.getGeometryByPieceType(PieceType.king)
);
const isBlack = color === ColorVariant.black;

Object.keys(group.pieces).forEach((id) => {
const piece = group.pieces[parseInt(id)];
if (!piece) return;
const isBlack = piece.color === ColorVariant.black;

group.setPieceCoord(piece.id, this.boardComponent.instancedCell, {
col: isBlack ? BOARD_MATRIX_RANGE_SIZE - 5 : 4,
group.pieces.forEach((piece) => {
group.setPieceCoord(piece.instanceId, this.boardComponent.instancedCell, {
col: 4,
row: isBlack ? BOARD_MATRIX_RANGE_SIZE - 1 : 0
});
});
Expand Down Expand Up @@ -196,23 +181,32 @@ export class PiecesComponent {
}

public initPieces() {
const createGroup = <C extends ColorVariant = ColorVariant>(color: C) => ({
[PieceType.pawn]: this._initPawns(color),
[PieceType.rock]: this._initRocks(color),
[PieceType.knight]: this._initKnights(color),
[PieceType.bishop]: this._initBishops(color),
[PieceType.queen]: this._initQueens(color),
[PieceType.king]: this._initKings(color)
});

const createDroppedGroup = () => ({
[PieceType.pawn]: [],
[PieceType.rock]: [],
[PieceType.knight]: [],
[PieceType.bishop]: [],
[PieceType.queen]: [],
[PieceType.king]: []
});

this.groups = {
[ColorVariant.black]: {
[PieceType.pawn]: this._initPawns(ColorVariant.black),
[PieceType.rock]: this._initRocks(ColorVariant.black),
[PieceType.bishop]: this._initBishops(ColorVariant.black),
[PieceType.knight]: this._initKnights(ColorVariant.black),
[PieceType.queen]: this._initQueens(ColorVariant.black),
[PieceType.king]: this._initKings(ColorVariant.black)
},
[ColorVariant.white]: {
[PieceType.pawn]: this._initPawns(ColorVariant.white),
[PieceType.rock]: this._initRocks(ColorVariant.white),
[PieceType.bishop]: this._initBishops(ColorVariant.white),
[PieceType.knight]: this._initKnights(ColorVariant.white),
[PieceType.queen]: this._initQueens(ColorVariant.white),
[PieceType.king]: this._initKings(ColorVariant.white)
}
[ColorVariant.black]: createGroup(ColorVariant.black),
[ColorVariant.white]: createGroup(ColorVariant.white)
};

this.droppedGroups = {
[ColorVariant.black]: createDroppedGroup(),
[ColorVariant.white]: createDroppedGroup()
};
}

Expand Down Expand Up @@ -249,7 +243,7 @@ export class PiecesComponent {
Color extends ColorVariant
>(piece: MatrixPieceModel<Type, Color>, position: Vector3Like) {
this.groups?.[piece.color]?.[piece.type]?.setPiecePosition(
piece.id,
piece.instanceId,
position
);
}
Expand All @@ -259,7 +253,7 @@ export class PiecesComponent {
coord: BoardCoord
) {
this.groups?.[piece.color]?.[piece.type]?.setPieceCoord(
piece.id,
piece.instanceId,
this.boardComponent.instancedCell,
coord
);
Expand All @@ -271,17 +265,45 @@ export class PiecesComponent {
const piecesGroup = this.groups?.[piece.color]?.[piece.type];
const pieces = piecesGroup?.pieces;

if (!pieces || !pieces[piece.id]) return;
if (
!piecesGroup ||
!(pieces?.[piece.instanceId] instanceof MatrixPieceModel)
)
return undefined;

const newGroup = piecesGroup.dropPiece(
piece.id,
piece.instanceId,
this.physics
) as unknown as InstancedPieceModel<Type, Color> | undefined;

if (!newGroup) return;
if (!newGroup) return undefined;

this.setGroupType(piece.type, piece.color, newGroup);

return pieces[piece.id] as MatrixPieceModel<Type, Color> | undefined;
return piece;
}

public promotePiece<Color extends ColorVariant, ToType extends PieceType>(
piece: MatrixPieceModel<PieceType.pawn, Color>,
toPiece: ToType
) {
const promotedPieceGroup = this.groups?.[piece.color]?.[
toPiece
] as unknown as InstancedPieceModel<ToType, Color>;
const droppedPiecesGroup =
this.droppedGroups?.[piece.color]?.[PieceType.pawn];
const droppedPiece = this.dropPiece(piece);

if (!droppedPiece || !droppedPiecesGroup || !promotedPieceGroup) return;

const newPiece = new MatrixPieceModel(
toPiece,
piece.color,
piece.instanceId,
piece.type
);

promotedPieceGroup.createPiece(newPiece, this.physics);
droppedPiecesGroup.push(droppedPiece);
}
}
4 changes: 3 additions & 1 deletion apps/web/src/core/pieces/pieces.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ export class PiecesController {
if (
typeof intersection?.instanceId !== "number" ||
!(instancedPiece instanceof InstancedPieceModel) ||
!(piece = instancedPiece.getPieceByIndex(intersection.instanceId))
!(piece = instancedPiece.getPieceByInstanceId(
intersection.instanceId
))
)
return undefined as any;

Expand Down
Loading

0 comments on commit db47129

Please sign in to comment.