-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathGridIndex.cs
154 lines (120 loc) · 5.75 KB
/
GridIndex.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
using System.Runtime.Serialization;
namespace System.Grid
{
/// <summary>
/// Represent the coordinates of the 2D grid. The value of each component is greater than or equal to 0.
/// </summary>
[Serializable]
public readonly struct GridIndex : IEquatableReadOnlyStruct<GridIndex>, ISerializable
{
public readonly int Row;
public readonly int Column;
public int this[int index]
{
get
{
if (index == 0) return this.Row;
if (index == 1) return this.Column;
throw new IndexOutOfRangeException();
}
}
public GridIndex(int row, int column)
{
this.Row = Math.Max(row, 0);
this.Column = Math.Max(column, 0);
}
private GridIndex(SerializationInfo info, StreamingContext context)
{
this.Row = Math.Max(info.GetInt32OrDefault(nameof(this.Row)), 0);
this.Column = Math.Max(info.GetInt32OrDefault(nameof(this.Column)), 0);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(this.Row), this.Row);
info.AddValue(nameof(this.Column), this.Column);
}
public void Deconstruct(out int row, out int column)
{
row = this.Row;
column = this.Column;
}
public GridIndex With(int? Row = null, int? Column = null)
=> new GridIndex(
Row ?? this.Row,
Column ?? this.Column
);
public int ToIndex1(int columnCount)
=> columnCount <= 0 ? 0 : this.Column + this.Row * columnCount;
public int ToIndex1(in GridIndex size)
=> size.Column <= 0 ? 0 : this.Column + this.Row * size.Column;
public override bool Equals(object obj)
=> obj is GridIndex other && this.Row == other.Row && this.Column == other.Column;
public bool Equals(GridIndex other)
=> this.Row == other.Row && this.Column == other.Column;
public bool Equals(in GridIndex other)
=> this.Row == other.Row && this.Column == other.Column;
public override int GetHashCode()
{
#if USE_SYSTEM_HASHCODE
return HashCode.Combine(this.Row, this.Column);
#endif
#pragma warning disable CS0162 // Unreachable code detected
var hashCode = 240067226;
hashCode = hashCode * -1521134295 + this.Row.GetHashCode();
hashCode = hashCode * -1521134295 + this.Column.GetHashCode();
return hashCode;
#pragma warning restore CS0162 // Unreachable code detected
}
public override string ToString()
=> $"({this.Row}, {this.Column})";
/// <summary>
/// Shorthand for writing GridIndex(0, 0)
/// </summary>
public static GridIndex Zero { get; } = new GridIndex(0, 0);
/// <summary>
/// Shorthand for writing GridIndex(1, 1)
/// </summary>
public static GridIndex One { get; } = new GridIndex(1, 1);
/// <summary>
/// Shorthand for writing GridIndex(0, 1)
/// </summary>
public static GridIndex Right { get; } = new GridIndex(0, 1);
/// <summary>
/// Shorthand for writing GridIndex(1, 0)
/// </summary>
public static GridIndex Up { get; } = new GridIndex(1, 0);
public static implicit operator GridIndex(in (int row, int column) value)
=> new GridIndex(value.row, value.column);
public static bool operator ==(in GridIndex lhs, in GridIndex rhs)
=> lhs.Row == rhs.Row && lhs.Column == rhs.Column;
public static bool operator !=(in GridIndex lhs, in GridIndex rhs)
=> lhs.Row != rhs.Row || lhs.Column != rhs.Column;
public static GridIndex operator +(in GridIndex lhs, in GridIndex rhs)
=> new GridIndex(lhs.Row + rhs.Row, lhs.Column + rhs.Column);
public static GridIndex operator -(in GridIndex lhs, in GridIndex rhs)
=> new GridIndex(lhs.Row - rhs.Row, lhs.Column - rhs.Column);
public static GridIndex operator *(in GridIndex lhs, int rhs)
=> new GridIndex(lhs.Row * rhs, lhs.Column * rhs);
public static GridIndex operator *(int lhs, in GridIndex rhs)
=> new GridIndex(rhs.Row * lhs, rhs.Column * lhs);
public static GridIndex operator *(in GridIndex lhs, in GridIndex rhs)
=> new GridIndex(lhs.Row * rhs.Row, lhs.Column * rhs.Column);
public static GridIndex operator /(in GridIndex lhs, int rhs)
=> new GridIndex(lhs.Row / rhs, lhs.Column / rhs);
public static GridIndex operator /(in GridIndex lhs, in GridIndex rhs)
=> new GridIndex(lhs.Row / rhs.Row, lhs.Column / rhs.Column);
public static GridIndex operator %(in GridIndex lhs, int rhs)
=> new GridIndex(lhs.Row % rhs, lhs.Column % rhs);
public static GridIndex operator %(in GridIndex lhs, in GridIndex rhs)
=> new GridIndex(lhs.Row % rhs.Row, lhs.Column % rhs.Column);
public static GridIndex Clamp(in GridIndex value, in GridIndex min, in GridIndex max)
=> new GridIndex(
value.Row < min.Row ? min.Row : (value.Row > max.Row ? max.Row : value.Row),
value.Column < min.Column ? min.Column : (value.Column > max.Column ? max.Column : value.Column)
);
public static GridIndex Convert(int index1, int columnCount)
=> columnCount <= 0 ? Zero : new GridIndex(index1 / columnCount, index1 % columnCount);
public static GridIndex Convert(int index1, in GridIndex size)
=> size.Column <= 0 ? Zero : new GridIndex(index1 / size.Column, index1 % size.Column);
}
}