I created a struct in C# for storing the X, Y and Z coordinates for characters, objects and rooms within my current PBBG project Perenthia. The struct, called Vector, is serializable and can be used as the key value in a sorted or generic dictionary. Here is the code for the class.
[Serializable] public struct Vector : IEquatable<Vector> { public static readonly Vector Empty = new Vector(0, 0, 0); public Vector(int x, int y, int z) { _x = x; _y = y; _z = z; } public void SetLocation(int x, int y) { this.SetLocation(x, y, this.Z); } public void SetLocation(int x, int y, int z) { _x = x; _y = y; _z = z; } public Vector Copy() { return new Vector(this.X, this.Y, this.Z); } public static Vector FromString(string value) { if (!String.IsNullOrEmpty(value)) { string[] parts = value.Split(','); if (parts != null && parts.Length == 3) { int x, y, z; if (Int32.TryParse(parts[0], out x)) { if (Int32.TryParse(parts[1], out y)) { if (Int32.TryParse(parts[2], out z)) { return new Vector(x, y, z); } } } } } return Vector.Empty; } #region GetHashCode public override int GetHashCode() { // The Y value should always come first in any kind of sorting, comparison or hashing operations // followed by X and then Z because typical loops would start with the Y value. return (this.Y.GetHashCode() + this.X.GetHashCode() + this.Z.GetHashCode()); } #endregion #region Equals public bool Equals(Vector obj) { // The Y value should always come first in any kind of sorting, comparison or hashing operations // followed by X and then Z because typical loops would start with the Y value. if (obj != null) { if (obj.Y == this.Y) { if (obj.X == this.X) { return (obj.Z == this.Z); } } } return false; } public override bool Equals(object obj) { if (obj is Vector) { return this.Equals((Vector)obj); } return base.Equals(obj); } #endregion #region ToString public override string ToString() { return String.Format("{0},{1},{2}", _x, _y, _z); } public string ToString(bool forDisplay) { if (forDisplay) { return String.Format("X = {0}, Y = {1}, Z = {2}", _x, _y, _z); } return this.ToString(); } #endregion #region Operators public static Vector operator +(Vector v1, Vector v2) { return new Vector(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z); } public static Vector operator -(Vector v1, Vector v2) { return new Vector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z); } public static bool operator ==(Vector v1, Vector v2) { return v1.Equals(v2); } public static bool operator !=(Vector v1, Vector v2) { return (!v1.Equals(v2)); } public static bool operator >=(Vector v1, Vector v2) { // The Y value should always come first in any kind of sorting, comparison or hashing operations // followed by X and then Z because typical loops would start with the Y value. if (v1.Y >= v2.Y) { if (v1.X >= v2.X) { return (v1.Z >= v2.Z); } } return false; } public static bool operator <=(Vector v1, Vector v2) { // The Y value should always come first in any kind of sorting, comparison or hashing operations // followed by X and then Z because typical loops would start with the Y value. if (v1.Y <= v2.Y) { if (v1.X <= v2.X) { return (v1.Z <= v2.Z); } } return false; } #endregion #region Properties private int _x; public int X { get { return _x; } set { _x = value; } } private int _y; public int Y { get { return _y; } set { _y = value; } } private int _z; public int Z { get { return _z; } set { _z = value; } } #endregion #region IEquatable<Vector> Members bool IEquatable<Vector>.Equals(Vector other) { return this.Equals(other); } #endregion }
7/16/2007