在位域变量中设置值

Set value in Bitfield variable

我正在使用下面的位域结构来存储国际象棋游戏的棋盘状态,它是一个 32 位整数。我 encoding/decoding 的字段是:

我可以创建和提取 'states',但我在改变给定状态时遇到问题:

/*
    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
  }
 }

如何实现 setHalfMoves 方法?第一个 setEPSquare 似乎有效,但我无法弄清楚前者。谢谢!

首先,您的 #setEPSquare() 函数不正确。当我向您展示下面的代码时,您可能会明白为什么,但我也会解释一下:

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
}

所以您的第一个问题是,将新值与旧值进行 OR 运算是错误的操作。对于 'set' 类型的函数,您需要将其归零。您的第二个问题是您必须在通过 setHalfMoves(int, int) 操作后重新分配 s。您还必须修复 #setEPSquare(),但我将其留给您尝试。

这是我得到的结果,但不确定它是否 100% 正确:

public static int setEpSquare(int s, int ep){
    s&= ~0x3f;
    return s | ep ;     
}

public static int setHalfMoves(int s, int h){
    s&= ~(0x7f << 6);
    return s | (h << 6);
}