using System.Text.RegularExpressions;
///
/// Represents a struct which contains Virtual Paradise coordinates.
///
public struct OldCoordinates : IEquatable
{
///
/// Gets or sets the direction.
///
public double Direction { get; set; }
///
/// Gets or sets a value indicating whether this instance represents relative coordinates.
///
public bool IsRelative { get; set; }
///
/// Gets or sets the world.
///
public string World { get; set; }
///
/// Gets or sets the X coordinate.
///
public double X { get; set; }
///
/// Gets or sets the Y coordinate.
///
public double Y { get; set; }
///
/// Gets or sets the Z coordinate.
///
public double Z { get; set; }
public static bool operator ==(OldCoordinates left, OldCoordinates right) =>
left.Equals(right);
public static bool operator !=(OldCoordinates left, OldCoordinates right) =>
!(left == right);
///
/// Parses a coordinate string.
///
/// The coordinates to parse.
/// Returns an instance of .
public static OldCoordinates ParseFaster(string coordinates)
{
const string pattern =
@"(?:([a-z]+) +)?(?: *(\+)?(-?\d+(?:\.\d+)?)([ns])? +(\+)?(-?\d+(?:\.\d+)?)([we])?( +(\+)?(-?\d+(?:\.\d+)?)a)?( +(\+)?(-?\d+(?:\.\d+)?))?)?";
Regex regex = new(pattern, RegexOptions.IgnoreCase);
Match match = regex.Match(coordinates);
bool relative = match.Groups[2].Success || match.Groups[5].Success;
string world = match.Groups[1].Success ? match.Groups[1].Value : string.Empty;
double z = match.Groups[3].Success ? double.Parse(match.Groups[3].Value) : 0.0;
double x = match.Groups[6].Success ? double.Parse(match.Groups[6].Value) : 0.0;
double y = match.Groups[10].Success ? double.Parse(match.Groups[10].Value) : 0.0;
double direction = match.Groups[13].Success ? double.Parse(match.Groups[13].Value) : 0.0;
if (match.Groups[4].Success &&
match.Groups[4].Value.Equals("S", StringComparison.InvariantCultureIgnoreCase))
{
z = -z;
}
if (match.Groups[7].Success &&
match.Groups[7].Value.Equals("E", StringComparison.InvariantCultureIgnoreCase))
{
x = -x;
}
return new OldCoordinates
{
Z = z,
X = x,
Y = y,
Direction = direction,
World = world,
IsRelative = relative
};
}
///
/// Parses a coordinate string.
///
/// The coordinates to parse.
/// Returns an instance of .
public static OldCoordinates Parse(string coordinates)
{
const string pattern =
@"(?:([a-z]+) *)?(?: *(\+)?(-?\d+(?:\.\d+)?)([ns])? +(\+)?(-?\d+(?:\.\d+)?)([we])?( +(\+)?(-?\d+(?:\.\d+)?)a)?( +(\+)?(-?\d+(?:\.\d+)?))?)?";
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
Match match = regex.Match(coordinates);
bool relative = match.Groups[2].Success || match.Groups[5].Success;
string world = match.Groups[1].Success ? match.Groups[1].Value : string.Empty;
double z = match.Groups[3].Success ? Convert.ToDouble(match.Groups[3].Value) : 0.0;
double x = match.Groups[6].Success ? Convert.ToDouble(match.Groups[6].Value) : 0.0;
double y = match.Groups[10].Success ? Convert.ToDouble(match.Groups[10].Value) : 0.0;
double direction = match.Groups[13].Success ? Convert.ToDouble(match.Groups[13].Value) : 0.0;
if (match.Groups[4].Success &&
match.Groups[4].Value.Equals("S", StringComparison.InvariantCultureIgnoreCase))
{
z = -z;
}
if (match.Groups[7].Success &&
match.Groups[7].Value.Equals("E", StringComparison.InvariantCultureIgnoreCase))
{
x = -x;
}
return new OldCoordinates
{
Z = z,
X = x,
Y = y,
Direction = direction,
World = world,
IsRelative = relative
};
}
///
/// Returns the string representation of these coordinates.
///
/// Returns a .
public override string ToString()
{
return ToString("{0}");
}
///
/// Returns the string representation of these coordinates.
///
/// The format to apply to each component.
/// Returns a .
public string ToString(string format)
{
var result = "";
if (!string.IsNullOrWhiteSpace(World))
{
result += $"{World} ";
}
bool north = Z >= 0.0;
bool west = X >= 0.0;
bool up = Y >= 0.0;
bool dir = Direction >= 0.0;
if (IsRelative)
{
string zChar = north ? "+" : "";
string xChar = west ? "+" : "";
string upChar = up ? "+" : "";
string dirChar = dir ? "+" : "";
result += zChar + string.Format(format, Z) + " " +
xChar + string.Format(format, X) + " " +
upChar + string.Format(format, Y) + " " +
dirChar + string.Format(format, Direction);
}
else
{
string zChar = north ? "n" : "s";
string xChar = west ? "w" : "e";
result += zChar + string.Format(format, Z) + " " +
xChar + string.Format(format, X) + " " +
string.Format(format, Y) + "a " +
string.Format(format, Direction);
}
return result;
}
///
public override bool Equals(object? obj)
{
return obj is OldCoordinates other && Equals(other);
}
///
public override int GetHashCode()
{
unchecked
{
int hashCode = Direction.GetHashCode();
hashCode = (hashCode * 397) ^ X.GetHashCode();
hashCode = (hashCode * 397) ^ Y.GetHashCode();
hashCode = (hashCode * 397) ^ Z.GetHashCode();
return hashCode;
}
}
///
public bool Equals(OldCoordinates other)
{
return Direction.Equals(other.Direction) &&
X.Equals(other.X) &&
Y.Equals(other.Y) &&
Z.Equals(other.Z);
}
}