您可以尝试以编程方式生成图块,但由于对称性,需要注意重复,并且某些生成的图案可能是伪造的,例如:
int array0[16]={0,0,0,0,
0,0,0,0,
0,0,0,0,
1,1,1,1};
int array0[16]={0,0,0,1,
0,1,0,0,
1,1,0,1,
0,0,1,0};
可以通过尝试每种组合的生成算法生成。为避免重复,您需要建立瓷砖配置中存在的对称规则。在更一般的多联骨牌设置中,这将是一个非常有趣的问题。
对于俄罗斯方块图块,鉴于只有少数有效配置,该解决方案可能有点牵强。但是,您可以节省一点内存空间,方法是将所有图块存储在同一个数组中,使用数组元素的每个位来携带每个图块的信息,然后使用位掩码选择正确的模式。
这是 C++11 中的一个小程序为您进行组合:
#include <array>
#include <vector>
#include <iostream>
#include <utility>
#define WIDTH 4
typedef std::pair<int,int> coord_t;
coord_t coord(int x, int y) {
return std::make_pair(x,y);
}
int index(const coord_t &c) {
//std::cout << "getting (" << c.first << "," << c.second << ")" << std::endl;
return c.first * WIDTH + c.second;
}
coord_t cw (const coord_t &c){
int x = c.first;
int y = c.second;
return coord(WIDTH - 1 - y, x);
}
coord_t r0(const coord_t &c){
return c;
}
coord_t r90(const coord_t &c){
return r0(cw(c));
}
coord_t r180(const coord_t &c){
return r90(cw(c));
}
coord_t r270(const coord_t &c){
return r180(cw(c));
}
typedef coord_t (*rotate)(const coord_t &);
class tetro;
std::ostream &operator <<(std::ostream &out, const tetro &t);
class tetro {
public:
tetro(){ v.reserve(WIDTH * WIDTH); }
tetro(const std::initializer_list<int> &data): v(data){
std::cout << *this << std::endl;
}
tetro(const tetro &src) {
for (int i = 0; i < WIDTH * WIDTH; i++)
v[i] = src.v[i];
}
void set(coord_t c, int val){
v[index(c)] = val;
}
int get(coord_t c) const {
return v[index(c)];
}
void combine (int r, const tetro &b, rotate rot){
int i,j;
for (i = 0; i < WIDTH; i++) {
for (j = 0; j < WIDTH; j++) {
coord_t c = coord(i,j);
set(c, get(c) | ( b.get(rot(c)) << r));
}
}
}
private:
std::vector<int> v;
};
std::ostream &operator <<(std::ostream &out, const tetro &t){
int i,j;
for (i = 0; i < WIDTH; i++) {
for (j = 0; j < WIDTH; j++) {
coord_t c = coord(i,j);
out << t.get(c) << ",";
}
out << std::endl;
}
return out;
}
std::array<tetro, 6> vl {{
{
0,0,1,0,
0,0,1,0,
0,1,1,0,
0,0,0,0
},
{
0,0,0,0,
0,1,1,0,
0,1,1,0,
0,0,0,0
},
{
0,0,0,0,
1,1,1,1,
0,0,0,0,
0,0,0,0
},
{
0,1,0,0,
0,1,0,0,
0,1,1,0,
0,0,0,0
},
{
0,1,0,0,
0,1,1,0,
0,0,1,0,
0,0,0,0
},
{
0,0,0,0,
1,1,1,0,
0,1,0,0,
0,0,0,0
}
}};
void combine(int rank, tetro &t, rotate rot){
for (auto it = vl.begin(); it != vl.end(); ++it) {
t.combine(rank, *it, rot);
rank++;
}
}
int main(){
tetro t;
int d = 6;
combine(0, t, r0);
combine(d, t, r90);
combine(d+d, t, r180);
combine(d+d+d, t, r270);
std::cout << "result " << std::endl << t << std::endl;
}
它从规范和镜像的四元骨开始, 并构建一个包含所有变化的单个数组int
,包括每个四元骨的所有旋转。您可以简单地将代码限制为第一个组合 - 即。如果您的代码已经处理了旋转,则无需旋转,char
而是使用数组,总共仅消耗 16 个字节的空间(不计算操作数据所需的任何其他代码使用的空间,保留为练习...)。
否则,保留整个数据,并使用享元模式来实现您的对象,每个对象仅包含四联体的等级,以及它的旋转(0
、90
、180
和270
,因此 4 种不同的状态)。您必须包含上述程序生成的整个数组(384 字节),并编写函数来根据等级和状态计算位掩码(这可以从提供的程序的代码中推断出来)。