Skip to content

Commit

Permalink
Merge pull request #61 from BlazingTwist/39-hex2p-implementieren
Browse files Browse the repository at this point in the history
39 hex2p implementieren
  • Loading branch information
BlazingTwist authored Jan 28, 2024
2 parents aa9703b + f97ef53 commit c1a062f
Show file tree
Hide file tree
Showing 26 changed files with 563 additions and 103 deletions.
40 changes: 38 additions & 2 deletions src/main/java/jchess/common/BaseChessGame.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import dx.schema.types.MarkerType;
import dx.schema.types.PieceType;
import jchess.common.components.MarkerComponent;
import jchess.common.components.PieceComponent;
import jchess.common.components.PieceIdentifier;
import jchess.common.components.TileComponent;
import jchess.common.events.BoardClickedEvent;
import jchess.common.events.BoardInitializedEvent;
Expand Down Expand Up @@ -73,6 +75,8 @@ public void revertState() {

protected abstract Entity getEntityAtPosition(int x, int y);

protected abstract int getDirectionFromOwnerId(int ownerId);

protected void onBoardClicked(int x, int y) {
Entity clickedEntity = getEntityAtPosition(x, y);
if (clickedEntity == null) {
Expand All @@ -90,7 +94,11 @@ protected void onBoardClicked(int x, int y) {
if (clickedMarker.onMarkerClicked != null) {
clickedMarker.onMarkerClicked.run();
}
} else if (clickedEntity.piece != null) {
eventManager.getEvent(RenderEvent.class).fire(null);
return;
}

if (clickedEntity.piece != null) {
long startTime = System.currentTimeMillis();

// show the tiles this piece can move to
Expand All @@ -100,7 +108,9 @@ protected void onBoardClicked(int x, int y) {

long endTime = System.currentTimeMillis();
logger.info("Computing valid moves with kingCheck took {} ms", endTime - startTime);
} else if (clickedEntity.tile != null) {
}

if (clickedEntity.tile != null) {
// show which pieces can move to the selected tile
for (Entity attacker : clickedEntity.tile.attackingPieces) {
createMoveFromMarker(attacker);
Expand Down Expand Up @@ -212,6 +222,20 @@ protected MateResult computeMateResult() {
}
}

protected void placePiece(Entity tile, int ownerId, int direction, PieceStore.IPieceDefinitionProvider pieceProvider) {
PieceStore.PieceDefinition pieceDefinition = pieceProvider.getPieceDefinition();
PieceIdentifier pieceIdentifier = new PieceIdentifier(
pieceProvider.getPieceType(),
pieceDefinition.shortName(),
ownerId,
direction
);

PieceComponent pieceComp = new PieceComponent(this, pieceIdentifier, pieceDefinition.baseMoves());
pieceComp.addSpecialMoves(pieceDefinition.specialRules());
tile.piece = pieceComp;
}

@Override
public void start() {
generateBoard();
Expand Down Expand Up @@ -241,6 +265,18 @@ public int getActivePlayerId() {
return activePlayerId;
}

@Override
public void createPiece(Entity targetTile, PieceType pieceType, int ownerId) {
PieceStore.IPieceDefinitionProvider pieceProvider = pieceStore.getPiece(pieceType);
if (pieceProvider == null) {
logger.error("unable to place piece with pieceType '" + pieceType + "'. PieceType does not exist.");
return;
}

int direction = getDirectionFromOwnerId(ownerId);
placePiece(targetTile, ownerId, direction, pieceProvider);
}

@Override
public int getNumPlayers() {
return numPlayers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import jchess.ecs.Entity;
import jchess.el.CompiledTileExpression;
import jchess.el.v2.ExpressionCompiler;

import java.util.Set;
import java.util.stream.Stream;

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/jchess/gamemode/GameModeStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import dx.schema.types.LayoutId;
import jchess.common.IChessGame;
import jchess.gamemode.hex2p.Hex2pPieceLayouts;
import jchess.gamemode.hex2p.Hex2pPieces;
import jchess.gamemode.hex2p.Hex2PlayerGame;
import jchess.gamemode.hex3p.Hex3PlayerGame;
import jchess.gamemode.hex3p.Hex3pPieceLayouts;
import jchess.gamemode.hex3p.Hex3pPieces;
Expand All @@ -25,6 +28,13 @@ public class GameModeStore {
));
}

for (Hex2pPieceLayouts pieceLayout : Hex2pPieceLayouts.values()) {
gameModeProviders.put(LayoutId.HEX_2_P.name() + "." + pieceLayout.name(), new GameModeProvider(
Hex2PlayerGame::new, LayoutId.HEX_2_P, "2 Player Hexagonal Chess - " + pieceLayout.name(), 2,
new PieceStore(Hex2pPieces.values()), pieceLayout
));
}

for (Square2pPieceLayouts pieceLayout : Square2pPieceLayouts.values()) {
gameModeProviders.put(LayoutId.SQUARE_2_P.name() + "." + pieceLayout.name(), new GameModeProvider(
Square2PlayerGame::new, LayoutId.SQUARE_2_P, "2 Player Classic Chess - " + pieceLayout.name(), 2,
Expand Down
100 changes: 100 additions & 0 deletions src/main/java/jchess/gamemode/hex2p/Hex2PlayerGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package jchess.gamemode.hex2p;

import dx.schema.types.Vector2I;
import jchess.common.BaseChessGame;
import jchess.common.components.TileComponent;
import jchess.ecs.Entity;
import jchess.gamemode.IPieceLayoutProvider;
import jchess.gamemode.PieceStore;

import java.awt.Point;
import java.util.Arrays;
import java.util.Objects;

public class Hex2PlayerGame extends BaseChessGame {

private static final int numTilesHorizontal = 6 + 5;

private static final int numTilesVertical = 21;

private final Entity[][] tiles = new Entity[numTilesVertical][numTilesHorizontal];

public Hex2PlayerGame(PieceStore pieceStore, IPieceLayoutProvider layoutProvider) {
super(2, pieceStore, layoutProvider);
}

@Override
public dx.schema.types.Entity applyPerspective(dx.schema.types.Entity tile, int playerIndex) {
if (playerIndex < 0 || playerIndex > 1) {
throw new IllegalArgumentException("playerIndex must be 0 or 1, but was " + playerIndex);
}
if (playerIndex == 0) return tile;
if (tile == null || tile.getTile() == null || tile.getTile().getDisplayPos() == null) return tile;

Vector2I displayPos = tile.getTile().getDisplayPos();
displayPos.setX(numTilesHorizontal - displayPos.getX());
displayPos.setY(numTilesVertical - displayPos.getY());
return tile;
}

@Override
protected Entity getEntityAtPosition(int x, int y) {
if (x < 0 || x >= numTilesHorizontal) return null;
if (y < 0 || y >= numTilesVertical) return null;

return tiles[y][x];
}

@Override
protected int getDirectionFromOwnerId(int ownerId) {
return ownerId == 0 ? 0 : 180;
}

@Override
protected void generateBoard() {
for (int y = 0; y < numTilesVertical; y++) {
Entity[] tileRow = tiles[y];
final int x0;
final int x1;

if (y < 5) { // top part
x0 = 5 - y;
x1 = x0 + 2 * (y + 1);
} else if (y < 16) { // middle part
x0 = (y % 2 == 0) ? 1 : 0;
x1 = numTilesHorizontal;
} else { // bottom part
x0 = y - 15;
x1 = x0 + (6 - x0) * 2;
}

for (int x = x0; x < x1; x += 2) {
tileRow[x] = entityManager.createEntity();
tileRow[x].tile = new TileComponent(new Point(x, y), y % 3);
}
}

// second pass: generate neighbors
Arrays.stream(tiles).flatMap(Arrays::stream)
.filter(Objects::nonNull)
.forEach(entity -> {
TileComponent tile = entity.tile;
assert tile != null;
int x = tile.position.x;
int y = tile.position.y;
tile.neighborsByDirection.put(0, getEntityAtPosition(x, y - 2));
tile.neighborsByDirection.put(30, getEntityAtPosition(x + 1, y - 3));
tile.neighborsByDirection.put(60, getEntityAtPosition(x + 1, y - 1));
tile.neighborsByDirection.put(90, getEntityAtPosition(x + 2, y));
tile.neighborsByDirection.put(120, getEntityAtPosition(x + 1, y + 1));
tile.neighborsByDirection.put(150, getEntityAtPosition(x + 1, y + 3));
tile.neighborsByDirection.put(180, getEntityAtPosition(x, y + 2));
tile.neighborsByDirection.put(210, getEntityAtPosition(x - 1, y + 3));
tile.neighborsByDirection.put(240, getEntityAtPosition(x - 1, y + 1));
tile.neighborsByDirection.put(270, getEntityAtPosition(x - 2, y));
tile.neighborsByDirection.put(300, getEntityAtPosition(x - 1, y - 1));
tile.neighborsByDirection.put(330, getEntityAtPosition(x - 1, y - 3));
});
}

}
149 changes: 149 additions & 0 deletions src/main/java/jchess/gamemode/hex2p/Hex2pPieceLayouts.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package jchess.gamemode.hex2p;

import jchess.common.IChessGame;
import jchess.ecs.Entity;
import jchess.gamemode.IPieceLayoutProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.BiFunction;

public enum Hex2pPieceLayouts implements IPieceLayoutProvider {
Standard((game, tileProvider) -> populateStandardBoard(new BoardController(game, tileProvider))),
Custom((game, tileProvider) -> populateCustomBoard(new BoardController(game, tileProvider))),
;

private static final int PLAYER_LIGHT = 0;
private static final int PLAYER_DARK = 1;

private static final Logger logger = LoggerFactory.getLogger(Hex2pPieceLayouts.class);

public final IPieceLayoutProvider layoutProvider;

Hex2pPieceLayouts(IPieceLayoutProvider layoutProvider) {
this.layoutProvider = layoutProvider;
}

@Override
public void placePieces(IChessGame game, BiFunction<Integer, Integer, Entity> tileProvider) {
layoutProvider.placePieces(game, tileProvider);
}

private static void populateStandardBoard(BoardController boardController) {
// place kings
boardController.placeKing(6, 19, PLAYER_LIGHT);
boardController.placeKing(6, 1, PLAYER_DARK);

// place queens
boardController.placeQueen(4, 19, PLAYER_LIGHT);
boardController.placeQueen(4, 1, PLAYER_DARK);


// place bishops
for (int i = 0; i <= 4; i+=2) {
boardController.placeBishop(5, i, PLAYER_DARK);
boardController.placeBishop(5, 20 - i, PLAYER_LIGHT);
}

// place knights
for (int x : new int[]{3, 7}) {
boardController.placeKnight(x,18, PLAYER_LIGHT);
boardController.placeKnight(x,2, PLAYER_DARK);
}

// place rooks
for (int x : new int[] {2, 8}) {
boardController.placeRook(x,17, PLAYER_LIGHT);
boardController.placeRook(x,3, PLAYER_DARK);
}


// place pawns
for (int i = 0; i < 5; i++) {
for (int x : new int[] {1+i, 9-i}) {
boardController.placePawn(x, 16 - i, PLAYER_LIGHT);
boardController.placePawn(x, 4 + i, PLAYER_DARK);
}
}
}

private static void populateCustomBoard(BoardController boardController) {
populateStandardBoard(boardController);

boardController.placeArcher(4,15, PLAYER_LIGHT);
boardController.placeArcher(6,15, PLAYER_LIGHT);
boardController.placeArcher(4,5, PLAYER_DARK);
boardController.placeArcher(6,5, PLAYER_DARK);

boardController.placePegasus(5,14, PLAYER_LIGHT);
boardController.placePegasus(5,6, PLAYER_DARK);

boardController.placeSkrull(3,16, PLAYER_LIGHT);
boardController.placeSkrull(7,16, PLAYER_LIGHT);
boardController.placeSkrull(3,4, PLAYER_DARK);
boardController.placeSkrull(7,4, PLAYER_DARK);

boardController.placeCatapult(4,17, PLAYER_LIGHT);
boardController.placeCatapult(6,17, PLAYER_LIGHT);
boardController.placeCatapult(4,3, PLAYER_DARK);
boardController.placeCatapult(6,3, PLAYER_DARK);

}

@SuppressWarnings("SameParameterValue")
private record BoardController(IChessGame game, BiFunction<Integer, Integer, Entity> tileProvider) {

private Entity getEntityAtPosition(int x, int y) {
return tileProvider.apply(x, y);
}

private void placeRook(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Rook);
}

private void placeKnight(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Knight);
}

private void placeBishop(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Bishop);
}

private void placeQueen(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Queen);
}

private void placeKing(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.King);
}

private void placePawn(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Pawn);
}

private void placeArcher(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Archer);
}

private void placePegasus(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Pegasus);
}

private void placeSkrull(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Skrull);
}

private void placeCatapult(int x, int y, int playerColor) {
placePiece(x, y, playerColor, Hex2pPieces.Catapult);
}

private void placePiece(int x, int y, int playerColor, Hex2pPieces piece) {
Entity tile = getEntityAtPosition(x, y);
if (tile == null) {
logger.error("cannot place piece on tile ({}, {}). No tile found.", x, y);
return;
}
game.createPiece(tile, piece.getPieceType(), playerColor);
}
}
}
Loading

0 comments on commit c1a062f

Please sign in to comment.