简体   繁体   中英

Coming from C, I need some help figuring out, how to best generate Chess-Bitmaps from an input-string

I'm attempting to generate some Bitmaps from an input-string for the chess-variant "Anti-King Chess". Unfortunately I have to do it in Java, which I'm not super familiar with. In the few lines of code i wrote so far I already found that a few things are thought about very differently in Java than in C and it's derivatives.

Like you see in the except below, I have a constructor, that takes the board as string. I iterate over it and call the function placePiece with the corresponding bitmap-long, so that that might get updated correctly.

Now I come to my first question : Since you can't make a "call-by-reference" in Java I decided to return the updated long. That feels pretty "hacky". What would be a better way of updating the bitmaps without writing a function for every type of piece?

Second Question: What does Java do, when I assign the return value of a function to a variable? Is it as run-time efficient as just changing a global variable, like I do with "pieces", "whitePieces" and "blackPieces"?

    /*
 * Parse the starting board state and build the corresponding bitmaps 
 */
public Board(String[] board) {

    //Go through all lines
    for(int i = 0; i < board.length; i++) {
        //Go through all positions
        for(int j = 0; j < board[i].length(); j++) {
            switch(board[i].charAt(j)) {
                //Pawns
                case 'P': pawns = placePiece(pawns, i, j, true); break;
                case 'p': pawns = placePiece(pawns, i, j, false); break;

                //Bishop
                case 'B': bishops = placePiece(bishops, i, j, true); break;
                case 'b': bishops = placePiece(bishops, i, j, false); break;

                //Rook
                case 'R': rooks = placePiece(rooks, i, j, true); break;
                case 'r': rooks = placePiece(rooks, i, j, false); break;

                //Knight
                case 'N': knights = placePiece(knights, i, j, true); break;
                case 'n': knights = placePiece(knights, i, j, false); break;

                //Queen
                case 'Q': queens = placePiece(queens, i, j, true); break;
                case 'q': queens = placePiece(queens, i, j, false); break;

                //King
                case 'K': kings = placePiece(kings, i, j, true); break;
                case 'k': kings = placePiece(kings, i, j, false); break;

                //Anti-King
                case 'A': antikings = placePiece(antikings, i, j, true); break;
                case 'a': antikings = placePiece(antikings, i, j, true); break;

            }
        }
    }

}

/*
 * Function to place a Piece at the appropriate place in the bitmaps
 */
private long placePiece(long map, int row, int column, boolean white) {

    //Place a 1 in the right position of the pieces long
    pieces |= 1L << (row*COLUMN_NUM + column);

    //Place a 1 at the right position in either the black or white pieces
    if(white == true) {
        whitePieces |= 1L << (row*COLUMN_NUM + column);
    }else {
        blackPieces |= 1L << (row*COLUMN_NUM + column);
    }

    //Place a 1 at the right position in the pawn long and return the changed set
    return map | 1L << (row*COLUMN_NUM + column);
}

Edit: Changed (long)1 to 1L as suggested by RaceYouAnytime.

In java all primitive types are immutable, so there is no way of updating a long .

What you did is right.

You are asking questions about performance that are much above the pay grade of the typical developer.

To have true answers to your question one should look at the bytecode generated after compilation.

For example you can ask yourself if your placePiece function would be inlined or not (which possibly has a much higher impact then updating a global varible or not).

Java programmers are not really much obsessed by performance, not when dealing with in-memory operation, since we mostly deal with IO (DB, HTTP, Files) which are order of magnitude slower then memory.

So, in general we try to optimize IO, but we care much less about in memory ops.

I think you can scrape some microseconds by checking if your methods gets inlined, if not so you may use static final methods, which are essentially faster.

Methods in java are all virtual apart from final methods which cannot be overridden.

Use primitive when you can (but often the compiler would do that for you).

That being said, concerning coding style ... you almost never use final method, an try not to use primitives, which goes against my performance tips, but fits into the java mentality of abstracting as much as you can even at the expense of performance (up to a point).

All primitive types have wrapper classes in Java that can be used to avoid the problem you're talking about

Should I just pass a one-element Array with it then?

Just use Long. (the wrapper class)

private void placePiece(Long map, int row, int column, boolean white) {

documentation can be found here: https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html

Note that instantiating a Long value is more efficient if you use the "valueOf()" method.

https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#valueOf(long)

Long pawns = Long.valueOf(14L);
...
placePiece(pawns, i, j, true); break;

Also, since you're concerned about efficiency, you may want to stick with primitive types. In that case, though, it would be more efficient to type 1L rather than (long)1 so that you aren't recasting one primitive type to another every time you instantiate.

I found a great solution for my problem here: https://chessprogramming.wikispaces.com/Bitboard+Board-Definition

Basically, you define an array, that contains all the bitmaps, then you define constants, in the given example an Enum, which doesn't work in Java, but there are ways to define constants. Then you just have to pass the constant and can have the array, that contains all the bitmaps globally.

You then call it by invoking something like board[PAWN] .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM