This site requires JavaScript, please enable it in your browser!
Greenfoot back
danpost
danpost wrote ...

2012/10/9

Help on 'Chess' by Razzo

danpost danpost

2012/10/9

#
This discussion thread is for helping Razzo with his new 'Chess' scenario.
danpost danpost

2012/10/9

#
For the Bishop and Rook, you need the direction that you are checking, therefore
// instead of
int nx = Math.abs(x-getX());
int ny = Math.abs(y-getY());
// use
int nx = x - getX();
int ny = y - getY();
// from the above, you can get direction and distance
int dx = (int) Math.signum(nx);
int dy = (int) Math.signum(ny);
int dist = Math.max(Math.abs(nx), Math.abs(ny));
// now, you can start the 'for' loop with
for (int i = 0; i < dist - 1; i++)
// remove this first line in the 'for' loop (shown below)
// execution will exit the 'for' loop automatically when this condition occurs
// -- well, when i == dist (or the greater of Math.abs(nx) and Math.abs(ny))
if (i == nx) return true; // remove this line
// you only need one check inside the 'for' loop
if (PieceExist(getX() + dx * i, getY() + dy * i)) return false;
// the 'for' loop does not check the last square (the one the moving piece lands on)
// as it CAN have a piece on it
The code above will work for BOTH the rook and the bishop; but, you still have to first verify the following: (Bishop) Math.abs(nx) == Math.abs(ny) && nx != 0; (for diagonal move) (Rook) (nx == 0 || ny == 0) && (nx != 0 || ny != 0) (for horizontal or vertical move)
danpost danpost

2012/10/9

#
By the way, your Bishops and Horseys are misplaced. The Horseys start next to the Rooks, and the Bishops start next to the royalty.
Razzo Razzo

2012/10/9

#
Fixed the Horseys and Bishops, However, after adding the code to the Rooks, It is only able to move 1 space.
    public boolean isValidMove(int x,int y)
    {
        int nx = x - getX();
        int ny = y - getY();
        // from the above, you can get direction and distance
        int dx = (int) Math.signum(nx);
        int dy = (int) Math.signum(ny);
        int dist = Math.max(Math.abs(nx), Math.abs(ny));
        for (int i = 0; i < dist - 1; i++)
            if (PieceExist(getX() + dx * i, getY() + dy * i)) return false;
        if ((nx == 0 || ny == 0) && (nx != 0 || ny != 0))
            return true;
        return false;
        // the 'for' loop does not check the last square (the one the moving piece lands on)
        // as it CAN have a piece on it
    }
Oh and by the way, your code is so interesting ^.^ Thanks for helping though :D
danpost danpost

2012/10/9

#
My bad! The 'for' loop should not check the starting square at all (not that I intended it to). It should be more like this
for (int i = 1; i < dist; i++)
{
    if (i != dist)
    {
        if (PieceExist(getX() + dx * i, getY() + dy * i)) return false;
    }
    else
    {
        // checks for move end square here
        // (if pieceE exists, verify other team [if not other team, return 'false'])
    }
}
On your lastest code post, line 11 should be moved up to line 5 and should be coded to return 'false' as follows
if ((nx == 0 && ny == 0) || (nx != 0 && ny != 0)) return false;
which is the exact opposite of the condition that returns 'true' on (the conditions and returns are both opposite -- both statements mean the same thing; but we want to exit the method only if the condition was 'false', hence the change) }The conditions for the verification of move coordinates for the Bishop will also need reversed to return a 'false' value if not valid.
danpost danpost

2012/10/9

#
I do not know where you have the check for same color piece, but it appears you are doing that before 'isValidMove' is called; so really the 'for' loop can be
for (int i = 1; i < dist - 1; i++) if (PieceExist(getX() + dx * i, getY() + dy * i)) return false;
danpost danpost

2012/10/9

#
I noticed that you have the wrong names for the image files for the king and the queen (they are reversed from what they should be). After fixing the file names, their placement on the board will have to be reversed (Queens on column 3 and Kings on column 4; counts starting at zero).
Razzo Razzo

2012/10/9

#
Thanks so much for helping me so far, I'm just having trouble getting the bishop to work! (The Rook works perfectly now, because of you)
    public boolean isValidMove(int x,int y)
    {
        int nx = x - getX();
        int ny = y - getY();
        // from the above, you can get direction and distance
        int dx = (int) Math.signum(nx);
        int dy = (int) Math.signum(ny);
        int dist = Math.max(Math.abs(nx), Math.abs(ny));
        for (int i = 1; i < dist; i++) if (PieceExist(getX() + dx * i, getY() + dy * i)) return false;
        if (Math.abs(x) == Math.abs(y))
            return true;
        return false;
    }
I edited a bit of code in futile attempts to make it work.
danpost danpost

2012/10/9

#
Remove lines 10 and 11 and insert the following at line 5:
if ((nx == 0 || ny == 0) || (Math.abs(nx) != Math.abs(ny))) return false;
The time to check the direction is at the moment you get the differences in the locations (the offsets: nx and ny). There would be no need to continue if the goto square was not a valid square for the move. Actually, with the third condition, you could remove one of the first two conditions. However, it looks strange to only check the one. Changing 'nx == 0 || ny == 0' to 'nx * ny == 0' would also work (without it looking like it was missing something).
danpost danpost

2012/10/10

#
Razzo, Where did you get the images for the chess pieces?
danpost danpost

2012/10/11

#
This is what I have in the 'isValidMove' method for the Rook:
public boolean isValidMove(int x, int y)
{
    int nx = x - getX();
    int ny = y - getY();
    if ((nx == 0 && ny == 0) || (nx != 0 && ny != 0)) return false;
    int dx = (int) Math.signum(nx);
    int dy = (int) Math.signum(ny);
    int dist = Math.max(Math.abs(nx), Math.abs(ny));
    for (int i = 1; i < dist; i++) if (PieceExist(getX() + dx * i, getY() + dy * i)) return false;
    return true;
}
I have the exact same thing for the Bishop and Queen, except that line 5 checks differently.
// for the Bishop
if (nx == 0 || ny == 0 || Math.abs(nx) != Math.abs(ny)) return false;
// for the Queen
if (!((nx == 0 || ny == 0) && (nx != 0 || ny != 0)) && !(nx != 0 && ny != 0 && Math.abs(nx) == Math.abs(ny))) return false;
I simplified the Knight 'isValidMove' to
public boolean isValidMove(int x, int y)
{
    return Math.abs((x - getX()) * (y - getY())) == 2;
}
and for the King, I used
public boolean isValidMove(int x, int y)
{
    int nx = x - getX();
    int ny = y - getY();
    return Math.abs(nx * ny) < 2 && Math.abs(nx - ny) < 2;
}
The Pawn needed a little help, as if it was not yet moved and there was a piece directly in front of it (but not two squares in front), it was allowed to move two squares forward. It is fixed with this code
public boolean isValidMove(int x, int y)
{
    if (isEnemy(x, y))  return Math.abs(x - getX()) == 1 && (team == "blue" ? getY() - 1 == y : getY() + 1 == y);
    if (x != getX()) return false;
    if (team == "blue" ? y > getY() : y < getY()) return false;
    if (y - getY() == 1 || y - getY() == -1) return true;
    return !moved && Math.abs(y - getY()) == 2 && !PieceExist(getX(), getY() + (int) Math.signum(y - getY()));
}
Still, there is en passant, castling and pawn promotion, but these take care of the standard movement.
Razzo Razzo

2012/10/11

#
Thanks a bunch, I haven't got around to implementing it yet, But thanks so much for being so patient. I'm not sure where I got the Chess Images from. (The board however is just an edit of the one contained with Greenfoot) (I'm fairly sure they where copyright free) Here is the images though incase you want to use them :)
Upupzealot Upupzealot

2012/10/18

#
@Razzo Have you finished this Demo?
Razzo Razzo

2012/10/18

#
Nope, I haven't had time to work on it, I will finish it eventually!
You need to login to post a reply.