admin 發表於 2024-4-22 16:17:39

使用位字段和掩码寫一個國際象棋遊戲

假如你在用 C 說话寫一個國際象棋遊戲。追踪棋盘上棋子的一種法子是界說一個布局,该布局界說了棋盘上每一個可能的棋子及其色彩,是以每一個格子都包括该布局中的一個元素。比方,你可以将布局界說成下面如许:

struct chess_pc {
int piece;
int is_black;
}
有了這個数据布局,你的步伐就會晓得每一個格子里是甚麼棋子及棋子的色彩。你可以快速辨認出棋子是兵、車、马、象、後仍是王,和棋子是黑仍是白。可是,有一種更直接的法子来跟踪這些信息,同時只用音波拉皮, 更少的数据和内存。與為棋盘上的每一個方格存储hoya,两個 int 值的布局分歧,咱们可以存储单個 int 值,并利用二進制位字段和掩码来標識每一個方格中的棋子和色彩。

當利用位字段暗示数据時,咱们最仿佛计较機同样思虑。讓咱们從列出可能的棋子起頭,并為每一個棋子分派一個数字。讓咱们進入下一個步调,用二進制暗示這個数字,也就是依照计较機追踪它的方法。记着,二進制数是由比特構成的,比特要末是 0,要末是 1。

要列出一個棋盘上的所有棋子,咱们只必要三個比特從右到左挨次代表值 一、2 和 4。比方,数字 6 是二進制的 110。6 的二進制暗示中的其他所有位都是 0。

一個聪慧一點的法子:咱们可使用那些分外的老是為零的比特来跟踪一個棋子是黑仍是白。咱们可使用数字 8(二進制 00001000)来暗示棋子是不是為玄色。若是這一名是 1,則代表该棋子是玄色;若是是 0,則代表该棋子是白色。這被称為位字段,稍後咱们可小琉球三天兩夜包棟民宿,使用二進制掩码将其掏出。

要编寫一個利用位字段和掩码的國際象棋步伐,咱们可以從如下界說起頭:

/* 棋子 */
#define EMPTY 0   // 空
#define PAWN 1    // 兵
#define ROOK 2    // 車
#define KNIGHT 3// 马
#define BISHOP 4// 象
#define QUEEN 5   // 後
#define KING 6    // 王

/* 棋色 */
#define BLACK 8   // 黑
#define WHITE 0   // 白

/* 掩码 */
#define PIECE 7
當你為一個棋格赋值時,好比初始化棋盘,你可以赋一個 int 類型的值来跟踪棋子及其色彩。比方,要在棋盘的 0,0 位置存储棋子黑車,你可使用下面的代码:

int board;
..
board = BLACK | ROOK;
| 是二進制“或”(OR)操作符,這象征着计较機将归并两個数字的比特。對付每一個比特的位置,若是肆意一個数字的比特為 1,该位置比特的成果也是 寵物商品, 1。BLACK 的值(8,即二進制下的 00001000)和 ROOK 的值(2,即二進制下的 00000010)的二進制或成果是二進制下的 00001010,即 10:

00001000 = 8
OR 00000010 = 2
________
00001010 = 10
雷同地,要在棋盘的 6,0 位置存储一個白色兵,你可以如许做:

board = WHITE | PAWN;
如许存储的值就是 WHITE(0)和 PAWN(1)的二進制或的成果,也便是 1。

00000000 = 0
OR 00000001 = 1
________
00000001 = 1
鄙人棋進程中,步伐必要晓得棋格中的棋子和它的色彩。咱们可使用二進制掩码来分手這部門。

举個例子,步伐可能必要晓得棋局中棋盘上特定棋格的内容,比方位於 board 的数组元素。這個是甚麼棋子,是黑的仍是白的?為了辨認棋子,利用二進制“與”(AND)操作符将元素的值與掩码 PIECE 連系起来:

int board;
int piece;
..
piece = board & PIECE;
二進制“與”(AND)操作符(&)将两個二進制值連系,如许對付肆意位,若是两個数字中的阿谁位都是 1,那末成果也是 1。比方,若是 board 的值是 11(二進制下的 00001011),那末 11 和 掩码 PIECE(7,二進制下的 00000111)二進制與的成果為二進制下的 00000011,也即 3。頭髮增長液,這代表马,马的值是 3。

00001011 = 11
AND 00000111 = 7
________
00000011 = 3
解析棋子的色彩是一個简略的事變,只必要将棋子的值與 BLACK 位字段举行二進制與操作。好比,你可以寫一個名為 is_black 的函数来肯定棋子是黑仍是白:

int is_black(int piece)
{
return (piece & BLACK);
}
之以是可以如许,是由於 BLACK 的值為 8(二進制下的 00001000)。在 C 說话中,任何非零值都被視為 True,零老是 False。以是若是 5,3 處的棋子是玄色的,則 is_black(board) 返回 True 值(8);若是是白色的,則返回 False 值(0)。

利用位字段和掩码是不利用布局组合数据的經常使用法子。它们值得被步伐员保藏到“东西包”中。固然数据布局對付必要跟踪相干数据的有序编程是一種有價值的东西,可是利用零丁的元夙来跟踪单個的開或闭值(比方棋子的色彩)的效力较低。在這些环境下,可以斟酌利用位字段和掩码来更高效地组合数据。

本文瘦身產品,利用 CC BY-SA 4.0 國際协定 举行允许,接待 依照协定划定 轉载。

原文: Write a chess game using bit-fields and masks

首發:利用位字段和掩码寫一個國際象棋遊戲 @ Linux中國
頁: [1]
查看完整版本: 使用位字段和掩码寫一個國際象棋遊戲