-
Notifications
You must be signed in to change notification settings - Fork 0
/
Location.cs
162 lines (131 loc) · 4.14 KB
/
Location.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.VisualStyles;
using Newtonsoft.Json;
namespace WDS_Dispatches
{
public class CubeHex {
public double Q { get; set; }
public double R { get; set; }
public double S { get; set; }
public static double lerp (double a, double b, double t) {
return a + t*(b - a);
}
public static CubeHex CubeLerp(CubeHex a, CubeHex b, double t) {
return new CubeHex(
lerp(a.Q, b.Q, t),
lerp(a.R, b.R, t),
lerp(a.S, b.S, t)
);
}
public CubeHex(double q, double r, double s) {
Q = q;
R = r;
S = s;
}
public CubeHex(Location l) {
this.Q = (double)l.X;
this.R = (double)(l.Y - (l.X + (l.X & 1)) / 2);
this.S = (double)(-this.Q - this.R);
}
public CubeHex Subtract(CubeHex b) {
return new CubeHex(
this.Q - b.Q,
this.R - b.R,
this.S - b.S
);
}
public int DistanceTo(CubeHex b){
CubeHex vec = this.Subtract(b);
return ((int)(Math.Abs(vec.Q) + Math.Abs(vec.R) + Math.Abs(vec.S))) / 2;
}
public CubeHex MoveTowards(CubeHex b, int steps) {
int dist = this.DistanceTo(b);
if(dist == 0) {
return this;
}
return CubeLerp(
this,
b,
(double)(1.0 / dist) * Math.Min(steps, dist)
);
}
public CubeHex Round() {
double q = Math.Round(this.Q);
double r = Math.Round(this.R);
double s = Math.Round(this.S);
double q_diff = Math.Abs(q - this.Q);
double r_diff = Math.Abs(r - this.R);
double s_diff = Math.Abs(s - this.S);
if (q_diff > r_diff && q_diff > s_diff) {
q = -r - s;
} else if (r_diff > s_diff) {
r = -q - s;
} else {
s = -q - r;
}
return new CubeHex(q, r, s);
}
public Location ToLocation() {
CubeHex rounded = this.Round();
int q = (int)rounded.Q;
int r = (int)rounded.R;
return new Location(
q,
r + (q + (q & 1)) / 2
);
}
}
public class Location {
public int X { get; set; }
public int Y { get; set; }
public override string ToString() {
if (!IsPresent()) {
return "(not present)";
}
return "(" + X + ", " + Y + ")";
}
public Location(int x = -1, int y = -1)
{
Set(x, y);
}
public bool IsPresent() {
return (X != -1 && Y != -1);
}
private static Location evenq_to_axial(Location hex) {
int q = hex.X;
int r = hex.Y - (hex.X + (hex.X & 1)) / 2;
return new Location(q, r);
}
private static int axial_distance(Location a, Location b) {
return (
Math.Abs(a.X - b.X) +
Math.Abs(a.X + a.Y - b.X - b.Y) +
Math.Abs(a.Y - b.Y)
) / 2;
}
public void Set(int x, int y) {
X = x;
Y = y;
}
public int DistanceTo(Location b) {
if(!IsPresent() || !b.IsPresent()) {
return 999999;
}
Location a_axial = evenq_to_axial(this);
Location b_axial = evenq_to_axial(b);
return axial_distance(a_axial, b_axial);
}
public bool Equals(Location other) {
return this.X == other.X && this.Y == other.Y;
}
public Location MoveTowards(Location b, int steps) {
CubeHex cube_a = new CubeHex(this);
CubeHex cube_b = new CubeHex(b);
return cube_a.MoveTowards(cube_b, steps).ToLocation();
}
}
}