【问题标题】:Connect Four Bitboard连接四个位板
【发布时间】:2012-11-11 01:16:20
【问题描述】:

this 帖子中,有一个非常有趣的建议,用于使用位板测试连接四胜。

董事会的结构如下:

6 14 22 30 38 46 54
5 13 21 29 37 45 53
4 12 20 28 36 44 52
3 11 19 27 35 43 51
2 10 18 26 34 42 50
1  9 17 25 33 41 49
0  8 16 24 32 40 48

他们还推荐了以下算法,用于测试仅使用 8 个班次的胜利:

bool haswon(int64_t board)
{
    int64_t y = board & (board >> 7);
    if (y & (y >> 2 * 7)) // check \ diagonal
        return true;
    y = board & (board >> 8);
    if (y & (y >> 2 * 8)) // check horizontal -
        return true;
    y = board & (board >> 9);
    if (y & (y >> 2 * 9)) // check / diagonal
        return true;
    y = board & (board >> 1);
    if (y & (y >> 2))     // check vertical |
        return true;
    return false;
}

我想在我正在编写的类似程序中实现这个算法。但是,要应用我的启发式函数,我需要能够判断给定行中有多少块。我真的一直在努力解决这个算法,但我不知道如何检查是否只有 1、2 或 3 件连续。

现在,我只是遍历每一行并计算位数,但我确信一定有更好的方法使用移位。

【问题讨论】:

    标签: c++ bit-manipulation


    【解决方案1】:

    对于第 0 行,您可以通过以下方式获取件数:

    int64_t row0 = board & 0x01010101010101LL;
    row0 += row0 >> 32;
    row0 += row0 >> 16;
    row0 += row0 >> 8;
    return row0 & 0xff;
    

    对于其他行也是如此(首先按行号移动)。事实上,你可以一次做两行,因为计数总是适合 3 位。

    int64_t x = board & 0x11111111111111LL;
    x += x >> 32;
    x += x >> 16;
    x += x >> 8;
    int row0 = x & 0xf;
    int row4 = (x >> 4) & 0xf;
    

    【讨论】:

    • 成功了,非常感谢。如果不是太不方便,您认为您可以分享您解决此类问题的技巧吗?你是从一个例子开始,然后试着在纸上写出来吗?
    • 这是一个非常标准的位并行操作。查看graphics.stanford.edu/~seander/bithacks.html 了解许多标准的位旋转。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多