Search code examples
javaarraysasciichess

Using ASCII for board co-ordinates in Java


I'm pretty new to Java and learning it as a hobby mainly after school to kill my free time productively. I find it really interesting and picking it up relatively pain free however I'm a bit stuck trying to implement a basic chess program that can be played via the command line. Ideally, I'd like to print out the board initially with just Kings and Queens on both sides and get them moving forwards, backwards and diagonally. (Once I get the hang of this I would try adding all other pieces, but at first I would like to just start as simply as possible). For simplicity I will just be using the standard 8x8 playing board.

I've already created a main game loop which uses a command line input of 1 to switch players and 2 to exit the game but I am stuck when it comes to printing out positions and having them change during the game. Firstly I would like to print out the starting positions of both kings and queens as a string (e.g ["D1","E1","D8","E8"]) for the player to see. I imagine the best way to do this is by using the ASCII index but I'm not really sure where to go from this, I tried the code below I know it's not correct and I don't know what to change...

    int num[] = {65, 66, 67, 68, 69, 70, 71, 72};
    String start_Pos =null;
    for(int i = 4; i < 6; i++){
        start_Pos[i] = (Character.toString((char)i) + "1");
    }

    int num[] = {65, 66, 67, 68, 69, 70, 71, 72};
    String start_Pos =null;
    for(int i = 4; i < 6; i++){
        start_Pos1[i] = (Character.toString((char)i) + "8");
    }
        System.out.println(start_Pos + start_Pos1);

I have also tried coding the board set-up but this is literally just printing out the starting positions of the pieces and therefore will not change when a player makes a move - ideally it should. An example would be the starting positions are shown on the board like so:

Photo (PS I know QK should be swapped on one side so they're not opposite each other, my bad!

Photo (PS I know QK should be swapped on one side so they're not opposite each other, my bad!)

But after an input of "D1 D3" (first coordinates indicating what piece and the second indicating final position)from player 1 the board changes to reflect this. Is this possible without having to recompile the entire code after each turn? (Maybe a stupid question...).

Any help would be greatly appreciated. I find learning through making small games like these a lot more interesting and rewarding so if anyone is able to help me implement this I would be very thankful.


Solution

  • Java is an Object Oriented language, so it is best to use classes and object instances.

    Of course, with a chessboard, you'll still want to perform calculations on the x, y coordinates. Computers are just better with numbers, they have problems interpreting things. The chess notation is mainly of use to us humans.

    So here is a class that can be used to parse and interpret chess positions. Note that you should keep this class immutable and simply use a new object instance rather than changing the x or y field.

    public final class ChessPosition {
        // use constants so you understand what the 8 is in your code
        private static final int BOARD_SIZE = 8;
    
        // zero based indices, to be used in a 2D array
        private final int x;
        private final int y;
    
        public ChessPosition(int x, int y) {
            // guards checks, so that the object doesn't enter an invalid state
            if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE) {
                throw new IllegalArgumentException("Invalid position");
            }
    
            this.x = x;
            this.y = y;
        }
    
        public ChessPosition(String chessNotation) {
            // accept upper and lowercase, but output only uppercase
            String chessNotationUpper = chessNotation.toUpperCase();
            // use a regular expression for this guard
            if (!chessNotationUpper.matches("[A-H][0-7]")) {
                throw new IllegalArgumentException("Invalid position");
            }
    
            // can be done in one statement, but we're not in a hurry
            char xc = chessNotationUpper.charAt(0);
            // chars are also numbers, so we can just use subtraction with another char
            x = xc - 'A';
    
            char yc = chessNotation.charAt(1);
            // note that before calculation, they are converted to int by Java
            y = yc - '1';
        }
    
    
        public int getX() {
            return x;
        }
    
        public int getY() {
            return y;
        }
    
        public String getChessNotation() {
            // perform the reverse and create a string out of it
            // using StringBuilder#append(char c) is another option, but this is easier
            return new String(new char[] {
                // Java converts 'A' to int first (value 0x00000041)
                (char) (x + 'A'),
                (char) (y + '1')
            });
        }
    
        // this will be helpfully displayed in your debugger, so implement toString()!
        @Override
        public String toString() {
            return getChessNotation();
        }
    }
    

    Now probably you want to also create a Board class with a backing 2D array of ChessPiece[][] and perform board.set(WHITE_KING, new ChessPosition("E1")) or something similar.