Fernando Fernando - 2 months ago 6
Java Question

Set value in Bitfield variable

I'm using the Bitfield structure bellow to store the board state of a chess game, it's a 32 bit integer. The fields I'm encoding/decoding are:


  • epSquare (0 from 63)

  • half moves count (0 to 100)

  • current player (0 or 1)

  • 4 castling rights flags



I can create and extract 'states', but I'm having trouble mutating a given state:

/*
0000 0000 0000 0000 0000 0011 1111 epSquare 0x3f
0000 0000 0000 0001 1111 1100 0000 halfMoves 0x7f >> 6
0000 0000 0000 0010 0000 0000 0000 curPlayer 0x1 >> 13;
0000 0000 0000 0100 0000 0000 0000 Kc 0x4000
0000 0000 0000 1000 0000 0000 0000 Qc 0x8000
0000 0000 0001 0000 0000 0000 0000 kc 0x10000
0000 0000 0010 0000 0000 0000 0000 qc 0x20000
*/

public class State {

public static int new_state(int epSquare, int halfMoves, int turn, int flags){
return epSquare | (halfMoves << 6) | (turn << 13) | flags;
}

public static int epSquare(int s){
return s & 0x3f;
}

public static int halfMoves(int s){
return s >> 6 & 0x7f;
}

// s state, e new epSquare
public static int setEPSquare(int s, int e){
//??
}

// s state, h halfMoves value
public static int setHalfMoves(int s, int e){
//??
}

public static void main (String[] args){
int s = BoardState.new_state(36, 84, 1, 0);
System.out.println("ep square: " + epSquare(s)); //36
System.out.println("half moves: " + halfMoves(s)); //84
s = setHalfMoves(s, 13);
System.out.println("half moves: " + halfMoves(s)); //should give 13
}
}


How do I implement the
setHalfMoves
method? The first one,
setEPSquare
, seems to work, but I couldn't figure out the former. Thanks!

Answer

Well, firstly, your #setEPSquare() function is not correct. When I show you the code below, you might understand why, but I will explain as well:

public static int setHalfMoves(int s, int e){
     return (
             //mask for e to only the correct bits
             (e & 0x7f)
             //left shifted into position
             << 6)
             //zero out the original value
             | (s & (~(0x7f << 6)));
}
public static void main (String[] args){
   int s = BoardState.new_state(36, 84, 1, 0);
   System.out.println("ep square: " + epSquare(s)); //36
   System.out.println("half moves: " + halfMoves(s)); //84
   //Note that this is fixed to now reassign s
   s = setHalfMoves(s, 13);
   System.out.println("half moves: " + halfMoves(s)); //should give 13
}

So your first issue is that ORing the new value against the old is the wrong operation. You need to zero it out for a 'set' type of function. Your second issue was that you have to reassign s after you manipulate it via setHalfMoves(int, int). You will have to fix #setEPSquare() as well, but I leave that for you to try out.