Programming Chess Rook Movement - chess

I am trying to create a board game where all the pieces are able to move the same as a rook in chess. (i.e. Horizontally or vertically as many spaces as they wish)
My board is a simple 2d integer array, with values of 0,1,2 depending on whether the space is empty, has a red piece or a black piece.
My code for the movement so far is shown below, it creates a true or false value if the move is allowed or not:
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;
}
}
My problem is trying to create collision detection, if another piece is in the way it should not be able to move past it, however with my code currently it can. Can anyone help me do this?

Try code below. It's quite naive (and also not tested), but I think it should work just as is. And also I think it illustrates the idea pretty well (see comments). It's in C, but I'm sure you can transform it easily to Java (or whatever language you use).
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;
}
EDIT
You can also optimize your code by reducing conditional statement count, using the method proposed by Toon Krijthe. The main idea is to use "delta" values (dx/dy) for incrementing or decrementing cell indexes. In that case the destination cell should be checked explicitly.
Code:
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;
}

you could have a 2D char array with each cell representing the position on the board. there you can have a char for the three states of the position (white/red/empty).
The other way i can think of is before each move to check from the startPosition till the endPosition positions their states. but performance wise i think the some kind of array will be much better

You can simply "walk" each field in order to check if it is empty.
For example:
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
}

Related

How to write test cases using Equivalence Class, Boundary value, and Basis Path Testing

I have a method isPerfect(x) (with 4<=x<=10000) below, how to write test cases based on Equivalence Class, Boundary Value, and Basis Path Testing:
public boolean checkPerfectNumber(int x) {
if(x >= 4 && x <= 10000) {
int sum = 0;
for(int i = 1; i < x; i++) {
if(x % i == 0) {
sum += i;
}
}
if(sum == x) return true;
}
return false;
}

Calculating size of Google Firestore documents

Firestore docs give details of how to manually calculate the stored size of a document, but there does not seem to be a function provided for this on any of document reference, snapshot, or metadata.
Before I attempt to use my own calculation, does anyone know of an official or unofficial function for this?
Here is my (completely untested) first cut for such a function from my interpretation of the docs at https://firebase.google.com/docs/firestore/storage-size
function calcFirestoreDocSize(collectionName, docId, docObject) {
let docNameSize = encodedLength(collectionName) + 1 + 16
let docIdType = typeof(docId)
if(docIdType === 'string') {
docNameSize += encodedLength(docId) + 1
} else {
docNameSize += 8
}
let docSize = docNameSize + calcObjSize(docObject)
return docSize
}
function encodedLength(str) {
var len = str.length;
for (let i = str.length - 1; i >= 0; i--) {
var code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) {
len++;
} else if (code > 0x7ff && code <= 0xffff) {
len += 2;
} if (code >= 0xDC00 && code <= 0xDFFF) {
i--;
}
}
return len;
}
function calcObjSize(obj) {
let key;
let size = 0;
let type = typeof obj;
if(!obj) {
return 1
} else if(type === 'number') {
return 8
} else if(type === 'string') {
return encodedLength(obj) + 1
} else if(type === 'boolean') {
return 1
} else if (obj instanceof Date) {
return 8
} else if(obj instanceof Array) {
for(let i = 0; i < obj.length; i++) {
size += calcObjSize(obj[i])
}
return size
} else if(type === 'object') {
for(key of Object.keys(obj)) {
size += encodedLength(key) + 1
size += calcObjSize(obj[key])
}
return size += 32
}
}
In Android, if you want to check the size of a document against the maximum of 1 MiB (1,048,576 bytes), there is a library that can help you with that:
https://github.com/alexmamo/FirestoreDocument-Android/tree/master/firestore-document
In this way, you'll be able to always stay below the limit. The algorithm behind this library is the one that is explained in the official documentation regarding the Storage Size.

I Made a maze in AS3 and the maze wont go to my win screen when the player hits the exit

I made A Maze and Action script 3.0 and everything works except when the player touches the exit box (a movie clip called exit) the maze wont go to my win screen.
If someone could help me that'd be great because this is a final project for school
here's my code
var rightArrow:Boolean = false;
var leftArrow:Boolean = false;
var upArrow:Boolean = false;
var downArrow:Boolean = false;
var speed:int = 5;
stage.addEventListener(KeyboardEvent.KEY_DOWN, stage_onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, stage_onKeyUp);
stage.addEventListener(Event.ENTER_FRAME, stage_onEnterFrame);
function stage_onKeyDown(event:KeyboardEvent):void {
if(event.keyCode == Keyboard.RIGHT) rightArrow = true;
if(event.keyCode == Keyboard.LEFT) leftArrow = true;
if(event.keyCode == Keyboard.UP) upArrow = true;
if(event.keyCode == Keyboard.DOWN) downArrow = true;
}
function stage_onKeyUp(event:KeyboardEvent):void {
if(event.keyCode == Keyboard.RIGHT) rightArrow = false;
if(event.keyCode == Keyboard.LEFT) leftArrow = false;
if(event.keyCode == Keyboard.UP) upArrow = false;
if(event.keyCode == Keyboard.DOWN) downArrow = false;
}
function stage_onEnterFrame(event:Event):void {
var rect:Rectangle = player.getBounds(this);
var i:int = 0;
var xBump:int = 0;
var yBump:int = 0;
if(rightArrow) {
xBump = speed;
for(i = 0; i < speed; i++) {
if(maze.hitTestPoint(rect.right + i, player.y, true)) {
xBump = i - 1;
break;
}
}
}
if(leftArrow) {
xBump = -speed;
for(i = 0; i < speed; i++) {
if(maze.hitTestPoint(rect.left - i, player.y, true)) {
xBump = -i + 1;
break;
}
}
}
if(upArrow) {
yBump = -speed;
for(i = 0; i < speed; i++) {
if(maze.hitTestPoint(player.x, rect.top - i, true)) {
yBump = -i + 1;
break;
}
}
}
if(downArrow) {
yBump = speed;
for(i = 0; i < speed; i++) {
if(maze.hitTestPoint(player.x, rect.bottom + i, true)) {
yBump = i - 1;
break;
}
}
}
player.x += xBump;
player.y += yBump;
}
if(player.hitTestObject(exit)) {
gotoAndStop("win");
}
stop();
Your test:
if(player.hitTestObject(exit)) {
gotoAndStop("win");
}
appears to be outside the function stage_onEnterFrame and is thus only executed once. Make sure the closing brace of the function:
player.x += xBump;
player.y += yBump;
} // this one
Comes after the test, like so:
}
player.x += xBump;
player.y += yBump;
if(player.hitTestObject(exit)) {
gotoAndStop("win");
}
} // closing function here, NOT above

Getting indexOutOfBoundsException and I don't know why

I have been having this problem for a few hours. I don't know what it is, but I am having a hard time thinking clearly at the moment. This method displays a set of images. The first part of the method is just setting the gridbag constraints, whereas the next part in the if statement is creating jlabels and adding them to an arraylist of jlabels. The exception is being thrown when I try and add mouselisteners to the jlabels after they have been added to the arraylist (this is on line 112, and i have commented this on the code).
public void displayComplexStimulus(BufferedImage[] complexStimulus){
for(int i = 0; i < numberOfElements; i++){
if (i == 0 || i == 1 || i == 2){
c.gridx = i;
c.gridy = 0;
}
else if(i == 3 || i == 4 || i == 5){
c.gridx = i - 3;
c.gridy = 1;
}
else {
c.gridx = i - 6;
c.gridy = 2;
}
if(counter == 1){
if (phase1Trial.getPositionOfCorrectImage()!= i){
phase1IncorrectLabels.add(new JLabel(new ImageIcon(complexStimulus[i])));
phase1IncorrectLabels.get(i).addMouseListener(this); //line 112
add(phase1IncorrectLabels.get(i),c);
}
else if(phase1Trial.getPositionOfCorrectImage() == i){
correctLabel = new JLabel(new ImageIcon(complexStimulus[i]));
add(correctLabel, c);
correctLabel.addMouseListener(this);
}
}
}
}
If i==phase1Trial.getPositionOfCorrectImage() you're not adding an element to phase1IncorrectLabels. So in the next iteration after adding one element to the array it's at position i-1 and not i. You should replace your get(i) by get(phase1IncorrectLabels.size() - 1).

Negamax not working beyond depth 1

I am making a chess engine in C++ and with this algorithm, I get expected play with max depth set to 1. Beyond that however, it ignores pieces that are in danger and seems to even willingly put itself in danger.
Here is my code:
int negamax(int depth, int alpha, int beta)
{
int max = -INFINITY;
MoveList legalMoves;
MoveGeneration::generateCaptureMoves(&legalMoves);
MoveGeneration::generateQuietMoves(&legalMoves);
// No legal moves
if(legalMoves.count == 0)
{
if(Position::isCheck())
{
// Checkmate
if(Position::activeColor == WHITE)
return VAL_VICTORY;
else
return -VAL_VICTORY;
}
else
{
// Stalemate
return 0;
}
}
// Go through legal moves
for(int i = 0; i < legalMoves.count; i++)
{
// Get move score
Position::doMove(legalMoves[i]);
int score;
if(depth == 0)
score = quiescence(MAX_QUIESCENCE_DEPTH, alpha, beta);
else
score = -negamax(depth - 1, alpha, beta);
Position::undoMove();
// Pruning
if(Position::activeColor == WHITE && score > beta) break;
if(Position::activeColor == BLACK && score < alpha) break;
if(Position::activeColor == WHITE && score > alpha) alpha = score;
if(Position::activeColor == BLACK && score < beta) beta = score;
// Best so far?
if(score > max)
{
max = score;
if(depth == MAX_DEPTH)
bestMove = legalMoves[i];
}
}
return max;
}
Try:
score = -negamax(depth - 1, -beta, -alpha);