1- 分析


通過對照觀察,我們會發(fā)現,在這個自動拼接元素上,小元素可以分為以下幾種:
A- 向內轉角(也就是0,1,6,7,以及12, 17, 42, 47,這里只取一組即可 )(FIXED:這里選擇12,17,42,47這組,因為部分特殊元素這四個才是真實的向內轉角)
B- 向外轉角(4,5,10,11)
C- 上下連接(24,29,30,35)
D- 左右連接(14,15,44,45)
E- 填充物(26,27,32,33)
通過觀察組合圖塊,我們會發(fā)現下面的幾條規(guī)律
A- 斜方向的同類塊對目標塊的影響當且僅當斜方向相鄰的兩個垂直方向上都有同類塊的時候才會出現。也就是將目標塊的對應小圖塊變成填充物。
B- 當兩個相鄰的垂直方向上都有同類塊,且他們之間的斜方向上沒有同類塊的時候,目標快對應的小圖塊變成向外轉角
C- 當某個垂直方向上有同類塊,且相鄰的一個垂直方向上沒有同類塊,無論相鄰的斜方向上有沒有同類塊,目標塊對應的小圖塊變成連接(向上下或者向左右連接)
D- 當某個垂直方向上沒有同類塊,且相鄰的垂直方向上也沒有同類塊,無論相鄰的斜方向上有沒有同類塊,目標塊對應的小圖塊變成向內轉角
2- 生成算法(C#代碼)
1 // 填充物 26 27 32 33
2 // 向外轉角 4 5 10 11
3 // 上下連接 24 29 30 35
4 // 左右連接 14 15 44 45
5 // 向內轉角 12 17 42 47
6
7 // 各方向比特 1 2 4 8 16 32 64 128
8
9 // 4 個小圖塊對應的索引
10 // 0 1 小圖塊在大圖塊里
11 // 2 3 按照這種順序排列
12 byte[] mTile = new byte[4];
13 // 調色板數組,每個元素是一個包含4個索引的DWORD
14 UInt32[] mAutoTilePal = new UInt32[256];
15
16 for (uint nIndex = 0; nIndex < 256; nIndex++)
17 {
18 // 初始化成向內轉角
19 mTile[0] = 12;
20 mTile[1] = 17;
21 mTile[2] = 42;
22 mTile[3] = 47;
23 // 如果上方有同類塊
24 if ((nIndex & 2) > 0)
25 {
26 // 如果左方有同類塊
27 if ((nIndex & 128) > 0)
28 {
29 // 如果左上方有同類塊
30 if ((nIndex & 1) > 0)
31 {
32 // 目標塊左上為填充物
33 mTile[0] = 26;
34 }
35 else
36 {
37 // 目標塊左上為向外轉角
38 mTile[0] = 4;
39 }
40 }
41 else
42 {
43 // 目標塊左上為向上連接
44 mTile[0] = 24;
45 }
46
47 // 如果右方有同類塊
48 if ((nIndex & 8) > 0)
49 {
50 // 如果右上方有同類塊
51 if ((nIndex & 4) > 0)
52 {
53 // 目標塊右上為填充物
54 mTile[1] = 27;
55 }
56 else
57 {
58 // 目標塊右上為向外轉角
59 mTile[1] = 5;
60 }
61 }
62 else
63 {
64 // 目標塊右上為向上連接
65 mTile[1] = 29;
66 }
67 }
68 else
69 {
70 // 如果左方有同類塊
71 if ((nIndex & 128) > 0)
72 {
73 // 目標左上為向左連接
74 mTile[0] = 14;
75 }
76 // 如果右方有同類塊
77 if ((nIndex & 8) > 0)
78 {
79 // 目標右上為向右連接
80 mTile[1] = 15;
81 }
82 }
83
84 // 如果下方有同類塊
85 if ((nIndex & 32) > 0)
86 {
87 // 如果左方有同類塊
88 if ((nIndex & 128) > 0)
89 {
90 // 如果左下方有同類塊
91 if ((nIndex & 64) > 0)
92 {
93 // 目標塊左下為填充物
94 mTile[2] = 32;
95 }
96 else
97 {
98 // 目標塊左下為向外轉角
99 mTile[2] = 10;
100 }
101 }
102 else
103 {
104 // 目標塊左下為向下連接
105 mTile[2] = 30;
106 }
107
108 // 如果右方有同類塊
109 if ((nIndex & 8) > 0)
110 {
111 // 如果右下方有同類塊
112 if ((nIndex & 16) > 0)
113 {
114 // 目標塊右下為填充物
115 mTile[3] = 33;
116 }
117 else
118 {
119 // 目標塊右下為向外轉角
120 mTile[3] = 11;
121 }
122 }
123 else
124 {
125 // 目標塊右下為向下連接
126 mTile[3] = 35;
127 }
128 }
129 else
130 {
131 // 如果左方有同類塊
132 if ((nIndex & 128) > 0)
133 {
134 // 目標塊左下為向左連接
135 mTile[2] = 44;
136 }
137 // 如果右方有同類塊
138 if ((nIndex & 8) > 0)
139 {
140 // 目標塊右下為向右連接
141 mTile[3] = 45;
142 }
143 }
144
145 mAutoTilePal[nIndex] = (UInt32)mTile[0];
146 mAutoTilePal[nIndex] |= ((UInt32)mTile[1]) << 8;
147 mAutoTilePal[nIndex] |= ((UInt32)mTile[2]) << 16;
148 mAutoTilePal[nIndex] |= ((UInt32)mTile[3]) << 24;
149 }