help
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package chess;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// An actor is an entity capable of making descisions on the board.
|
||||
abstract class Actor {
|
||||
Util.Col col; // The color the Actor is acting as.
|
||||
|
@@ -41,6 +41,11 @@ class Board {
|
||||
Util.scale, Util.scale, OutlineMode.SOLID,
|
||||
new Color(0, 150, 200, 150)
|
||||
);
|
||||
else if (info == Info.PROMOTION)
|
||||
infoImage = new RectangleImage(
|
||||
Util.scale, Util.scale, OutlineMode.SOLID,
|
||||
new Color(200, 50, 200, 150)
|
||||
);
|
||||
|
||||
scene.placeImageXY(
|
||||
new OverlayImage(
|
||||
@@ -64,6 +69,22 @@ class Board {
|
||||
);
|
||||
}
|
||||
|
||||
// Check for a pawn eligible for promotion.
|
||||
boolean isPawnPromotionPosition(Coord coord, Piece piece) {
|
||||
if (piece == null || piece.type != PieceType.PAWN) return false;
|
||||
|
||||
boolean isPromotionPosition =
|
||||
(piece.col == Util.Col.WHITE && coord.y == 0) ||
|
||||
(piece.col == Util.Col.BLACK && coord.y == 7);
|
||||
|
||||
return isPromotionPosition;
|
||||
}
|
||||
|
||||
// Display promotion dialog.
|
||||
void displayPromotionOptions(Coord coord) {
|
||||
this.info.put(coord, Info.PROMOTION);
|
||||
}
|
||||
|
||||
WorldImage drawPiece(Piece piece) {
|
||||
return (piece == null) ? new EmptyImage() : piece.draw();
|
||||
}
|
||||
@@ -105,6 +126,15 @@ class Board {
|
||||
|
||||
this.drop(targ);
|
||||
this.set(dest, piece);
|
||||
|
||||
// Check if a pawn needs promotion.
|
||||
if (piece.type == PieceType.PAWN &&
|
||||
isPawnPromotionPosition(dest, piece)) {
|
||||
// Hold turn til promotion complete.
|
||||
this.game.setAwaitingPromotion(dest);
|
||||
return;
|
||||
}
|
||||
|
||||
this.game.changeActive();
|
||||
}
|
||||
|
||||
@@ -115,6 +145,31 @@ class Board {
|
||||
return piece.moves(coord, this);
|
||||
}
|
||||
|
||||
// Promote pawn to type.
|
||||
void promotePawn(Coord pawnPos, PieceType promotionType) {
|
||||
Piece pawn = this.get(pawnPos);
|
||||
if (pawn == null || pawn.type != PieceType.PAWN) return;
|
||||
|
||||
Util.Col color = pawn.col;
|
||||
Piece newPiece = null;
|
||||
|
||||
switch (promotionType) {
|
||||
case QUEEN: newPiece = new Queen(color); break;
|
||||
case ROOK: newPiece = new Rook(color); break;
|
||||
case BISHOP: newPiece = new Bishop(color); break;
|
||||
case KNIGHT: newPiece = new Knight(color); break;
|
||||
default: newPiece = new Queen(color); // Default queen because best.
|
||||
}
|
||||
|
||||
// Replace pawn with new piece.
|
||||
this.set(pawnPos, newPiece);
|
||||
|
||||
// Clear promotion indicator.
|
||||
this.info.remove(pawnPos);
|
||||
|
||||
this.game.promotionComplete();
|
||||
}
|
||||
|
||||
// Is the selected space free? (either nothing there, or an enemy piece).
|
||||
boolean isFree(Coord coord, Util.Col col) {
|
||||
return this.get(coord) == null || this.get(coord).col != col;
|
||||
@@ -234,7 +289,7 @@ class Board {
|
||||
}
|
||||
|
||||
// Information layered over the board.
|
||||
enum Info { CANMOVE, WARN, SELECTED }
|
||||
enum Info { CANMOVE, WARN, SELECTED, PROMOTION }
|
||||
|
||||
// Measured from top left.
|
||||
class Coord {
|
||||
|
@@ -11,6 +11,8 @@ class Game extends World {
|
||||
WorldScene scene;
|
||||
Actor activeActor;
|
||||
Actor winner;
|
||||
Coord awaitingPromotion; // Tracks pawn awaiting promotion.
|
||||
boolean promotionMode; // Whether game is in special promotion mode.
|
||||
|
||||
Game(Actor white, Actor black, Board board) {
|
||||
this.white = white;
|
||||
@@ -18,6 +20,8 @@ class Game extends World {
|
||||
this.board = board;
|
||||
this.activeActor = this.white;
|
||||
this.winner = null;
|
||||
this.awaitingPromotion = null;
|
||||
this.promotionMode = false;
|
||||
}
|
||||
|
||||
Game() {
|
||||
@@ -26,6 +30,8 @@ class Game extends World {
|
||||
this.black = new Player(Util.Col.BLACK, this.board);
|
||||
this.activeActor = this.white;
|
||||
this.winner = null;
|
||||
this.awaitingPromotion = null;
|
||||
this.promotionMode = false;
|
||||
|
||||
this.setup();
|
||||
}
|
||||
@@ -53,14 +59,30 @@ class Game extends World {
|
||||
Util.scale * 4, 3 * Util.scale
|
||||
);
|
||||
} else {
|
||||
this.scene.placeImageXY(
|
||||
new TextImage(
|
||||
(this.activeActor.equals(this.white) ? "white" : "black") +
|
||||
"'s turn",
|
||||
Util.scale / 2, Color.red
|
||||
),
|
||||
Util.scale * 2, 3 * Util.scale
|
||||
);
|
||||
if (this.promotionMode) {
|
||||
this.scene.placeImageXY(
|
||||
new TextImage(
|
||||
"PROMOTE: [Q]ueen; [R]ook; [B]ishop; "
|
||||
+ "K[N]ight",
|
||||
Util.scale / 3, Color.magenta
|
||||
),
|
||||
Util.scale * 4, 3 * Util.scale
|
||||
);
|
||||
|
||||
// Highlight pawn being promoted.
|
||||
if (this.awaitingPromotion != null) {
|
||||
this.board.displayPromotionOptions(this.awaitingPromotion);
|
||||
}
|
||||
} else {
|
||||
this.scene.placeImageXY(
|
||||
new TextImage(
|
||||
(this.activeActor.equals(this.white) ? "white" : "black"
|
||||
) + "'s turn",
|
||||
Util.scale / 2, Color.red
|
||||
),
|
||||
Util.scale * 2, 3 * Util.scale
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,12 +161,16 @@ class Game extends World {
|
||||
|
||||
public void onMouseClicked(Posn posn) {
|
||||
// Process clicks if game not over.
|
||||
if (this.winner == null) this.activeActor.click(this.where(posn));
|
||||
if (this.winner == null && !this.promotionMode)
|
||||
this.activeActor.click(this.where(posn));
|
||||
}
|
||||
|
||||
public void onKeyEvent(String key) {
|
||||
// Process keys if game is not over.
|
||||
if (this.winner == null) this.activeActor.key(key);
|
||||
if (this.winner == null) {
|
||||
if (this.promotionMode) handlePromotionKey(key);
|
||||
else this.activeActor.key(key);
|
||||
}
|
||||
}
|
||||
|
||||
void changeActive() {
|
||||
@@ -152,12 +178,41 @@ class Game extends World {
|
||||
else this.activeActor = this.white;
|
||||
}
|
||||
|
||||
void setWinner(Actor winner) {
|
||||
this.winner = winner;
|
||||
System.out.println(
|
||||
(winner.equals(this.white) ? "WHITE" : "BLACK") + " WINS!"
|
||||
);
|
||||
// Enter promotion mode.
|
||||
void setAwaitingPromotion(Coord pawnPos) {
|
||||
this.awaitingPromotion = pawnPos;
|
||||
this.promotionMode = true;
|
||||
this.board.displayPromotionOptions(pawnPos);
|
||||
}
|
||||
|
||||
// Promotion selection key.
|
||||
void handlePromotionKey(String key) {
|
||||
if (this.awaitingPromotion == null) return;
|
||||
|
||||
PieceType promotionType = null;
|
||||
|
||||
switch (key.toLowerCase()) {
|
||||
case "q": promotionType = PieceType.QUEEN; break;
|
||||
case "r": promotionType = PieceType.ROOK; break;
|
||||
case "b": promotionType = PieceType.BISHOP; break;
|
||||
case "n":
|
||||
promotionType = PieceType.KNIGHT;
|
||||
break; // N for knight because K already taken for vim keys :P.
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (promotionType != null)
|
||||
this.board.promotePawn(this.awaitingPromotion, promotionType);
|
||||
}
|
||||
|
||||
// Called when promotion is complete.
|
||||
void promotionComplete() {
|
||||
this.awaitingPromotion = null;
|
||||
this.promotionMode = false;
|
||||
this.changeActive();
|
||||
}
|
||||
|
||||
void setWinner(Actor winner) { this.winner = winner; }
|
||||
|
||||
boolean isGameOver() { return this.winner != null; }
|
||||
}
|
||||
|
@@ -56,6 +56,12 @@ class Pawn extends Piece {
|
||||
|
||||
return moves;
|
||||
}
|
||||
|
||||
// Check if pawn in promotion position.
|
||||
boolean canPromote(Coord coord) {
|
||||
return (this.col == Util.Col.WHITE && coord.y == 0) ||
|
||||
(this.col == Util.Col.BLACK && coord.y == Util.boardW - 1);
|
||||
}
|
||||
}
|
||||
|
||||
class Rook extends Piece {
|
||||
@@ -121,12 +127,6 @@ class Bishop extends Piece {
|
||||
|
||||
ArrayList<Coord> moves(Coord coord, Board board) {
|
||||
ArrayList<Coord> moves = new ArrayList<Coord>();
|
||||
/*
|
||||
for (int i = -7; i < 8; i++) {
|
||||
if (i == 0) continue; // Can't move to own position.
|
||||
moves.add(new Coord(coord.x + i, coord.y + i));
|
||||
moves.add(new Coord(coord.x + i, coord.y - i));
|
||||
}*/
|
||||
ArrayList<Coord> ne = board.getLineDiagNE(coord, this.col);
|
||||
ArrayList<Coord> nw = board.getLineDiagNW(coord, this.col);
|
||||
ArrayList<Coord> se = board.getLineDiagSE(coord, this.col);
|
||||
|
@@ -2,11 +2,15 @@ package chess;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// A human-controlled Actor."
|
||||
// A human-controlled Actor.
|
||||
class Player extends Actor {
|
||||
Coord selected; // The currently selected piece.
|
||||
Coord selected; // The currently selected piece.
|
||||
Coord promotionPending; // Tracks if in a promotion.
|
||||
|
||||
Player(Util.Col col, Board board) { super(col, board); }
|
||||
Player(Util.Col col, Board board) {
|
||||
super(col, board);
|
||||
this.promotionPending = null;
|
||||
}
|
||||
|
||||
void click(Coord coord) {
|
||||
Piece piece = this.board.get(coord);
|
||||
@@ -34,6 +38,17 @@ class Player extends Actor {
|
||||
System.out.println(
|
||||
"clicked on moveable space with something selected"
|
||||
);
|
||||
// Check if this is a pawn that'll be promoted.
|
||||
Piece movingPiece = this.board.get(this.selected);
|
||||
boolean isPawnPromotion = false;
|
||||
|
||||
if (movingPiece != null && movingPiece.type == PieceType.PAWN) {
|
||||
isPawnPromotion =
|
||||
(movingPiece.col == Util.Col.WHITE && coord.y % 7 == 0
|
||||
); // Check if on end of board; modulo is nice here.
|
||||
if (isPawnPromotion) this.promotionPending = coord;
|
||||
}
|
||||
|
||||
this.board.move(this.selected, coord);
|
||||
this.board.unselect(this.selected);
|
||||
this.board.undisplayMoves(moves);
|
||||
@@ -58,9 +73,16 @@ class Player extends Actor {
|
||||
}
|
||||
|
||||
void key(String key) {
|
||||
// Not my problem.
|
||||
if (this.promotionPending != null) return;
|
||||
|
||||
if (this.selected == null) return;
|
||||
|
||||
this.board.undisplayMoves(this.board.getMoves(this.selected));
|
||||
this.board.unselect(this.selected);
|
||||
this.selected = null;
|
||||
}
|
||||
|
||||
// Call when promotion complete.
|
||||
void clearPromotionPending() { this.promotionPending = null; }
|
||||
}
|
||||
|
Reference in New Issue
Block a user