あなたは本当の問題を過度に制約していると思います。これは、私がゲーム エンジンで遭遇した問題と非常によく似ています。16 進グリッド上の座標は、標準参照フレーム (ほとんどの内部ゲーム機能に便利な 120 度の軸) または長方形 (ユーザー) 参照フレームのいずれかになります。軸が 90 度の場合 (ユーザーに表示されるほとんどのゲーム機能に便利です)。
ICoordsCanon と ICoordsUser の両方のインターフェイスを明示的に実装する単一のクラス Coords を作成することで、これに対処しました。実際の座標は遅延保存され、次のような自動変換で評価されます。
protected static IntMatrix2D MatrixUserToCanon;
protected IntVector2D VectorCanon {
get { return ! isCanonNull ? _vectorCanon
: VectorUser * MatrixUserToCanon; }
set { _vectorCanon = value; isUserNull = true; }
} IntVector2D _vectorCanon;
bool isCanonNull;
protected static IntMatrix2D MatrixCanonToUser;
protected IntVector2D VectorUser {
get { return ! isUserNull ? _vectorUser
: VectorCanon * MatrixCanonToUser; }
set { _vectorUser = value; isCanonNull = true; }
} IntVector2D _vectorUser;
bool isUserNull;
Coords のコンストラクターはプライベートであり、パブリックな静的関数 NewUserCoords(...) および NewCanonCoords(...) が定義されています。
実装は実際には ... でも ... でもありませんが、アプリケーションにはそのように実装されているように見えます。ほとんどのアプリケーションの使用法は、ICoordsCanon オブジェクトまたは ICoordsUser オブジェクトのいずれかで機能します。ICoordsCanon.User() と ICoordsUser.Canon() の 2 つのメソッドは、必要に応じて 2 つの間で変換するために存在します。
一般的な要望により、インターフェースの定義と実装を以下に示します。
public interface ICoordsUser {
int X { get; }
int Y { get; }
IntVector2D Vector { get; set; }
ICoordsCanon Canon { get; }
//ICoordsUser Clone();
string ToString();
int Range(ICoordsUser coords);
IEnumerable<NeighbourCoords> GetNeighbours(Hexside hexsides);
}
public partial class Coords {
int ICoordsUser.X { get { return VectorUser.X; } }
int ICoordsUser.Y { get { return VectorUser.Y; } }
IntVector2D ICoordsUser.Vector { get { return VectorUser; }
set { VectorUser=value; } }
ICoordsCanon ICoordsUser.Canon { get { return this; } }
//ICoordsUser ICoordsUser.Clone() { return NewUserCoords(VectorUser); }
string ICoordsUser.ToString() { return VectorUser.ToString(); }
IEnumerable<NeighbourCoords> ICoordsUser.GetNeighbours(Hexside hexsides) {
return GetNeighbours(hexsides);
}
int ICoordsUser.Range(ICoordsUser coords) { return Range(coords.Canon); }
}
}
と
public interface ICoordsCanon {
int X { get; }
int Y { get; }
IntVector2D Vector { get; set; }
ICoordsCustom Custom { get; }
ICoordsUser User { get; }
//ICoordsCanon Clone();
string ToString();
int Range(ICoordsCanon coords);
IEnumerable<NeighbourCoords> GetNeighbours(Hexside hexsides);
}
public partial class Coords {
int ICoordsCanon.X { get { return VectorCanon.X; } }
int ICoordsCanon.Y { get { return VectorCanon.Y; } }
IntVector2D ICoordsCanon.Vector { get { return VectorCanon; }
set { VectorCanon=value; } }
ICoordsUser ICoordsCanon.User { get { return this; } }
ICoordsCustom ICoordsCanon.Custom { get { return this; } }
//ICoordsCanon ICoordsCanon.Clone() { return NewCanonCoords(this.VectorCanon); }
string ICoordsCanon.ToString() { return VectorCanon.ToString(); }
IEnumerable<NeighbourCoords> ICoordsCanon.GetNeighbours(Hexside hexsides) {
return GetNeighbours(hexsides);
}
int ICoordsCanon.Range(ICoordsCanon coords) { return Range(coords); }
}
クラス Coords の定義全体を含めていないことに注意してください。これは単純に投稿が大きすぎるためです。実装全体は、ここの CodePlex で入手できます: HexGrid Utilities