编程国际象棋车运动
Programming Chess Rook Movement
我正在尝试创建一个棋盘游戏,其中所有棋子都能够像国际象棋中的车一样移动。 (即水平或垂直任意数量的 space)
我的棋盘是一个简单的二维整数数组,值 0,1,2 取决于 space 是否为空,有红色棋子还是黑色棋子。
到目前为止,我的移动代码如下所示,如果允许或不允许移动,它会创建一个 true 或 false 值:
int[][] board;
public boolean validMove(int fromRow, int fromCol, int toRow, int toCol) {
if (pieceAt(toRow, toCol) != EMPTY) {
return false;
} else if (fromRow - toRow == 0 && fromCol - toCol != 0) {
return true;
} else if (fromCol - toCol == 0 && fromRow - toRow != 0) {
// Trying to add piece collision code
for (int i = fromRow; i < toRow; i++) {
if (pieceAt(toCol, i) != EMPTY)
return false;
}
return true;
} else {
return false;
}
}
我的问题是尝试创建碰撞检测,如果另一块挡在路上,它不应该能够越过它,但是目前我的代码可以。谁能帮我做这个?
你可以有一个二维字符数组,每个单元格代表棋盘上的位置。在那里你可以有一个位置的三个状态的字符 (white/red/empty).
我能想到的另一种方法是在每次移动之前检查从 startPosition 到 endPosition 定位它们的状态。但性能方面我认为某种数组会好得多
试试下面的代码。这很天真(也没有经过测试),但我认为它应该按原样工作。而且我认为它很好地说明了这个想法(见评论)。它是用 C 语言编写的,但我相信您可以轻松地将它转换为 Java(或您使用的任何语言)。
bool validMove(int fromRow, int fromCol, int toRow, int toCol)
{
int i;
// Attempt to move to the same cell
if (fromRow == toRow && fromCol == toCol)
return false;
// Collision detection
if (fromRow == toRow) {
// Horizontal move
if (fromCol < toCol) {
// Move right
for (i = fromCol + 1; i <= toCol; ++i)
if (pieceAt(fromRow, i) != EMPTY)
return false;
} else {
// Move left
for (i = fromCol - 1; i >= toCol; --i)
if (pieceAt(fromRow, i) != EMPTY)
return false;
}
} else if (fromCol == toCol) {
// Vertical move
if (fromRow < toRow) {
// Move down
for (i = fromRow + 1; i <= toRow; ++i)
if (pieceAt(i, fromCol) != EMPTY)
return false;
} else {
// Move up
for (i = fromRow - 1; i >= toRow; --i)
if (pieceAt(i, fromCol) != EMPTY)
return false;
}
} else {
// Not a valid rook move (neither horizontal nor vertical)
return false;
}
return true;
}
编辑
您还可以通过减少 conditional statement count, using the method proposed by Toon Krijthe 来优化您的代码。主要思想是使用 "delta" 值 (dx
/dy
) 来递增或递减单元格索引。在那种情况下,应该明确检查目标单元格。
代码:
bool validMove(int fromRow, int fromCol, int toRow, int toCol)
{
int i;
// Attempt to move to the same cell
if (fromRow == toRow && fromCol == toCol)
return false;
// Collision detection
if (fromRow == toRow) { // Horizontal move
int dx = (fromCol < toCol) ? 1 : -1;
for (i = fromCol + dx; i != toCol; i += dx)
if (pieceAt(fromRow, i) != EMPTY)
return false;
} else if (fromCol == toCol) { // Vertical move
int dy = (fromRow < toRow) ? 1 : -1;
for (i = fromRow + dy; i != toRow; i += dy)
if (pieceAt(i, fromCol) != EMPTY)
return false;
} else { // Not a valid rook move
return false;
}
// Return true if destination cell is free
return pieceAt(toRow, toCell) == EMPTY;
}
您可以简单地 "walk" 每个字段以检查它是否为空。
例如:
int[][] board;
public boolean validMove(int fromRow, int fromCol, int toRow, int toCol)
{
if (pieceAt(toRow, toCol) != EMPTY) return false;
else if (fromRow == toRow)
{
// horizontal move
if (fromCol == toCol) return false; // same position
int dx, x;
if (fromCol < toCol)
dx = 1;
else
dx = -1;
for (x = fromCol + dx; x != toCol; x += dx)
{
if (pieceAt(toRow, x) != EMPTY) return false; // occupied
}
}
else if (fromCol == toCol)
{
// vertical move
int dy, y;
if (fromRow < toRow)
dy = 1;
else
dy = -1;
for (y = fromRow + dy; y != toRow; y += dy)
{
if (pieceAt(y, toCol) != EMPTY) return false; // occupied
return true; // free path
}
}
else return false; // no horizontal or vertical move
}
我正在尝试创建一个棋盘游戏,其中所有棋子都能够像国际象棋中的车一样移动。 (即水平或垂直任意数量的 space)
我的棋盘是一个简单的二维整数数组,值 0,1,2 取决于 space 是否为空,有红色棋子还是黑色棋子。
到目前为止,我的移动代码如下所示,如果允许或不允许移动,它会创建一个 true 或 false 值:
int[][] board;
public boolean validMove(int fromRow, int fromCol, int toRow, int toCol) {
if (pieceAt(toRow, toCol) != EMPTY) {
return false;
} else if (fromRow - toRow == 0 && fromCol - toCol != 0) {
return true;
} else if (fromCol - toCol == 0 && fromRow - toRow != 0) {
// Trying to add piece collision code
for (int i = fromRow; i < toRow; i++) {
if (pieceAt(toCol, i) != EMPTY)
return false;
}
return true;
} else {
return false;
}
}
我的问题是尝试创建碰撞检测,如果另一块挡在路上,它不应该能够越过它,但是目前我的代码可以。谁能帮我做这个?
你可以有一个二维字符数组,每个单元格代表棋盘上的位置。在那里你可以有一个位置的三个状态的字符 (white/red/empty).
我能想到的另一种方法是在每次移动之前检查从 startPosition 到 endPosition 定位它们的状态。但性能方面我认为某种数组会好得多
试试下面的代码。这很天真(也没有经过测试),但我认为它应该按原样工作。而且我认为它很好地说明了这个想法(见评论)。它是用 C 语言编写的,但我相信您可以轻松地将它转换为 Java(或您使用的任何语言)。
bool validMove(int fromRow, int fromCol, int toRow, int toCol)
{
int i;
// Attempt to move to the same cell
if (fromRow == toRow && fromCol == toCol)
return false;
// Collision detection
if (fromRow == toRow) {
// Horizontal move
if (fromCol < toCol) {
// Move right
for (i = fromCol + 1; i <= toCol; ++i)
if (pieceAt(fromRow, i) != EMPTY)
return false;
} else {
// Move left
for (i = fromCol - 1; i >= toCol; --i)
if (pieceAt(fromRow, i) != EMPTY)
return false;
}
} else if (fromCol == toCol) {
// Vertical move
if (fromRow < toRow) {
// Move down
for (i = fromRow + 1; i <= toRow; ++i)
if (pieceAt(i, fromCol) != EMPTY)
return false;
} else {
// Move up
for (i = fromRow - 1; i >= toRow; --i)
if (pieceAt(i, fromCol) != EMPTY)
return false;
}
} else {
// Not a valid rook move (neither horizontal nor vertical)
return false;
}
return true;
}
编辑
您还可以通过减少 conditional statement count, using the method proposed by Toon Krijthe 来优化您的代码。主要思想是使用 "delta" 值 (dx
/dy
) 来递增或递减单元格索引。在那种情况下,应该明确检查目标单元格。
代码:
bool validMove(int fromRow, int fromCol, int toRow, int toCol)
{
int i;
// Attempt to move to the same cell
if (fromRow == toRow && fromCol == toCol)
return false;
// Collision detection
if (fromRow == toRow) { // Horizontal move
int dx = (fromCol < toCol) ? 1 : -1;
for (i = fromCol + dx; i != toCol; i += dx)
if (pieceAt(fromRow, i) != EMPTY)
return false;
} else if (fromCol == toCol) { // Vertical move
int dy = (fromRow < toRow) ? 1 : -1;
for (i = fromRow + dy; i != toRow; i += dy)
if (pieceAt(i, fromCol) != EMPTY)
return false;
} else { // Not a valid rook move
return false;
}
// Return true if destination cell is free
return pieceAt(toRow, toCell) == EMPTY;
}
您可以简单地 "walk" 每个字段以检查它是否为空。 例如:
int[][] board;
public boolean validMove(int fromRow, int fromCol, int toRow, int toCol)
{
if (pieceAt(toRow, toCol) != EMPTY) return false;
else if (fromRow == toRow)
{
// horizontal move
if (fromCol == toCol) return false; // same position
int dx, x;
if (fromCol < toCol)
dx = 1;
else
dx = -1;
for (x = fromCol + dx; x != toCol; x += dx)
{
if (pieceAt(toRow, x) != EMPTY) return false; // occupied
}
}
else if (fromCol == toCol)
{
// vertical move
int dy, y;
if (fromRow < toRow)
dy = 1;
else
dy = -1;
for (y = fromRow + dy; y != toRow; y += dy)
{
if (pieceAt(y, toCol) != EMPTY) return false; // occupied
return true; // free path
}
}
else return false; // no horizontal or vertical move
}