So I'm working on a checkers like game that involved moving two different types of pieces around the board to try and capture the opponents pieces. One of these pieces is a ball, and it's movement rules are that it can move up and down only one space per turn, with no side to side movement allowed. However, when testing, for some reason I've noticed the opposite to be true. I can't seem to spot my coding error and I think I just need another set of eyes at this point. The following should be the classes relavent to the error.

public class Board {
    public static final int NUM_ROWS = 6;
    public static final int NUM_COLUMNS = 6;
    public static final int ZERO = 0;
    public static final int ONE = 1;
    public static final int TWO = 2;
    public static final int THREE = 3;
    public static final int FOUR = 4;
    public static final int FIVE = 5;
    public static final String EMPTY = "*";
    public static final String SPACE = " ";

    private GamePiece[][] gameBoard;
    private ArrayList<GamePiece> playerOnePieces;
    private ArrayList<GamePiece> playerTwoPieces;

    /**
     * Constructor for objects of class Board
     */
    public Board()
    {
        gameBoard = new GamePiece[NUM_ROWS][NUM_COLUMNS];
        playerOnePieces = new ArrayList<GamePiece>();
        playerTwoPieces = new ArrayList<GamePiece>();
        fillBoard();
    }

    /**
     * Fills the game board with game pieces.
     */
    private void fillBoard()
    {
        gameBoard[1][2] = new Torches("T", true);
        gameBoard[1][3] = new Torches("T", true);
        gameBoard[1][4] = new Torches("T", true);
        gameBoard[2][2] = new Balls("O", true);
        gameBoard[2][3] = new Balls("O", true);
        gameBoard[2][4] = new Balls("O", true);
        gameBoard[4][2] = new Torches("t", false);
        gameBoard[4][3] = new Torches("t", false);
        gameBoard[4][4] = new Torches("t", false);
        gameBoard[5][2] = new Balls("o", false);
        gameBoard[5][3] = new Balls("o", false);
        gameBoard[5][4] = new Balls("o", false);
    }

    /**
     * Displays the contents of the game board.
     */
    public void displayBoard()
    {
        int counter = ONE;
        for (int rowCounter = ZERO; rowCounter < NUM_ROWS; rowCounter++) {
            for (int columnCounter = ZERO; columnCounter < NUM_COLUMNS; columnCounter++) {
                if (rowCounter == ZERO && columnCounter == ZERO) {
                    System.out.print(SPACE + SPACE);
                }
                else if (rowCounter == ZERO && columnCounter == ONE) {
                    System.out.print("a" + SPACE);
                }
                else if (rowCounter == ZERO && columnCounter == TWO) {
                    System.out.print("b" + SPACE);
                }
                else if (rowCounter == ZERO && columnCounter == THREE) {
                    System.out.print("c" + SPACE);
                }
                else if (rowCounter == ZERO && columnCounter == FOUR) {
                    System.out.print("d" + SPACE);
                }
                else if (rowCounter == ZERO && columnCounter == FIVE) {
                    System.out.print("e" + SPACE);
                }
                else if (columnCounter == ZERO) {
                    System.out.print(counter + SPACE);
                    counter++;
                }
                else if (gameBoard[rowCounter][columnCounter] == null) {
                    System.out.print(EMPTY + SPACE);
                }
                else {
                    System.out.print(gameBoard[rowCounter][columnCounter] + SPACE);
                }
                }
            System.out.println();
            }
    }

    /**
     * Moves a piece from one location to another if a it passes a check to see if the move is legal
     * @param from - the location that the piece is moving from.
     * @param to - the location that the piece is moving to.
     * @throws InvalidMoveException
     */
    public void movePiece(Location from, Location to) throws InvalidMoveException
    {
        if (checkBoundsFrom(from)) {
            throw new InvalidMoveException("Invalid input for source location.");
        }
        else if (checkBoundsTo(to)) {
            throw new InvalidMoveException("Invalid input for destination location.");
        }
        else if (isSameLocation(from, to)) {
            throw new InvalidMoveException("Invalid move, source and destination cannot be the same.");
        }
        else if (!isPiecePresent(from)) {
            throw new InvalidMoveException("No piece at source location.");
        }
        GamePiece piece = gameBoard[from.getxLocation()][from.getyLocation()];
        if (!piece.isLegalMove(from, to)) {
            throw new InvalidMoveException("Invalid move for this piece.");
        }
        else {
            gameBoard[to.getxLocation()][to.getyLocation()] = piece;
            gameBoard[from.getxLocation()][from.getyLocation()] = null;
        }
    }

    /**
     * Checks a proposed move to ensure it is within the bounds of the board.
     * @param from - the location that the piece is moving from.
     * @return false if both source and destination are within bounds
     */
    private boolean checkBoundsFrom(Location from)
    {
        boolean outOfBounds = false;
        try {
            from.getxLocation();
            from.getyLocation();
        }
        catch (java.lang.NullPointerException exc) {
            outOfBounds = true;
            return outOfBounds;
        }
        return outOfBounds;
    }

    /**
     * Checks a proposed move to ensure it is within the bounds of the board.
     * @param to - the location that the piece is moving to.
     * @return false if both source and destination are within bounds
     */
    private boolean checkBoundsTo(Location to)
    {
        boolean outOfBounds = false;
        try {
            to.getxLocation();
            to.getyLocation();
        }
        catch (java.lang.NullPointerException exc) {
            outOfBounds = true;
            return outOfBounds;
        }
        return outOfBounds;
    }

    /**
     * Checks a proposed move to ensure source and destination are different.
     * @param from - the location that the piece is moving from.
     * @param to - the location that the piece is moving to.
     * @return true if source and destination are the same
     */
    private boolean isSameLocation(Location from, Location to)
    {
        int fromxLocation = from.getxLocation();
        int fromyLocation = from.getyLocation();
        int toxLocation = to.getxLocation();
        int toyLocation = to.getyLocation();
        boolean isSameLocation = false;
        if (toxLocation == fromxLocation && toyLocation == fromyLocation) {
            isSameLocation = true;
        }
        return isSameLocation;
    }

    /**
     * Checks a proposed move to ensure there is a piece present at the from location
     * @param from - the location the piece is moving from.
     * @return true if a piece is present, false if not.
     */
    private boolean isPiecePresent(Location from)
    {
        boolean isPiecePresent = true;
        if (gameBoard[from.getxLocation()][from.getyLocation()] == null) {
            isPiecePresent = false;
        }
        return isPiecePresent;
    }

public class Location {
    private int xLocation;
    private int yLocation;

    /**
     * Constructor for objects of class Location
     */
    public Location(int xLocation,
                    int yLocation)
    {
        this.xLocation = xLocation;
        this.yLocation = yLocation;
    }

    /**
     * @return the xLocation
     */
    public int getxLocation()
    {
        return xLocation;   
    }

    /**
     * @return the yLocation
     */
    public int getyLocation()
    {
        return yLocation;
    }
 }

public class Balls extends GamePiece {

    /*
     * Constructor for objects of class Balls
     */
    public Balls (String howPieceDisplays,
                  boolean isPlayerOne)
    {
        super(howPieceDisplays, isPlayerOne);
    }

    /**
     * Checks to see if the move is legal for this particular type of game piece.
     * @return a boolean saying whether the move is legal or not.
     */
    public boolean isLegalMove(Location from, Location to)
    {
        int fromxLocation = from.getxLocation();
        int fromyLocation = from.getyLocation();
        int toxLocation = to.getxLocation();
        int toyLocation = to.getyLocation();
        boolean isLegalMove = true;
        if (fromxLocation != toxLocation || toyLocation > (fromyLocation + 1) || toyLocation < (fromyLocation - 1)) {
            isLegalMove = false;
        }
        return isLegalMove;
    }

    /**
     * @return a String representation of an object of this class
     */
    public String toString()
    {
        return super.toString();
    }
}

I didn't try to understand all your code, but maybe your problem starts from the fact that you are mixing [row][col] coordinates and x,y coordinates? Note that x corresponds to col and y corresponds to row, so the order of the coordinates is opposite between those two representations. Sooner or later it's inevitable that you will get something the wrong way round!

eg line 183:

if (gameBoard[from.getxLocation()][from.getyLocation()] ...  // equivalent to gameBoard[col][row]

Edited 4 Years Ago by JamesCherrill

Sorry if I'm being really dense about this, but how/where did I first get my x and y mixed up. I know that 2D array coordinates are in the form of [row number][column number]. So if my Location objects are created with a similar form (x (corresponds to row),y (corresponds to column)), then when calling a gameBoard location why does calling x for the row coordinate and y for the column coordinate mix things up. I seem to be blind to being able to see this error and it's simutaneously frustrating, discouraging, and embarrassing me!

Edited 4 Years Ago by DEAD TERMINATOR

my Location objects are created with a similar form (x (corresponds to row),y (corresponds to column)

No, you use x for horizontal ( = column number), and y for vertical ( = row number). That's where you are confused.

Here's a little grid in [row][col] notation:

[1][1]  [1][2]
[2][1]  [2][2]
[3][1]  [3][2]

now here's the same thing in (x,y):

(1,1)  (2,1)
(1,2)  (2,2)
(1,3)  (2,3)

see how they are in opposite order?

Edited 4 Years Ago by JamesCherrill

ps: depending on how you define your rows, it may also be true that the row numbers increase going upwards (top row has the highest row number), whereas Java y coordinates always increase in the downwards direction.

This question has already been answered. Start a new discussion instead.