3

すべてのテトリスの定義を設定したい:

#include <iostream>
#include <vector>

struct Tetris{
    std::vector<int> data;
    int getAt(int x, int y){return data.at(y*4+x);};
} tetris[6];

int main(){
    //stick
    tetris[0].data.resize(32);
    int array0[32]={0,0,0,0,
                    0,0,0,0,
                    1,1,1,1,
                    0,0,0,0,
                    0,1,0,0,
                    0,1,0,0,
                    0,1,0,0,
                    0,1,0,0};
    tetris[0].data.assign(array0,array0+32);

    //brick
    tetris[1].data.resize(16);
    int array1[16]={0,0,0,0,
                    0,1,1,0,
                    0,1,1,0,
                    0,0,0,0};
    tetris[1].data.assign(array1,array1+16);

    ...

}

このように、初期化データ ( array0array1...) を格納するためだけに 6 つの配列を定義する必要がありますが、これは初期化後には役に立ちません。これは非常に非効率的で、メモリの無駄遣いのようです。各使用後にそれらのデータを削除する方法があるかどうか疑問に思っていますか?

アップデート:

を再利用したい場合はarray0

    tetris[0].data.resize(32);
    int array0[32]={...};
    tetris[0].data.assign(array0,array0+32);

    //brick
    tetris[1].data.resize(16);
    delete array0;
    int array0[16]={...};
    tetris[1].data.assign(array0,array0+16);

    ...

コンパイラは、「array0 の再定義」のエラーを報告します。deleteこの場合動作しませんか?

4

3 に答える 3

1

プログラムでタイルを生成しようとすることもできますが、対称性のために注意が必要な重複があり、生成されたパターンの一部は偽物である可能性があります。次に例を示します。

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 バイトのスペースしか消費されません (データを操作するために必要な追加のコードによって使用されるスペースはカウントされず、そのまま残ります)。練習…)。

それ以外の場合は、データ全体を保持し、 flyweightパターンを使用してオブジェクトを実装します。各オブジェクトには、テトロミノのランクとその回転 ( 090180、および270、つまり 4 つの異なる状態) のみが含まれます。上記のプログラムによって生成された配列全体 (384 バイト) を含め、ランクと状態からビットマスクを計算する関数を作成する必要があります (これは、提供されたプログラムのコードから推測できます)。

于 2013-06-06T19:57:07.663 に答える