【Unity】二次元配列のコピーや初期化

2048のバグを修正しているのですが、
上手く行きません。(ToT )( ToT) ウルウル

バグの修正をするよりもシステム自体を作り直す方が早い?
と思いまして、一から作り直しています。

新しいシステムが機能するといいのですが…


2048の事は、この辺で置いといて
配列について、調べた事があるので記事にしてみます。


2048のスクリプトでも、二次元配列の初期化を行ったのですが、
forループで0を代入する方法でした。

どうやらコマンドがあるようで、初期化やコピーが出来るみたいです。

知っている方からすれば今更なんですが、
今まで存在すら知りませんでした。(~-~;)ヾ(-_-;) オイオイ


ループで処理する事には、問題ないのですが、
ループとコマンドで処理速度を比較されているサイトを見ると
コマンドで処理する方が早いようです。

なので、コマンドを使えるように勉強したいと思います。


変数のコピーは、

int A=10;
int B=5;

A=B;

これでAに5が代入されて
Bの値がコピーされました。

この後、Bに新しい数値を代入してやれば、

B=2;

Debug.Log(A);
Debug.Log(B);

コンソールには、5と2が表示されます。

配列で同じ事をしてみます。

int[]A=new int[5];
int[]B={1,2,3,4,5};

A=B;

B[0]=2;

Debug.Log(A[0]);
Debug.Log(B[0]);

コンソールには、2と2が表示されます。

説明は難しいのですが、
配列の場合、シャローコピー(浅いコピー)となり
要素の値ではなくて、参照のみがコピーされるそうです。

この状況でB[1]=10と入力すると、A[1]も10が代入されてしまいます。

配列AとBは同じ扱いになり、別の配列にはなりません。

では、コピーするにはどうすれば…
そこで、CopyToです。

int[]A=new int[5];
int[]B={1,2,3,4,5};

B.CopyTo(A, 0);

B[0]=2;

Debug.Log(A[0]);
Debug.Log(B[0]);

コンソールの表示は、1と2が表示されます。
ディープコピーと言って、配列要素や参照型の構造も含めて全てコピーされるそうです。

コマンドは、コピー元配列.CopyTo(コピー先配列,開始インデックス)
開始インデックスは、コピー先の何番目から代入するとなります。



では、二次元配列ではどうなるかと言うと

int[,] A = new int[4,4];
int[,] B = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };

B.CopyTo(A, 0);

B[0,0]=2;

Debug.Log(A[0,0]);
Debug.Log(B[0,0]);

エラーが掛かります。

2048㊾.jpg
CopyToは二次元配列には対応してないようです。

二次元配列のコピーには、Array.Copyを使います。

using System;

int[,] A = new int[4,4];
int[,] B = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };

Array.Copy(B, 0, A, 0, 16);

B[0,0]=2;

Debug.Log(A[0,0]);
Debug.Log(B[0,0]);

Arrayを使う場合は、名前空間にSystemを宣言します。
宣言しないとエラーになるので注意です。


処理後のコンソールには、0と2が表示されます。

コマンドは、
Array.Copy(コピー元, 開始インデックス, コピー先, 開始インデックス, 要素数)

コピー元とコピー先でレンジが同じ場合は、
Array.Copy(B, 0, A, 0, B.Length);
これでも問題ありません。

列によってレンジが変わる場合は、要素数を指定するか
コピー元のレンジを取得して代入するようにします。


これで、二次元配列のコピーが簡単にできるようになりました。


続いて、配列や二次元配列の初期化です。

using System;

int[,] A = new int[4,4];
int[,] B = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
int[] D = { 1, 2, 3, 4 };

Array.Clear(A, 0, A.Length);
Array.Clear(B, 0, 16);
Array.Clear(C, 0, 4);

Arrayを使うので、Systemを宣言します。
配列でも二次元配列でも使い方は同じです。

Array.Clear(初期化する配列, 開始インデックス, 要素数)

要素数はレンジでも指定できます。
Array.Clear(C, 0, C.Length)でも処理できます。

数値だけでなく、bool型配列も初期化できます。

初期化後は、
int型なら0
bool型ならfalseが代入されます。


配列のコピー・初期化は以上となります。
List配列を併用する場合、いろいろと使えそうな感じですね~

Arrayには、まだまだ多くのコマンドがあるので機会があれば
試していこうと思います。

また、新しい使い方が分かれば記事にしたいと思います。
今回はこのへんで
(o・・o)/~マタネェ


この記事へのコメント