代表Quarto棋盘游戏棋子的最佳方式

Best way to represent Quarto Board Game Pieces

本文关键字:最佳 方式 棋子 Quarto 棋盘游戏 代表      更新时间:2023-10-16

我正在创建棋盘游戏Quarto。它本质上是高级连接4。

每件作品都有四个显著特征(白色与黑色|高光与短光|方形与圆形|实心与空心(。如果你连续获得其中四个功能,你就赢了。

目前,我正在尝试编写一个函数来检查是否获胜。然而,它正朝着O(n^4(的方向发展,我认为我可以根据我的代码结构来改进这一点。

目前,我有这个:

enum Piece
{
WTSS, WTSH, WTHS, WTHH,
WSSS, WSSH, WSHS, WSHH,
BTSS, BTSH, BTHS, BTHH,
BSSS, BSSH, BSHS, BSHH,
EMPTY
};
static const char * PieceStrings[] = {
"WTSS ", "WTSH ", "WTHS ", "WTHH ",
"WSSS ", "WSSH ", "WSHS ", "WSHH ",
"BTSS ", "BTSH ", "BTHS ", "BTHH ",
"BSSS ", "BSSH ", "BSHS ", "BSHH ",
"____ ",
};

但我认为这不是很有效。我曾想过让它们成为自己的类,但这会使初始化和处理所有这些部分变得困难。

这就是我开始检查获胜的方式:

// go through all N+2 possible connections
// check if any have shared feature
bool Board::isWin() {
int i, j, k;
for (i = 0, k = BOARDSIZE-1; i < BOARDSIZE; i++, k--) {
for (j = 0; j < BOARDSIZE; j++) {
//Horizontal case
// board[i][j];
//Vertical case
// board[j][i];
}
// Diagonal cases
// board[i][i];
// board[k][i];

}
return false;
}
// Checks if pieces have a similar component
bool Board::checkPieces(list<string> & piecesInARow) {
int i, j;
list<string>::iterator it = piecesInARow.begin();
for (i = 0; i < BOARDSIZE; i++) {
for (j = 0; j < BOARDSIZE; j++) {
// check if pieces all have shared char at index
}
}
}

我该如何改进这一点,让自己更轻松?

每个属性都有两种可能性,因此您可以将它们存储在一个位字段中,作为0或1。例如:

unsigned char type = (color << 0) | (size << 1) | (shape << 2) | (thickness << 3)

其中每个值是0或1。比方说:

enum Color { BLACK = 0, WHITE = 1 };
enum Size { SHORT = 0, TALL = 1 };
enum Shape { CIRCLE = 0, SQUARE = 1 };
enum Thickness { HOLLOW = 0, SOLID = 1 };

然后您可以通过检查XNOR(位相等(来比较它们,以便在一个操作中一次比较2,其中每个比较将返回一个位字段,其中哪些类型的比较相等。

0

像这个

class Piece {
public:
Piece(Color color, Size size, Shape shape, Thickness thickness) {
type = (color) | (size << 1) | (shape << 2) | (thickness << 3);
}
Color color() const {
return static_cast<Color>((type >> 0) & 1);
}
Size size() const {
return static_cast<Size>((type >> 1) & 1);
}
Shape shape() const {
return static_cast<Shape>((type >> 2) & 1);
}
Thickness thickness() const {
return static_cast<Thickness>((type >> 3) & 1);
}
static bool compare(Piece p0, Piece p1, Piece p2, Piece p3) {
unsigned char c[3];
c[0] = ~( p0.type ^ p1.type ); // XNOR
c[1] = ~( p1.type ^ p2.type ); // XNOR
c[2] = ~( p2.type ^ p3.type ); // XNOR
return (c[0] & c[1] & c[2] & 0b1111) != 0;
}
protected:
unsigned char type;
};

我用这个代码测试了它:

int main() {
Piece p0(WHITE, SHORT, CIRCLE, HOLLOW);
Piece p1(WHITE, SHORT, CIRCLE, HOLLOW);
Piece p2(BLACK, SHORT, CIRCLE, HOLLOW);
Piece p3(BLACK, TALL, CIRCLE, SOLID);
const char* str = Piece::compare(p0, p1, p2, p3) ? "success" : "fail";
std::cout << str << 'n';
return 0;
}

我决定用一个类来管理它,然而,每个部分都是一个4位的值,所以它可以很容易地以积分类型进行管理。

这样做的另一个结果是,可以通过选择0b0000和0b1111之间的值来随机化片段,该值包括[0,15]。