【问题标题】:Find last int (1-9) stored in long of bits (each int represented by 4 bits)查找存储在 long of bits 中的最后一个 int (1-9)(每个 int 由 4 位表示)
【发布时间】:2015-02-12 02:28:11
【问题描述】:

我正在开发井字游戏 AI,并希望使用游戏引擎提供的 long 找到最后一步(对手在当前回合之前的最后一步)。

每个空间都由一个数字整数 1-9 表示(我将从中减去 1 以获得移动 0-8,再加上 9 用于存储在 long 中的 0xF 中的场外移动)。

0xE 用于表示 NULL,但我的程序会将其视为场外移动。

以下是游戏状态的编码方式:

Used to encode game State, first 4 bits are first move, second 4 bits second move, (4 * 9 = 36 bits) bits 33-36 are the last Move. Each move is the coordinate singleton + 1, therefore the tictactoe board is recorded as...
  1 |  2 | 3
  4 |  5 | 6
  7 |  8 | 9

Normal equation for singleton is row*3+col, but you cannot record a state as 0, therefore game state moves are row*3+col + 1, note difference Coordinate singleton is 0..8, board game state position is 1..9;
 1 | 2 | 3
 4 | 5 | 6
 7 | 8 | 9



The game state 0x159, X first move 9; O move 2 is 5;move 3 X is 1


 X _ _ 
 _ O _
 _ _ 9



 Sets off board set all 4 bits (aka 0xf).


e.g., 0x12f45, On X's second move (game move 3)
 X picked a Coordinate outside the tictactoe range.


Duplicate guesses onto occupied square are just saved


e.g., 0x121 implies X has used position 1 on both his
 first and second move


Null coordinate usually caused by exception is saved as 0xE


e.g., 0x1E3; implies on game move 2, O first move, O throw an exception
 most likely causes index array out of bounds

到目前为止,这是我使用引擎的游戏状态找到最后一步的方法:

private int LastMoveFinder(final Board brd, int move)
{
    char prevMove = Long.toHexString(brd.getGameState()).charAt(0);

    if(prevMove == 'f' || prevMove == 'e')
        return 9;
    else
        return Character.getNumericValue(prevMove) - 1;
}

但是,我确信有一种更快的方法(性能方面)可以使用某种位移方法找到最后一步,因为我们的 AI 将相互测试速度(nanoSec/move)和胜利领带-损失率。

我已经阅读了有关移位的内容,并在整个 stackoverflow 上搜索了像我这样的问题的答案,但我尝试在我的程序中实施的任何内容都没有奏效。

我确信我错过了一些简单的东西,但还没有学习过有关位移和掩码的课程,所以我有点不知所措。

感谢您的帮助。

【问题讨论】:

  • 为什么这里同时标有java和c++?你想要哪一个?
  • 最高效的方法是放弃位旋转并使用常规大小的整数。现代平台上没有节省内存的好处。我相当肯定运行你的程序的平台会有足够的内存。

标签: java c++ bit-manipulation bit-shift


【解决方案1】:

您可以通过将位掩码0xf 向左移动 4 * moveNumber 位进行与运算来获得 int 的 4 位。然后,将结果右移 4 * moveNumber 位以获得一个 int,并将您的移动逻辑应用于该 int。修改后的方法是:

/**
   Assumes moveNumber is 0 indexed.
 */
private int LastMoveFinder(final Board brd, int moveNumber)
{
    int moveMask = 0xf << (4 * moveNumber);
    int prevMove = (brd.getGameState() & moveMask) >>> (4 * moveNumber);

    if (prevMove == 0xf || prevMove == 0xe) {
        return 9;
    } else {
        return prevMove - 1;
    }
}

【讨论】:

  • 感谢您的快速回复!我实现了代码,但它不是很有效。截至目前,该方法在第一次搜索时找到了移动,但游戏的所有后续运行都返回 -1(prevMode - 1,所以实际上 prevMode 正在返回 0)。我从 1 和 0 开始用 move 跑,结果是一样的。
  • 编辑:工作。移动数减少了 1,因为当前移动总是比游戏状态编码时的移动数多 1。非常感谢您的帮助!
  • 使用位掩码和位移来查找最后一步与转换为 HexString 相比快了大约 4 倍(0.446 毫秒 vs 2.22 毫秒)
  • 经过进一步测试,该方法可以完美运行,除非做出了错误的举动。 (prevMove == 0xf || prevMove 0xe) 条件永远不会触发。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多