Field.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // SuperTux Editor
  2. // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. using System;
  17. using System.Collections.Generic;
  18. namespace DataStructures
  19. {
  20. /// <summary>This class represents a dynamic 2-dimensional array</summary>
  21. public class Field<T>
  22. {
  23. public List<T> Elements = new List<T>();
  24. protected int width;
  25. protected int height;
  26. public Field()
  27. {
  28. }
  29. public Field(int Width, int Height, T FillValue)
  30. {
  31. this.width = Width;
  32. this.height = Height;
  33. for(int i = 0; i < Width * Height; ++i)
  34. Elements.Add(FillValue);
  35. }
  36. public Field(List<T> Values, int Width, int Height)
  37. {
  38. Assign(Values, Width, Height);
  39. }
  40. /// <summary>
  41. /// Clone Subset of other field
  42. /// </summary>
  43. public Field(Field<T> Other, int startX, int startY, int width, int height) {
  44. this.width = width;
  45. this.height = height;
  46. if (startX < 0) throw new ArgumentOutOfRangeException("startX");
  47. if (startY < 0) throw new ArgumentOutOfRangeException("startY");
  48. if (startX + width > Other.Width) throw new ArgumentOutOfRangeException("startX");
  49. if (startY + height > Other.Height) throw new ArgumentOutOfRangeException("startY");
  50. for (int y = 0; y < height; y++) {
  51. for (int x = 0; x < width; x++) {
  52. Elements.Add(Other[x + startX, y + startY]);
  53. }
  54. }
  55. }
  56. /// <summary>
  57. /// Clone Subset of other field, filling in missing values with FillValue
  58. /// </summary>
  59. public Field(Field<T> Other, int startX, int startY, int width, int height, T FillValue) {
  60. this.width = width;
  61. this.height = height;
  62. for (int y = startY; y < startY + height; y++) {
  63. for (int x = startX; x < startX + width; x++) {
  64. if(x < 0 || y < 0 || x >= Other.Width || y >= Other.Height)
  65. Elements.Add(FillValue);
  66. else
  67. Elements.Add(Other[x, y]);
  68. }
  69. }
  70. }
  71. /// <summary>
  72. /// Width of array
  73. /// </summary>
  74. public int Width
  75. {
  76. get
  77. {
  78. return width;
  79. }
  80. }
  81. /// <summary>
  82. /// Height of array
  83. /// </summary>
  84. public int Height
  85. {
  86. get
  87. {
  88. return height;
  89. }
  90. }
  91. public T this[int X, int Y]
  92. {
  93. get
  94. {
  95. return Elements[Y * width + X];
  96. }
  97. set
  98. {
  99. Elements[Y * width + X] = value;
  100. }
  101. }
  102. public T this[FieldPos Pos]
  103. {
  104. get
  105. {
  106. return this[Pos.X, Pos.Y];
  107. }
  108. set
  109. {
  110. this[Pos.X, Pos.Y] = value;
  111. }
  112. }
  113. public void Assign(List<T> Values, int Width, int Height)
  114. {
  115. if(Values.Count != Width * Height)
  116. throw new Exception("invalid size of value list for field");
  117. this.width = Width;
  118. this.height = Height;
  119. Elements.Clear();
  120. foreach(T val in Values) {
  121. Elements.Add(val);
  122. }
  123. }
  124. /// xOffset/yOffset are the coordinates of the old
  125. /// Field relative to the top/left of the new Field,
  126. /// same as Gimps "Image->Canvas Size"
  127. public void Resize(int xOffset, int yOffset, int newWidth, int newHeight, T fillValue)
  128. {
  129. if (xOffset == 0 && yOffset == 0)
  130. {
  131. Resize(newWidth, newHeight, fillValue);
  132. }
  133. else
  134. {
  135. List<T> newElements = new List<T>();
  136. for(int y = 0; y < newHeight; ++y)
  137. {
  138. for(int x = 0; x < newWidth; ++x)
  139. {
  140. int tX = x - xOffset;
  141. int tY = y - yOffset;
  142. if (0 <= tX && tX < width &&
  143. 0 <= tY && tY < height)
  144. {
  145. newElements.Add(this[tX, tY]);
  146. }
  147. else
  148. {
  149. newElements.Add(fillValue);
  150. }
  151. }
  152. }
  153. Elements = newElements;
  154. width = newWidth;
  155. height = newHeight;
  156. }
  157. }
  158. public void Resize(int NewWidth, int NewHeight, T FillValue)
  159. {
  160. List<T> NewElements = new List<T>();
  161. for(int y = 0; y < NewHeight; ++y) {
  162. for(int x = 0; x < NewWidth; ++x) {
  163. if(x < Width && y < Height)
  164. NewElements.Add(this[x, y]);
  165. else
  166. NewElements.Add(FillValue);
  167. }
  168. }
  169. Elements = NewElements;
  170. width = NewWidth;
  171. height = NewHeight;
  172. }
  173. public List<T> GetContentsArray()
  174. {
  175. List<T> Result = new List<T>(Elements);
  176. return Result;
  177. }
  178. public bool InBounds(FieldPos pos) {
  179. if (pos.X < 0) return false;
  180. if (pos.Y < 0) return false;
  181. if (pos.X >= Width) return false;
  182. if (pos.Y >= Height) return false;
  183. return true;
  184. }
  185. public bool InBounds(int x, int y) {
  186. if (x < 0) return false;
  187. if (y < 0) return false;
  188. if (x >= Width) return false;
  189. if (y >= Height) return false;
  190. return true;
  191. }
  192. public bool EqualContents(object obj) {
  193. if (!(obj is Field<T>)) return false;
  194. Field<T> other = (Field<T>)obj;
  195. if (this.width != other.width) return false;
  196. if (this.height != other.height) return false;
  197. if (this.Elements.Count != other.Elements.Count) return false;
  198. for (int i = 0; i < this.Elements.Count; i++) {
  199. if (!this.Elements[i].Equals(other.Elements[i])) return false;
  200. }
  201. return true;
  202. }
  203. }
  204. }
  205. /* EOF */