[アルゴリズム]六角対応 の続きです。
前回ヘックスマップにおけるデータ表現を書きました。
ならば次はこれだ!!
正三角形を敷き詰めた形ですね。
やっぱりこの形をそのまま使うのは難しいので、これを正方形の形に変換します。
上の形を変換したのが下の形です。
見やすさのために四隅を切り落としています。
赤い線が目立ちますが、これは壁です。
黄色なら下、水色なら上側が壁になり、ここは通行できません。
三角形と見比べてみると、この赤い線は頂点になります。
1マスで移動できる領域です。
上三角と下三角の形の二種類があるので、移動できる場所が異なります。
前回同様、距離の図です。
これも、ややこしいですが、前回同様Xの移動量とYの移動量で分けてみます。
紫の領域は非常に素直で、X+Yがそのまま距離となります。
しかし、橙の領域はなんだか変なことになっています。
一番下の行を見ると、76767と交互に数字が並んでいる、ってのはわかるわけですが…。
まず、橙のマスの中で、偶数になっているものを見ましょう。
すると、必ず市松模様上に配置され、しかもその値はYの移動量の2倍です。
あとは、奇数のマスは偶数マスの+1か-1で、その法則も簡単に割り出せます。
それを踏まえて作ったソースがこちら。
/* 上方向に移動する場合、Yはマイナスになる */
/* IsUpperは、そのマスが上三角(△) ならばtrue */
int distanct(int x, int y, int dx, int dy){
int ax = abs(dx);
int ay = abs(dy);
if (ax < ay){
/* Yの移動量が多い場合 */
if (IsUpper(x, y) == (0 < dy))
/* 最初の移動方向に壁なし */
return ay * 2 - (ax + ay) % 2;
}else{
/* 最初の移動方向に壁あり */
return ay * 2 + (ax + ay) % 2;
}
}else{
/* Xの移動量が多い場合 */
return ax + ay;
}
}
要は、最初の移動方向に壁があるかどうかでチェックすればいいわけです。
これで、三角形を敷き詰めるようなパターンを作りたい場合もある程度すっきりかけることになります。