我目前正在尝试实施国际象棋游戏。我对它进行了结构设计,以便为每种样片类型生成可能的移动并将其存储在数组列表中。我的木板是2D阵列。我想知道如何写,如果xTo yTo(要移动到点的坐标)可以移动,那么可以进行移动,但是它不会让我使用数组list.contains()
,因此建议不胜感激!这是我所拥有的一个例子。 (用户通过终端输入坐标xFrom,yFrom然后xTo yTo)
我现在想知道将其转换为布尔值是否更容易?并摆脱数组列表?
public Board() {
this.boardsize = DEFAULT_SIZE;
board = new char[boardsize][boardsize];
// Clear all playable fields
for (int x = 0; x < boardsize; x++)
for (int y = 0; y < boardsize; y++)
board[x][y] = FREE;
board[0][7] = BLACKROOK;
board[2][7] = BLACKBISHOP;
board[5][7] = BLACKBISHOP;
board[7][7] = BLACKROOK;
board[0][0] = WHITEROOK;
board[2][0] = WHITEBISHOP;
board[5][0] = WHITEBISHOP;
board[7][0] = WHITEROOK;
对于新手。...
public ArrayList<int[]> possibleMoves = new ArrayList<int[]>();
public ArrayList<int[]> generatePossibleMoves(char[][] gameBoard, int xFrom, int yFrom) {
for (int i = 1; xFrom + i < gameBoard.length; i++) {
if (getPieceColour(gameBoard, xFrom + i, yFrom) != getPieceColour(gameBoard, xFrom, yFrom)) {
if (gameBoard[xFrom + i][yFrom] != FREE) {
int[] move = {xFrom + i, yFrom};
possibleMoves.add(move);
break; //stops iterating here since a rook is not allowed to jump over other pieces
} else
{
int[] move = {xFrom + i, yFrom};
possibleMoves.add(move);
}
}
}
for (int i = 1; xFrom - i < gameBoard.length; i++) {
if (getPieceColour(gameBoard, xFrom - i, yFrom) != getPieceColour(gameBoard, xFrom, yFrom)) {
if (gameBoard[xFrom - i][yFrom] != FREE) {
int[] move = {xFrom - i, yFrom};
possibleMoves.add(move);
break;
}
else
{
int[] move = {xFrom - i, yFrom};
possibleMoves.add(move);
}
}
}
for (int i = 1; yFrom + i < gameBoard.length+1; i++) { //makes sure the place to be moved is on the board
if (getPieceColour(gameBoard, xFrom + i, yFrom) != getPieceColour(gameBoard, xFrom, yFrom)) {
if (gameBoard[xFrom][yFrom+i] != FREE) {
int[] move = {xFrom, yFrom+i};
possibleMoves.add(move);
break;
}
else
{
int[] move = {xFrom, yFrom+i};
possibleMoves.add(move);
}
}
}
for (int i = 1; yFrom- i < gameBoard.length+1; i++)
if (getPieceColour(gameBoard, xFrom, yFrom - 1) != getPieceColour(gameBoard, xFrom, yFrom)) {
if (gameBoard[xFrom][yFrom - 1] != FREE) {
int[] move = {xFrom, yFrom - 1};
possibleMoves.add(move);
break;
} else {
int[] move = {xFrom, yFrom - 1};
possibleMoves.add(move);
}
}
return possibleMoves;
}
public boolean moveLegal(char[][] gameBoard, int xFrom, int yFrom, int xTo, int yTo){
generatePossibleMoves(gameBoard, xFrom,yFrom);
if(possibleMoves.contains(xTo,yTo){
//this is where I'm stuck
}
}
答案 0 :(得分:0)
要检查是否可以移动,一种方法是将这对{xTo,yTo}与您通过generatePossibleMoves函数计算出的所有合法移动进行比较:
public boolean moveLegal(char[][] gameBoard, int xFrom, int yFrom, int xTo, int
yTo){
int[] wantedMove = new int[] {xTo, yTo};
ArrayList<int[]> possibleMoves = generatePossibleMoves(gameBoard, xFrom,yFrom);
boolean isMoveLegal = possibleMoves.stream().anyMatch(possibleMove ->
Arrays.equals(wantedMove, possibleMove));
return isMoveLegal;
}
答案 1 :(得分:0)
我将创建另一个可正确实现equals方法的类Coordinates
public class Coordinates {
int x = 0;
int y = 0;
public Coordinates(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Coordinates other = (Coordinates) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
,然后将此类用于ArrayList类型
例如
public List<Coordinates> possibleMoves = new ArrayList<Coordinates>();
然后功能变为
public boolean moveLegal(char[][] gameBoard, int xFrom, int yFrom, int xTo, int yTo){
generatePossibleMoves(gameBoard, xFrom,yFrom);
Coordinates checkCoordinates = new Coordinates (xTo,yTo);
if(possibleMoves.contains(xTo,yTo){
...
}
}
答案 2 :(得分:0)
主要原因是您保存在possibleMoves
数组中,但尝试检查不是数组。如documentation中所述,List.contains()
仅接受1个参数。由于您将数组放入List
中,因此可能要检查数组:if(possibleMoves.contains({xTo,yTo})
但是实际上它不能正常工作。您混合了所有棋子的可能动作,因此可以选择皇后并移动到可以到达骑士的任何位置。
主题: 我建议您使用更多的OOP风格的方法:使用更少的原始数组,使用更多的反映片段的对象。例如
enum Side {
White; Black;
public Side opposite() {
if (this==White) return Black;
else return White;
}
}
// in separate file
class Pawn {
private ChessSquare currentPosition;
private final Side color;
public boolean couldMoveTo(ChessSquare another) {
if (currentPosition.x == another.x) {
return another.y - currentPosition.y == 1; //TODO check for first move in two sruares
} else if (another.hasPiece(this.color.opposite())) {
// TODO allow to take enemy piece in diagonal
}
}
public List<ChessField> possibleMoves() {
List<ChessField> result = new ArrayList<>();
for (currentSquare in ALL_SQUARES) {
if (couldMoveTo(currentSquare)) result.add(currentSquare)
}
return result;
}
我的示例效率低下,可以通过许多方式进行改进。另外还有许多其他选项可以组织代码结构。我猜想它展示了您如何从一个作品的角度检查一个作品是否可以移动。同样,您可以在Pawn
类中隐藏许多详细信息(例如 en passant 规则),同时在较高级别上具有清晰的代码。您会发现possibleMoves()
很小,实际上对所有作品都是通用的。
P.S。国际象棋是一款很棒的游戏,希望您在创建游戏时能同时学习国际象棋和Java。