Chess generate possible moves king safe
Currently fooling around trying to piece together chess but I can't seem to find a easy way to reuse already existing code I have to solve it.
The problem lies with checking if possible move is safe or not. My thinking was going through each opposite piece and check if they can move to one of the squares the King can move to. But that does not work well. Tried several ways to either teach Pawn or King about each others but no success. Got every other piece working but those two working together nah! Board is using a 8x8 Array of Square that extends jButton.
How do I let the king know how to move around a Pawn while he is safe? Current problem is that the king is not safe at all and trying to resolve it seems to be iterator over the squares. But then how would you also go about defending the king against a piece by blocking.
Much like the rook. I want it to be able to see past the king piece or look for possible threaten square where the king could enter.
Though the pawn does not care at the moment and blocks the king for moving in front of a pawn but not to the aheadleft/aheadright depending on the color.
Any ideas on how to solve it?
Here is the solution.
Solved it by removing the king from his current location and checking his surronding squares and looking for matching PieceType to the fake piece in each square. Thus removing the fake piece & the square it was standing on from possible move if it found a matching PieceType opponent.
The king is smart enough now to dodge and attack a piece if no other piece is able to attack it after it attacks.
King:
@Override
public Collection<Square> generatePossibleMoves() {
possibleMoves.clear();
List<Square> moves = new ArrayList<>();
int[][] offsets = {
{1, 0},
{0, 1},
{-1, 0},
{0, -1},
{1, 1},
{-1, 1},
{-1, -1},
{1, -1}
};
for (int[] o : offsets) {
Square square = super.getSquare().neighbour(o[0], o[1]);
if (square != null && (square.getPiece() == null || isOpponent(square.getPiece()))) {
moves.add(square);
}
}
possibleMoves.addAll(moves);
if (getSquare().isSelected()) {
Piece[] pieces = {
PieceType.PAWN.create(getPieceColor()),
PieceType.ROOK.create(getPieceColor()),
PieceType.BISHOP.create(getPieceColor()),
PieceType.KNIGHT.create(getPieceColor()),
PieceType.QUEEN.create(getPieceColor()),
PieceType.KING.create(getPieceColor())};
Piece oldKing = this;
getSquare().removePiece();
for (Square kingMove : moves) {
if (kingMove.isEmpty()) {
for (Piece piece : pieces) {
piece.putPieceOnSquareFirstTime(kingMove);
piece.generatePossibleMoves();
for (Square enemy : piece.getPossibleMoves()) {
if (!enemy.isEmpty() && enemy.getPiece().isOpponent(piece) && enemy.getPiece().getTypeNumber() == piece.getTypeNumber()) {
enemy.setBackground(Color.BLUE);
possibleMoves.remove(kingMove);
break;
}
}
}
kingMove.removePiece();
} else if (isOpponent(kingMove.getPiece())) {
Piece oldPiece = kingMove.getPiece();
for (Piece piece : pieces) {
kingMove.removePiece();
piece.putPieceOnSquareFirstTime(kingMove);
piece.generatePossibleMoves();
for (Square square1 : piece.getPossibleMoves()) {
if (!square1.isEmpty() && square1.getPiece().isOpponent(piece) && square1.getPiece().getTypeNumber() == piece.getTypeNumber()) {
possibleMoves.remove(kingMove);
break;
}
}
}
kingMove.removePiece();
oldPiece.putPieceOnSquareFirstTime(kingMove);
}
}
oldKing.putPieceOnSquareFirstTime(getSquare());
}
return possibleMoves;
}
Bishop
@Override
public Collection<Square> generatePossibleMoves() {
int row = super.getSquare().ROW;
int column = super.getSquare().COLUMN;
possibleMoves.clear();
//all possible moves in the down positive diagonal
for (int j = column + 1, i = row + 1; j < Board.SIZE && i < Board.SIZE; j++, i++) {
Square square = super.getSquare().getBoardSquare(i, j);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves in the up positive diagonal
for (int j = column - 1, i = row + 1; j > -1 && i < Board.SIZE; j--, i++) {
Square square = super.getSquare().getBoardSquare(i, j);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves in the up negative diagonal
for (int j = column - 1, i = row - 1; j > -1 && i > -1; j--, i--) {
Square square = super.getSquare().getBoardSquare(i, j);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves in the down negative diagonal
for (int j = column + 1, i = row - 1; j < Board.SIZE && i > -1; j++, i--) {
Square square = super.getSquare().getBoardSquare(i, j);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
return possibleMoves;
}
Knight
@Override
public Collection<Square> generatePossibleMoves() {
possibleMoves.clear();
int[][] offsets = {
{-2, 1},
{-1, 2},
{1, 2},
{2, 1},
{2, -1},
{1, -2},
{-1, -2},
{-2, -1}
};
for (int[] o : offsets) {
Square square = super.getSquare().neighbour(o[0], o[1]);
if (square != null && (square.getPiece() == null || isOpponent(square.getPiece()))) {
possibleMoves.add(square);
}
}
return possibleMoves;
}
Rook
@Override
public Collection<Square> generatePossibleMoves() {
int row = super.getSquare().ROW;
int column = super.getSquare().COLUMN;
possibleMoves.clear();
//all possible moves in the up
for (int i = row + 1; i < Board.SIZE; i++) {
Square square = super.getSquare().getBoardSquare(i, column);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves in the down
for (int i = row - 1; i > -1; i--) {
Square square = super.getSquare().getBoardSquare(i, column);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves to the right
for (int i = column + 1; i < Board.SIZE; i++) {
Square square = super.getSquare().getBoardSquare(row, i);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves to the left
for (int i = column - 1; i > -1; i--) {
Square square = super.getSquare().getBoardSquare(row, i);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
return possibleMoves;
}
Queen
Moves exactly like the Rook and Bishop so why not reuse?
@Override
public Collection<Square> generatePossibleMoves() {
possibleMoves.clear();
Piece[] pieces = {
PieceType.ROOK.create(getPieceColor()),
PieceType.BISHOP.create(getPieceColor())
};
for (Piece piece : pieces) {
piece.setSquare(getSquare());
possibleMoves.addAll(piece.generatePossibleMoves());
}
return possibleMoves;
}
Pawn
@Override
public Collection<Square> generatePossibleMoves() {
possibleMoves.clear();
boolean color = super.isWhite();
int dx = color ? -1 : 1;
Square ahead = super.getSquare().neighbour(dx, 0);
if (ahead.getPiece() == null) {
possibleMoves.add(ahead);
if (super.getSquare().ROW == 6 && color) {
Square aheadsecond = super.getSquare().neighbour(dx - 1, 0);
if (aheadsecond.getPiece() == null) {
possibleMoves.add(aheadsecond);
}
} else if (super.getSquare().ROW == 1 && !color) {
Square aheadsecond = super.getSquare().neighbour(dx + 1, 0);
if (aheadsecond.getPiece() == null) {
possibleMoves.add(aheadsecond);
}
}
}
Square aheadLeft = super.getSquare().neighbour(dx, -1);
if (aheadLeft != null && aheadLeft.getPiece() != null && isOpponent(aheadLeft.getPiece())) {
possibleMoves.add(aheadLeft);
}
Square aheadRight = super.getSquare().neighbour(dx, 1);
if (aheadRight != null && aheadRight.getPiece() != null && isOpponent(aheadRight.getPiece())) {
possibleMoves.add(aheadRight);
}
return possibleMoves;
}
To generate the legal moves for the king, the simplest approach is:
Iterate through the 8 possible squares the king can move to.
At each square, pretend the king is one of the other pieces and check if it attacks an enemy piece. For example, we can branch out along the diagonals to see if we come across an enemy bishop. If we do, it's not legal to move to that square.
Collect the moves to the squares where the above check does not come across any enemy pieces.
This might be more verbose in an 8x8 array system, requiring a good amount of similar code, but it is far more efficient than looping through all enemy pieces. And performance in chess matters a lot when you start searching! This approach is simpler when you use a bitboard based approach where checking for piece intersections, etc is much easier.
链接地址: http://www.djcxy.com/p/84602.html上一篇: 国际象棋游戏设计问题
下一篇: 国际象棋生成可能的移动国王安全