change cpp for js
This commit is contained in:
parent
4b49500317
commit
eabc7dbaff
18 changed files with 215 additions and 312 deletions
6
Makefile
6
Makefile
|
|
@ -0,0 +1,6 @@
|
|||
all: docker
|
||||
|
||||
docker:
|
||||
docker-compose -f deploy/docker-compose.dev.yml up --build -d
|
||||
@echo "Frontend is running at http://localhost:3000"
|
||||
@echo "Backend is running at http://localhost:4000"
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef BOARD_HPP
|
||||
#define BOARD_HPP
|
||||
|
||||
#include <vector>
|
||||
#include "cell.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
class Board {
|
||||
private:
|
||||
int width;
|
||||
int height;
|
||||
std::vector<std::vector<Cell>> grid;
|
||||
|
||||
public:
|
||||
Board(int w, int h) : width(w), height(h), grid(h, std::vector<Cell>(w)) {}
|
||||
int getWidth() const { return width; }
|
||||
int getHeight() const { return height; }
|
||||
Cell& getCell(int x, int y) { return grid[y][x]; }
|
||||
void setPiece(int x, int y, const Piece& piece) {
|
||||
grid[y][x].pieceId = std::make_shared<Piece>(piece);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
||||
82
engine/core/board.js
Normal file
82
engine/core/board.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import Cell from './cell.js';
|
||||
|
||||
class Board {
|
||||
/**
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
*/
|
||||
constructor(width, height) {
|
||||
/** @type {number} */
|
||||
this.width = width;
|
||||
/** @type {number} */
|
||||
this.height = height;
|
||||
/** @type {Cell[][]} */
|
||||
this.grid = Array.from({ length: height }, () => Array.from({ length: width }, () => new Cell()));
|
||||
|
||||
this.setupInitialPieces();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @returns {Cell}
|
||||
*/
|
||||
getCell(x, y) {
|
||||
return this.grid[y][x];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {Piece|null} piece
|
||||
*/
|
||||
setPiece(x, y, piece) {
|
||||
this.grid[y][x].piece = piece;
|
||||
}
|
||||
|
||||
setupInitialPieces() {
|
||||
// Pawns
|
||||
for (let x = 0; x < this.width; x++) {
|
||||
this.setPiece(x, 1, new Piece(PieceColor.WHITE, PieceType.PAWN));
|
||||
this.setPiece(x, 6, new Piece(PieceColor.BLACK, PieceType.PAWN));
|
||||
}
|
||||
|
||||
// Rooks
|
||||
this.setPiece(0, 0, new Piece(PieceColor.WHITE, PieceType.ROOK));
|
||||
this.setPiece(7, 0, new Piece(PieceColor.WHITE, PieceType.ROOK));
|
||||
this.setPiece(0, 7, new Piece(PieceColor.BLACK, PieceType.ROOK));
|
||||
this.setPiece(7, 7, new Piece(PieceColor.BLACK, PieceType.ROOK));
|
||||
|
||||
// Knights
|
||||
this.setPiece(1, 0, new Piece(PieceColor.WHITE, PieceType.KNIGHT));
|
||||
this.setPiece(6, 0, new Piece(PieceColor.WHITE, PieceType.KNIGHT));
|
||||
this.setPiece(1, 7, new Piece(PieceColor.BLACK, PieceType.KNIGHT));
|
||||
this.setPiece(6, 7, new Piece(PieceColor.BLACK, PieceType.KNIGHT));
|
||||
|
||||
// Bishops
|
||||
this.setPiece(2, 0, new Piece(PieceColor.WHITE, PieceType.BISHOP));
|
||||
this.setPiece(5, 0, new Piece(PieceColor.WHITE, PieceType.BISHOP));
|
||||
this.setPiece(2, 7, new Piece(PieceColor.BLACK, PieceType.BISHOP));
|
||||
this.setPiece(5, 7, new Piece(PieceColor.BLACK, PieceType.BISHOP));
|
||||
|
||||
// Queens and Kings
|
||||
this.setPiece(3, 0, new Piece(PieceColor.WHITE, PieceType.QUEEN));
|
||||
this.setPiece(4, 0, new Piece(PieceColor.WHITE, PieceType.KING));
|
||||
this.setPiece(3, 7, new Piece(PieceColor.BLACK, PieceType.QUEEN));
|
||||
this.setPiece(4, 7, new Piece(PieceColor.BLACK, PieceType.KING));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef CELL_HPP
|
||||
#define CELL_HPP
|
||||
|
||||
#include "piece.hpp"
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct Cell {
|
||||
std::optional<std::shared_ptr<Piece>> piece;
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
||||
9
engine/core/cell.js
Normal file
9
engine/core/cell.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class Cell {
|
||||
/**
|
||||
* @param {Piece|null} piece
|
||||
*/
|
||||
constructor(piece = null) {
|
||||
/** @type {Piece|null} */
|
||||
this.piece = piece;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
#include "move.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct Event {
|
||||
std::string type; // e.g., "capture", "move", "promotion", "mine_triggered"
|
||||
std::string detail; // JSON or human-readable details
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
# include "game_state.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
GameState::GameState() : board(8, 8), whiteTeam(nullptr), blackTeam(nullptr), turn(0) {
|
||||
|
||||
// white pieces
|
||||
board.setPiece(0, 0, Piece(PieceColor::WHITE, PieceType::ROOK));
|
||||
board.setPiece(1, 0, Piece(PieceColor::WHITE, PieceType::KNIGHT));
|
||||
board.setPiece(2, 0, Piece(PieceColor::WHITE, PieceType::BISHOP));
|
||||
board.setPiece(3, 0, Piece(PieceColor::WHITE, PieceType::QUEEN));
|
||||
board.setPiece(4, 0, Piece(PieceColor::WHITE, PieceType::KING));
|
||||
board.setPiece(5, 0, Piece(PieceColor::WHITE, PieceType::BISHOP));
|
||||
board.setPiece(6, 0, Piece(PieceColor::WHITE, PieceType::KNIGHT));
|
||||
board.setPiece(7, 0, Piece(PieceColor::WHITE, PieceType::ROOK));
|
||||
|
||||
for (int x = 0; x < 8; ++x) {
|
||||
board.setPiece(x, 1, Piece(PieceColor::WHITE, PieceType::PAWN));
|
||||
}
|
||||
|
||||
// black pieces
|
||||
board.setPiece(0, 7, Piece(PieceColor::BLACK, PieceType::ROOK));
|
||||
board.setPiece(1, 7, Piece(PieceColor::BLACK, PieceType::KNIGHT));
|
||||
board.setPiece(2, 7, Piece(PieceColor::BLACK, PieceType::BISHOP));
|
||||
board.setPiece(3, 7, Piece(PieceColor::BLACK, PieceType::QUEEN));
|
||||
board.setPiece(4, 7, Piece(PieceColor::BLACK, PieceType::KING));
|
||||
board.setPiece(5, 7, Piece(PieceColor::BLACK, PieceType::BISHOP));
|
||||
board.setPiece(6, 7, Piece(PieceColor::BLACK, PieceType::KNIGHT));
|
||||
board.setPiece(7, 7, Piece(PieceColor::BLACK, PieceType::ROOK));
|
||||
|
||||
for (int x = 0; x < 8; ++x) {
|
||||
board.setPiece(x, 6, Piece(PieceColor::BLACK, PieceType::PAWN));
|
||||
}
|
||||
|
||||
whiteTeam = Team{std::make_shared<Piece>(board.getCell(4, 0).piece -> get() -> getColor(), board.getCell(4, 0).piece -> get() -> getType())};
|
||||
blackTeam = Team{std::make_shared<Piece>(board.getCell(4, 7).piece -> get() -> getColor(), board.getCell(4, 7).piece -> get() -> getType())};
|
||||
}
|
||||
GameState::~GameState() = default;
|
||||
|
||||
bool GameState::hasHisKing(PieceColor color) {
|
||||
if (color == PieceColor::WHITE) {
|
||||
return whiteTeam.king != nullptr;
|
||||
} else {
|
||||
return blackTeam.king != nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace engine
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include "piece.hpp"
|
||||
#include "move.hpp"
|
||||
#include "board.hpp"
|
||||
#include "team.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
class GameState {
|
||||
private:
|
||||
Board board;
|
||||
Team whiteTeam;
|
||||
Team blackTeam;
|
||||
int turn;
|
||||
|
||||
public:
|
||||
GameState();
|
||||
|
||||
Board getBoard() { return board; };
|
||||
Team getWhiteTeam() { return whiteTeam; };
|
||||
Team getBlackTeam() { return blackTeam; };
|
||||
int getTurn() { return turn; };
|
||||
void nextTurn() { turn = 1 - turn; };
|
||||
|
||||
bool hasHisKing(PieceColor color);
|
||||
bool isInCheck(PieceColor color);
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
56
engine/core/game_state.js
Normal file
56
engine/core/game_state.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
class GameState {
|
||||
constructor() {
|
||||
/** @type {Board} */
|
||||
this.board = new Board();
|
||||
/** @type {Team} */
|
||||
this.whiteTeam = new Team("white");
|
||||
/** @type {Team} */
|
||||
this.blackTeam = new Team("black");
|
||||
/** @type {number} */
|
||||
this.turn = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Board}
|
||||
*/
|
||||
getBoard() {
|
||||
return this.board;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Team}
|
||||
*/
|
||||
getWhiteTeam() {
|
||||
return this.whiteTeam;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Team}
|
||||
*/
|
||||
getBlackTeam() {
|
||||
return this.blackTeam;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
getTurn() {
|
||||
return this.turn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
nextTurn() {
|
||||
this.turn = 1 - this.turn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PieceColor} color
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasHisKing(color) {
|
||||
const team = color === PieceColor.WHITE ? this.whiteTeam : this.blackTeam;
|
||||
return team.hasKing();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "piece.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct Coord { int x; int y; };
|
||||
|
||||
enum class MoveActionKind {
|
||||
Move,
|
||||
Capture,
|
||||
Create,
|
||||
Remove,
|
||||
SetFlag
|
||||
};
|
||||
|
||||
struct MoveAction {
|
||||
MoveActionKind kind;
|
||||
Coord from;
|
||||
Coord to;
|
||||
std::optional<int> extra;
|
||||
};
|
||||
|
||||
enum class MoveType {
|
||||
Normal,
|
||||
Capture,
|
||||
Castling,
|
||||
Promotion,
|
||||
Multi,
|
||||
CardEffect
|
||||
};
|
||||
|
||||
struct Move {
|
||||
std::vector<MoveAction> actions;
|
||||
MoveType type = MoveType::Normal;
|
||||
int playerId = -1;
|
||||
std::string tag;
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "game_state.hpp"
|
||||
#include "move_result.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
class MoveApplier {
|
||||
public:
|
||||
MoveApplier();
|
||||
|
||||
MoveResult applyMove(GameState& state, const Move& move);
|
||||
MoveResult simulateApply(const GameState& state, const Move& move, GameState& outState) const;
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "move.hpp"
|
||||
#include "game_state.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
class MoveGenerator {
|
||||
public:
|
||||
MoveGenerator();
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "move.hpp"
|
||||
#include "events.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
enum class MoveStatus {
|
||||
Ok,
|
||||
Illegal,
|
||||
BlockedByCard,
|
||||
OutOfBounds,
|
||||
RequiresConfirmation
|
||||
};
|
||||
|
||||
struct MoveResult {
|
||||
MoveStatus status = MoveStatus::Ok;
|
||||
std::vector<Event> events;
|
||||
std::string reason;
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef PIECE_HPP
|
||||
#define PIECE_HPP
|
||||
|
||||
namespace engine {
|
||||
|
||||
enum class PieceColor {
|
||||
WHITE,
|
||||
BLACK
|
||||
};
|
||||
|
||||
enum class PieceType {
|
||||
PAWN,
|
||||
KNIGHT,
|
||||
BISHOP,
|
||||
ROOK,
|
||||
QUEEN,
|
||||
KING
|
||||
};
|
||||
|
||||
class Piece {
|
||||
private:
|
||||
PieceColor color;
|
||||
PieceType type;
|
||||
|
||||
public:
|
||||
Piece(PieceColor c, PieceType t) : color(c), type(t) {}
|
||||
|
||||
PieceColor getColor() const { return color; }
|
||||
PieceType getType() const { return type; }
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
||||
40
engine/core/piece.js
Normal file
40
engine/core/piece.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
const PieceColor = {
|
||||
WHITE: 'WHITE',
|
||||
BLACK: 'BLACK'
|
||||
};
|
||||
|
||||
const PieceType = {
|
||||
PAWN: 'PAWN',
|
||||
KNIGHT: 'KNIGHT',
|
||||
BISHOP: 'BISHOP',
|
||||
ROOK: 'ROOK',
|
||||
QUEEN: 'QUEEN',
|
||||
KING: 'KING'
|
||||
};
|
||||
|
||||
class Piece {
|
||||
/**
|
||||
* @param {PieceColor} color
|
||||
* @param {PieceType} type
|
||||
*/
|
||||
constructor(color, type) {
|
||||
/** @type {PieceColor} */
|
||||
this.color = color;
|
||||
/** @type {PieceType} */
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {PieceColor}
|
||||
*/
|
||||
getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {PieceType}
|
||||
*/
|
||||
getType() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef TEAM_HPP
|
||||
#define TEAM_HPP
|
||||
|
||||
#include "piece.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct Team {
|
||||
Team(std::shared_ptr<Piece> king) : king(king) {}
|
||||
|
||||
enum Type { WHITE, BLACK };
|
||||
std::shared_ptr<Piece> king;
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
||||
22
engine/core/team.js
Normal file
22
engine/core/team.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import Piece from './piece.js';
|
||||
import PieceColor from './piece.js';
|
||||
|
||||
class Team {
|
||||
/**
|
||||
* @param {PieceColor} color
|
||||
* @param {Piece} king
|
||||
*/
|
||||
constructor(color, king) {
|
||||
/** @type {PieceColor} */
|
||||
this.color = color;
|
||||
/** @type {Piece} */
|
||||
this.king = king;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasKing() {
|
||||
return this.king !== null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../core/game_state.hpp"
|
||||
#include "../core/move.hpp"
|
||||
#include "../core/move_result.hpp"
|
||||
#include "../core/move_generator.hpp"
|
||||
|
||||
namespace engine::plugins {
|
||||
|
||||
class EffectPlugin {
|
||||
public:
|
||||
virtual ~EffectPlugin() = default;
|
||||
|
||||
// modify the move generation step (can register extra moves)
|
||||
virtual void modifyMoveGeneration(const engine::GameState& state, engine::MoveGenerator& generator) {}
|
||||
|
||||
// hook before applying a move (can mutate the move or block it)
|
||||
virtual void onBeforeApply(engine::GameState& state, engine::Move& move, engine::MoveResult& out) {}
|
||||
|
||||
// hook after move applied
|
||||
virtual void onAfterApply(engine::GameState& state, const engine::Move& move, engine::MoveResult& out) {}
|
||||
};
|
||||
|
||||
} // namespace engine::plugins
|
||||
Loading…
Reference in a new issue