簡體   English   中英

表示四開棋盤游戲棋子的最佳方式

[英]Best way to represent Quarto Board Game Pieces

我正在創建棋盤游戲 Quarto。 它本質上是高級連接 4。

每件作品都有四個顯着特征(白色 VS 黑色 | 高 VS 短 | 方形 VS 圓形 | 實心 VS 空心)。 如果您連續獲得其中任何一項功能,您就贏了。

目前,我正在嘗試編寫 function 來檢查是否獲勝。 但是,它有望達到 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 ",
  "____ ",
};

但我認為這不是很有效。 我曾考慮過讓它們成為自己的 class,但這樣就很難初始化和使用所有這些部件。

這就是我開始 go 關於檢查勝利的方式:

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

我怎樣才能改善這一點,讓自己更容易?

每個屬性都有 2 種可能性,因此您可以將它們作為 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,其中每次比較將返回一個位字段,其中比較的類型相同。

(piece1 XNOR piece2) AND (piece2 XNOR piece3) AND (piece3 XNOR piece4) != 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;
}

我決定用 class 來管理它,但是,每個部分都是一個 4 位值,因此可以很容易地以整數類型進行管理。

這樣做的另一個結果是,可以通過選擇 0b0000 和 0b1111 之間的值(包括 [0,15])來隨機化片段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM