Fehler bei Auslagerung von Klasse in andere Codedatei

  • C#

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Fehler bei Auslagerung von Klasse in andere Codedatei

    Hi,
    ich probiere gerade, eine übersichtliche und vielseitige A*-Lib zu machen, jedoch scheitert VS aus irgendeinem bescheuerten Grund anscheinend daran, dass ich meine Klassen von der Hauptcodedatei in eine andere verschieben möchte. Bisher war alles ein richtiger Bandwurm, hier mal der Code (die eigentlichen Funktionen sind noch nicht implementiert, allerdings die Grundstruktur:
    Original-Code

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Drawing;
    7. namespace StefansAStarLibrary
    8. {
    9. public class AStar
    10. {
    11. /// <summary>
    12. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    13. /// </summary>
    14. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    15. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    16. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    17. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    18. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    19. /// <param name="tieBreaker">Der Wert, mit dem der H-Wert multipliziert wird, falls eine entsprechende Heuristische Funktion ausgewählt wurde</param>
    20. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    21. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    22. public bool TrySolve(Map map, Node start, Node end, DirectionCount movableDirections, HeuristicFunction heuristicFunction, double tieBreaker, out List<Point> pathOutput)
    23. {
    24. //Zu Testzwecken, damit keine unnötigen Fehler geworfen werden
    25. pathOutput = null;
    26. return false;
    27. }
    28. //Die anderen Versionen der Methode, alle verweisen direkt oder indirekt auf die Methode TrySolve(Map, Node, Node, DirectionCount, Heuristic, double, out List<Point>)
    29. #region OtherVersions
    30. /*Aufbau
    31. * Gruppen, immer sortiert nach
    32. * -TrySolve (Node)
    33. * -Solve (Node)
    34. * -TrySolve (Point)
    35. * -Solve (Point)
    36. */
    37. /// <summary>
    38. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    39. /// </summary>
    40. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    41. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    42. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    43. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    44. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    45. public bool TrySolve(Map map, Node start, Node end, out List<Point> pathOutput)
    46. {
    47. return TrySolve(map, start, end, DirectionCount.Four, HeuristicFunction.Manhattan, 1, out pathOutput);
    48. }
    49. /// <summary>
    50. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    51. /// </summary>
    52. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    53. /// <param name="start">Der Startpunkt</param>
    54. /// <param name="end">Der Endpunkt</param>
    55. /// <returns>Das Ergebnis der Wegsuche</returns>
    56. public List<Point> Solve(Map map, Node start, Node end)
    57. {
    58. List<Point> Path = new List<Point>();
    59. if (TrySolve(map, start, end, DirectionCount.Four, HeuristicFunction.Manhattan, 1, out Path))
    60. {
    61. return Path;
    62. }
    63. else
    64. {
    65. throw new Exception("Kein Weg gefunden");
    66. }
    67. }
    68. /// <summary>
    69. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    70. /// </summary>
    71. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    72. /// <param name="start">Der Startpunkt</param>
    73. /// <param name="end">Der Endpunkt</param>
    74. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    75. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    76. public bool TrySolve(Map map, Point start, Point end, out List<Point> pathOutput)
    77. {
    78. throw new NotImplementedException();
    79. }
    80. /// <summary>
    81. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    82. /// </summary>
    83. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    84. /// <param name="start">Der Startpunkt</param>
    85. /// <param name="end">Der Endpunkt</param>
    86. /// <returns>Das Ergebnis der Wegsuche</returns>
    87. public List<Point> Solve(Map map, Point start, Point end)
    88. {
    89. throw new NotImplementedException();
    90. }
    91. /// <summary>
    92. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    93. /// </summary>
    94. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    95. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    96. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    97. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    98. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    99. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    100. public bool TrySolve(Map map, Node start, Node end, DirectionCount movableDirections, out List<Point> pathOutput)
    101. {
    102. return TrySolve(map, start, end, movableDirections, HeuristicFunction.Manhattan, 1, out pathOutput);
    103. }
    104. /// <summary>
    105. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    106. /// </summary>
    107. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    108. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    109. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    110. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    111. /// <returns>Das Ergebnis der Wegsuche</returns>
    112. public List<Point> Solve(Map map, Node start, Node end, DirectionCount movableDirections)
    113. {
    114. List<Point> Path = new List<Point>();
    115. if (TrySolve(map, start, end, movableDirections, HeuristicFunction.Manhattan, 1, out Path))
    116. {
    117. return Path;
    118. }
    119. else
    120. {
    121. throw new Exception("Kein Weg gefunden");
    122. }
    123. }
    124. /// <summary>
    125. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    126. /// </summary>
    127. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    128. /// <param name="start">Der Startpunkt</param>
    129. /// <param name="end">Der Endpunkt</param>
    130. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    131. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    132. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    133. public bool TrySolve(Map map, Point start, Point end, DirectionCount movableDirections, out List<Point> pathOutput)
    134. {
    135. throw new NotImplementedException();
    136. }
    137. /// <summary>
    138. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    139. /// </summary>
    140. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    141. /// <param name="start">Der Startpunkt</param>
    142. /// <param name="end">Der Endpunkt</param>
    143. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    144. /// <returns>Das Ergebnis der Wegsuche</returns>
    145. public List<Point> Solve(Map map, Point start, Point end, DirectionCount movableDirections)
    146. {
    147. throw new NotImplementedException();
    148. }
    149. /// <summary>
    150. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    151. /// </summary>
    152. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    153. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    154. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    155. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    156. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    157. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    158. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    159. public bool TrySolve(Map map, Node start, Node end, DirectionCount movableDirections, HeuristicFunction heuristicFunction, out List<Point> pathOutput)
    160. {
    161. return TrySolve(map, start, end, movableDirections, heuristicFunction, 1, out pathOutput);
    162. }
    163. /// <summary>
    164. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    165. /// </summary>
    166. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    167. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    168. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    169. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    170. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    171. /// <returns>Das Ergebnis der Wegsuche</returns>
    172. public List<Point> Solve(Map map, Node start, Node end, DirectionCount movableDirections, HeuristicFunction heuristicFunction)
    173. {
    174. List<Point> Path = new List<Point>();
    175. if (TrySolve(map, start, end, movableDirections, heuristicFunction, 1, out Path))
    176. {
    177. return Path;
    178. }
    179. else
    180. {
    181. throw new Exception("Kein Weg gefunden");
    182. }
    183. }
    184. /// <summary>
    185. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    186. /// </summary>
    187. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    188. /// <param name="start">Der Startpunkt</param>
    189. /// <param name="end">Der Endpunkt</param>
    190. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    191. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    192. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    193. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    194. public bool TrySolve(Map map, Point start, Point end, DirectionCount movableDirections, HeuristicFunction heuristicFunction, out List<Point> pathOutput)
    195. {
    196. throw new NotImplementedException();
    197. }
    198. /// <summary>
    199. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    200. /// </summary>
    201. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    202. /// <param name="start">Der Startpunkt</param>
    203. /// <param name="end">Der Endpunkt</param>
    204. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    205. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    206. /// <returns>Das Ergebnis der Wegsuche</returns>
    207. public List<Point> Solve(Map map, Point start, Point end, DirectionCount movableDirections, HeuristicFunction heuristicFunction)
    208. {
    209. throw new NotImplementedException();
    210. }
    211. #endregion
    212. }
    213. /// <summary>
    214. /// Gibt an, wie viele Bewegungsrichtungen erwägt werden
    215. /// </summary>
    216. public enum DirectionCount
    217. {
    218. /// <summary>
    219. /// Stellt 4 Bewegungsrichtungen zur Verfügung
    220. /// </summary>
    221. Four,
    222. /// <summary>
    223. /// Stellt 8 Bewegungsrichtungen zur Verfügung
    224. /// </summary>
    225. Eight
    226. }
    227. /// <summary>
    228. /// Stellt eine Heuristik dar
    229. /// </summary>
    230. public class HeuristicFunction
    231. {
    232. public Func<Point, Point, double> Function { get; private set; }
    233. public bool TieBreak { get; private set; }
    234. /// <summary>
    235. /// Erstellt eine neue HeuristicFunction-Klasse
    236. /// </summary>
    237. /// <param name="functionSource">Die Heuristische Funktion, Form: '(start, end) => H'</param>
    238. /// <param name="tieBreak">Gibt an, ob TieBreaking aktiviert werden soll</param>
    239. public HeuristicFunction(Func<Point, Point, double> function, bool tieBreak)
    240. {
    241. this.Function = function;
    242. this.TieBreak = tieBreak;
    243. }
    244. /// <summary>
    245. /// Erstellt eine neue HeuristicFunction-Klasse aus einer Vorlage
    246. /// </summary>
    247. /// <param name="functionSource">Die Vorlage</param>
    248. /// <param name="tieBreak">Gibt an, ob TieBreaking aktiviert werden soll</param>
    249. public HeuristicFunction(HeuristicFunction functionSource, bool tieBreak)
    250. {
    251. this.Function = functionSource.Function;
    252. this.TieBreak = tieBreak;
    253. }
    254. /// <summary>
    255. /// Die Manhattan-Heuristik
    256. /// </summary>
    257. public static const HeuristicFunction Manhattan =
    258. new HeuristicFunction((start, end) => Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y), false);
    259. /// <summary>
    260. /// Die Diagonal-Heuristik
    261. /// </summary>
    262. public static const HeuristicFunction Diagonal =
    263. new HeuristicFunction((start, end) => Math.Max(Math.Abs(start.X - end.X), Math.Abs(start.Y - end.Y)), false);
    264. /// <summary>
    265. /// Die Euclidean-Heuristik
    266. /// </summary>
    267. public static const HeuristicFunction Euclidean =
    268. new HeuristicFunction((start, end) => Math.Sqrt(Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2)), false);
    269. /// <summary>
    270. /// Die Euclidean-Sqared-Heuristik
    271. /// </summary>
    272. public static const HeuristicFunction EuclideanSqared =
    273. new HeuristicFunction((start, end) => Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2), false);
    274. }
    275. }


    Das habe ich jetzt in 3 Codefiles auseinandergenommen:
    AStar.cs

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Drawing;
    7. namespace StefansAStarLibrary
    8. {
    9. public class AStar
    10. {
    11. /// <summary>
    12. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    13. /// </summary>
    14. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    15. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    16. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    17. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    18. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    19. /// <param name="tieBreaker">Der Wert, mit dem der H-Wert multipliziert wird, falls eine entsprechende Heuristische Funktion ausgewählt wurde</param>
    20. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    21. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    22. public bool TrySolve(Map map, Node start, Node end, DirectionCount movableDirections, HeuristicFunction heuristicFunction, double tieBreaker, out List<Point> pathOutput)
    23. {
    24. //Zu Testzwecken, damit keine unnötigen Fehler geworfen werden
    25. pathOutput = null;
    26. return false;
    27. }
    28. //Die anderen Versionen der Methode, alle verweisen direkt oder indirekt auf die Methode TrySolve(Map, Node, Node, DirectionCount, Heuristic, double, out List<Point>)
    29. #region OtherVersions
    30. /*Aufbau
    31. * Gruppen, immer sortiert nach
    32. * -TrySolve (Node)
    33. * -Solve (Node)
    34. * -TrySolve (Point)
    35. * -Solve (Point)
    36. */
    37. /// <summary>
    38. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    39. /// </summary>
    40. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    41. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    42. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    43. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    44. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    45. public bool TrySolve(Map map, Node start, Node end, out List<Point> pathOutput)
    46. {
    47. return TrySolve(map, start, end, DirectionCount.Four, HeuristicFunction.Manhattan, 1, out pathOutput);
    48. }
    49. /// <summary>
    50. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    51. /// </summary>
    52. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    53. /// <param name="start">Der Startpunkt</param>
    54. /// <param name="end">Der Endpunkt</param>
    55. /// <returns>Das Ergebnis der Wegsuche</returns>
    56. public List<Point> Solve(Map map, Node start, Node end)
    57. {
    58. List<Point> Path = new List<Point>();
    59. if (TrySolve(map, start, end, DirectionCount.Four, HeuristicFunction.Manhattan, 1, out Path))
    60. {
    61. return Path;
    62. }
    63. else
    64. {
    65. throw new Exception("Kein Weg gefunden");
    66. }
    67. }
    68. /// <summary>
    69. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    70. /// </summary>
    71. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    72. /// <param name="start">Der Startpunkt</param>
    73. /// <param name="end">Der Endpunkt</param>
    74. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    75. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    76. public bool TrySolve(Map map, Point start, Point end, out List<Point> pathOutput)
    77. {
    78. throw new NotImplementedException();
    79. }
    80. /// <summary>
    81. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    82. /// </summary>
    83. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    84. /// <param name="start">Der Startpunkt</param>
    85. /// <param name="end">Der Endpunkt</param>
    86. /// <returns>Das Ergebnis der Wegsuche</returns>
    87. public List<Point> Solve(Map map, Point start, Point end)
    88. {
    89. throw new NotImplementedException();
    90. }
    91. /// <summary>
    92. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    93. /// </summary>
    94. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    95. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    96. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    97. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    98. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    99. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    100. public bool TrySolve(Map map, Node start, Node end, DirectionCount movableDirections, out List<Point> pathOutput)
    101. {
    102. return TrySolve(map, start, end, movableDirections, HeuristicFunction.Manhattan, 1, out pathOutput);
    103. }
    104. /// <summary>
    105. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    106. /// </summary>
    107. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    108. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    109. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    110. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    111. /// <returns>Das Ergebnis der Wegsuche</returns>
    112. public List<Point> Solve(Map map, Node start, Node end, DirectionCount movableDirections)
    113. {
    114. List<Point> Path = new List<Point>();
    115. if (TrySolve(map, start, end, movableDirections, HeuristicFunction.Manhattan, 1, out Path))
    116. {
    117. return Path;
    118. }
    119. else
    120. {
    121. throw new Exception("Kein Weg gefunden");
    122. }
    123. }
    124. /// <summary>
    125. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    126. /// </summary>
    127. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    128. /// <param name="start">Der Startpunkt</param>
    129. /// <param name="end">Der Endpunkt</param>
    130. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    131. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    132. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    133. public bool TrySolve(Map map, Point start, Point end, DirectionCount movableDirections, out List<Point> pathOutput)
    134. {
    135. throw new NotImplementedException();
    136. }
    137. /// <summary>
    138. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    139. /// </summary>
    140. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    141. /// <param name="start">Der Startpunkt</param>
    142. /// <param name="end">Der Endpunkt</param>
    143. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    144. /// <returns>Das Ergebnis der Wegsuche</returns>
    145. public List<Point> Solve(Map map, Point start, Point end, DirectionCount movableDirections)
    146. {
    147. throw new NotImplementedException();
    148. }
    149. /// <summary>
    150. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    151. /// </summary>
    152. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    153. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    154. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    155. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    156. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    157. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    158. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    159. public bool TrySolve(Map map, Node start, Node end, DirectionCount movableDirections, HeuristicFunction heuristicFunction, out List<Point> pathOutput)
    160. {
    161. return TrySolve(map, start, end, movableDirections, heuristicFunction, 1, out pathOutput);
    162. }
    163. /// <summary>
    164. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    165. /// </summary>
    166. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    167. /// <param name="start">Der Startpunkt (muss sich in der Map befinden)</param>
    168. /// <param name="end">Der Endpunkt (muss sich in der Map befinden)</param>
    169. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    170. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    171. /// <returns>Das Ergebnis der Wegsuche</returns>
    172. public List<Point> Solve(Map map, Node start, Node end, DirectionCount movableDirections, HeuristicFunction heuristicFunction)
    173. {
    174. List<Point> Path = new List<Point>();
    175. if (TrySolve(map, start, end, movableDirections, heuristicFunction, 1, out Path))
    176. {
    177. return Path;
    178. }
    179. else
    180. {
    181. throw new Exception("Kein Weg gefunden");
    182. }
    183. }
    184. /// <summary>
    185. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    186. /// </summary>
    187. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    188. /// <param name="start">Der Startpunkt</param>
    189. /// <param name="end">Der Endpunkt</param>
    190. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    191. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    192. /// <param name="pathOutput">Hier wird das Ergebnis ausgegeben, falls der Lösungsversuch erfolgreich ist</param>
    193. /// <returns>Ob der Lösungsversuch geklappt hat</returns>
    194. public bool TrySolve(Map map, Point start, Point end, DirectionCount movableDirections, HeuristicFunction heuristicFunction, out List<Point> pathOutput)
    195. {
    196. throw new NotImplementedException();
    197. }
    198. /// <summary>
    199. /// Sucht mithilfe des A*-Algorhytmus einen möglichen Weg vom Start zum Ziel
    200. /// </summary>
    201. /// <param name="map">Die Map, in der der Weg gesucht werden soll</param>
    202. /// <param name="start">Der Startpunkt</param>
    203. /// <param name="end">Der Endpunkt</param>
    204. /// <param name="movableDirections">Die Anzahl der Richtungen, in welche sich der Path bewegen darf</param>
    205. /// <param name="heuristicFunction">Die Heuristik, die eingesetzt werden soll</param>
    206. /// <returns>Das Ergebnis der Wegsuche</returns>
    207. public List<Point> Solve(Map map, Point start, Point end, DirectionCount movableDirections, HeuristicFunction heuristicFunction)
    208. {
    209. throw new NotImplementedException();
    210. }
    211. #endregion
    212. }
    213. }

    HeuristicFunction.cs

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Drawing;
    7. namespace StefansAStarLibrary
    8. {
    9. /// <summary>
    10. /// Stellt eine Heuristik dar
    11. /// </summary>
    12. public class HeuristicFunction
    13. {
    14. public Func<Point, Point, double> Function { get; private set; }
    15. public bool TieBreak { get; private set; }
    16. /// <summary>
    17. /// Erstellt eine neue HeuristicFunction-Klasse
    18. /// </summary>
    19. /// <param name="functionSource">Die Heuristische Funktion, Form: '(start, end) => H'</param>
    20. /// <param name="tieBreak">Gibt an, ob TieBreaking aktiviert werden soll</param>
    21. public HeuristicFunction(Func<Point, Point, double> function, bool tieBreak)
    22. {
    23. this.Function = function;
    24. this.TieBreak = tieBreak;
    25. }
    26. /// <summary>
    27. /// Erstellt eine neue HeuristicFunction-Klasse aus einer Vorlage
    28. /// </summary>
    29. /// <param name="functionSource">Die Vorlage</param>
    30. /// <param name="tieBreak">Gibt an, ob TieBreaking aktiviert werden soll</param>
    31. public HeuristicFunction(HeuristicFunction functionSource, bool tieBreak)
    32. {
    33. this.Function = functionSource.Function;
    34. this.TieBreak = tieBreak;
    35. }
    36. /// <summary>
    37. /// Die Manhattan-Heuristik
    38. /// </summary>
    39. public static const HeuristicFunction Manhattan =
    40. new HeuristicFunction((start, end) => Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y), false);
    41. /// <summary>
    42. /// Die Diagonal-Heuristik
    43. /// </summary>
    44. public static const HeuristicFunction Diagonal =
    45. new HeuristicFunction((start, end) => Math.Max(Math.Abs(start.X - end.X), Math.Abs(start.Y - end.Y)), false);
    46. /// <summary>
    47. /// Die Euclidean-Heuristik
    48. /// </summary>
    49. public static const HeuristicFunction Euclidean =
    50. new HeuristicFunction((start, end) => Math.Sqrt(Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2)), false);
    51. /// <summary>
    52. /// Die Euclidean-Sqared-Heuristik
    53. /// </summary>
    54. public static const HeuristicFunction EuclideanSqared =
    55. new HeuristicFunction((start, end) => Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2), false);
    56. }
    57. }

    DirectionCount.cs

    C#-Quellcode

    1. using System;
    2. namespace StefansAStarLibrary
    3. {
    4. /// <summary>
    5. /// Gibt an, wie viele Bewegungsrichtungen erwägt werden
    6. /// </summary>
    7. public enum DirectionCount
    8. {
    9. /// <summary>
    10. /// Stellt 4 Bewegungsrichtungen zur Verfügung
    11. /// </summary>
    12. Four,
    13. /// <summary>
    14. /// Stellt 8 Bewegungsrichtungen zur Verfügung
    15. /// </summary>
    16. Eight
    17. }
    18. }


    Jetzt kriege ich von Visual Studio netterweise dutzende Fehler entgegengeworfen, hier mal alle verschiedenen Fehlertypen:
    Fehler

    Nummer 1: Tritt bei jeder Solve-/TrySolve-Methode auf, die Signatur der bemängelten Funktion variiert natürlich, manchmal wird auch die Map bemängelt:

    Quellcode

    1. Variante 1:
    2. Inkonsistenter Zugriff: Parametertyp 'StefansAStarLibrary.Node' ist weniger zugreifbar als Methode 'StefansAStarLibrary.AStar.TrySolve(StefansAStarLibrary.Map, StefansAStarLibrary.Node, StefansAStarLibrary.Node, StefansAStarLibrary.DirectionCount, StefansAStarLibrary.HeuristicFunction, double, out System.Collections.Generic.List<System.Drawing.Point>)'
    3. Variante 2:
    4. Inkonsistenter Zugriff: Parametertyp 'StefansAStarLibrary.Map' ist weniger zugreifbar als Methode 'StefansAStarLibrary.AStar.TrySolve(StefansAStarLibrary.Map, StefansAStarLibrary.Node, StefansAStarLibrary.Node, StefansAStarLibrary.DirectionCount, StefansAStarLibrary.HeuristicFunction, double, out System.Collections.Generic.List<System.Drawing.Point>)'

    Nummer 2: Tritt bei jeder Konstante in der Klasse HeuristicFunction auf:
    Hier variieren natürlich wieder die Namen:

    Quellcode

    1. Die Konstante 'StefansAStarLibrary.HeuristicFunction.Diagonal' kann nicht als statisch markiert werden.

    Nummer 3-5: Hier wird die Lambda-Funktion bemängelt

    Quellcode

    1. Der Name 'start' ist im aktuellen Kontext nicht vorhanden.

    Quellcode

    1. Der Name 'end' ist im aktuellen Kontext nicht vorhanden.

    Quellcode

    1. 'lambda-Ausdruck' kann nicht in den Typ 'StefansAStarLibrary.HeuristicFunction' konvertiert werden, da dies kein Delegattyp ist.

    Quellcode

    1. Der Ausdruck kann keine anonymen Methoden oder lambda-Ausdrücke enthalten.


    Und als ob das noch nicht genug wäre, ist es mir nichtmal möglich, mit dem Rückgängigmachen der Änderungen die Fehler wegzubekommen :cursing:.
    Kann mir da vielleicht jemand helfen?
    Guck dir mal die Definition von deiner Node- und der Map-Klasse an. Denn Fehler 1 besagt ja, dass die wohl auf private oder internal oder sowas stehen.
    Ich hab den Fehler gefunden :).
    Falls es noch jemanden interessiert, die Lösung war, aus den Konstanten Properties zu machen, dann wirft es keine Fehler mehr.
    Danke, das war der eine Fehler :), ich hatte das public vergessen.
    Zusammengeführt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „FlashTek“ ()

    Aus Konstanten Properties wegen den Fehlern oben wird wohl kaum die richtige Lösung sein. Vielmehr Konstanten als public deklarieren?


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Die Konstanten verhalten sich dann aber nicht so "static", oder? Ich hatte eigenlch vor, soetwas wie bei der Color-Struktur zu erreichen, dass ich dann vorgefertigte und eigene Typen in einer Klasse bekomme. Im Gründe gekommen verhalten sich die Dinger ja eh gleich.
    Also suchst du eher was wie Enumerationen (in Bezug auf deine Color Aussage)? msdn.microsoft.com/de-de/library/6e3t9w21%28v=vs.90%29.aspx
    Nebenbei, new HeuristicFunction((start, end) => Math.Max(Math.Abs(start.X - end.X), Math.Abs(start.Y - end.Y)), false); sieht mir nicht wirklich Konstant aus ?(
    ich tät sehr empfehlen, dieses ganze schwachsinnige Kommentar-Gelaber erstmal zu entfernen.

    Und dann Kommentare hinmachen, die wirdklich erklären, was man aussm Code nicht direkt versteht.
    Etwa: Was soll die Klasse HeuristicFunctions?

    sowas wäre glaub interessanter, als zu erfahren, dass Euclean eine Eucledean-Heuristik darstellt (letzteres ist nämlich eine Tautologie, und somit keine Erklärung, sondern eine Verarschung)

    Von den ganzen 287 Zeilen blieben vlt. 50 übrig, und das Bandwurm-Problem wäre gelöst.
    Dann kannman noch die ganzen Überladungen entfernen, und sich auf erstmal eine Methode konzentrieren, die auch mal was macht, weil dassis grad was mir fehlt in dem Snippet: Dass iwo mal eine Methode mal wirklich was macht.
    Zur Funktion kannman auch deshalb nix sagn, weil die Map-Klasse uns unbekannt ist.
    @slice
    Stimmt, vielleicht lag es daran. Ich dachte einfach Konstant = nicht veränderbare Variable. Um nochmal auf die Enumeration zurückzukommen, bei der Color-Struktur ist die Property-basiert.
    @ErfinderDesRades
    Was sollte ich denn sonst in die Beschreibungen reinmachen? Jeder, der sich mit dem Thema schon auseinandergesetzt hat, sollte wissen, was das ist.
    Die Map- und Nodeklasse sind bisher übrigens leer, genauso wie die "Original"-Funktion, in der alles zusammenläuft. Das liegt daran, dass ich erstmal die Grundstruktur schaffen will (alle zusätzlichen Methoden Solve/TrySolve verweisen immer auf die nächstumfangreichere, sodass ich den Code der eigentlichen Funktion nur noch einmal schreiben muss und alle Methoden werden damit versorgt.
    Wenn alles eh klar ist, kannste auf Kommentation auch komplett verzichten. Bzw, es ist erforderlich, dann auf Kommentation zu verzichten, denn was selbsterklärender Code selbst erklärt, kann durch Kommentation nur verwässert oder gar verfälscht werden.
    Aber wenn dir bereits klar ist, wie die Heuristics-Klasse zu verwenden ist, und da du das auch bei deinen Lesern vorraussetzst - dann kein Kommentar.
    Ich persönlich hätte eine Erklärung wie "Die Distanz einer Zelle zum Ziel kann auf verschiedene Weisen berechnet werden (etwa Luftlinie, Anzahl der Schritte, weitere) Die hier als Delegat niedergelegten Bewertungs-Funktionen werden dem Lösungs-Algorithmus übergeben und führen zu jeweils unterschiedlichen Ergebniswegen."

    Das wäre eine Erklärung, die man imo nicht so ohne weiteres dem Code ablesen kann, und solch Kommentar hätte dann eine Berechtigung. Bzw. er ist erforderlich (im Gegensatz zu allem anneren, was da derzeit hingeschrieben ist).
    Also wäre dieser Kommentar der einzige im Code, dann wäre dein Code vielfach leserlicher: kürzer, selbsterklärend, und der einzige Kommentar wäre wesentlich, und fände dann auch die nötige Beachtung.


    Also gut, du hast nun die grob Struktur. Dann solltest du wohl jetzt die Map ausprogrammieren - was hast du da bisher?

    ErfinderDesRades schrieb:

    Ich persönlich hätte eine Erklärung wie "Die Distanz einer Zelle zum Ziel kann auf verschiedene Weisen berechnet werden (etwa Luftlinie, Anzahl der Schritte, weitere) Die hier als Delegat niedergelegten Bewertungs-Funktionen werden dem Lösungs-Algorithmus übergeben und führen zu jeweils unterschiedlichen Ergebniswegen."

    Das ist mir klar, dass das besser verständlich ist, jedoch würde das doch eher in die Dokumentation gehören, oder? Ich werde jedenfalls noch mal überlegen, wie ich das mit den Kommentaren besser lösen könnte.

    ErfinderDesRades schrieb:

    Also gut, du hast nun die grob Struktur. Dann solltest du wohl jetzt die Map ausprogrammieren - was hast du da bisher?

    Bisher gar nichts, jedoch habe ich ein grobes Modell schon im Kopf:
    Properties:
    Size: Gibt die Größe der Map an
    Nodes/Default Property: Speichert die einzelnen Nodes

    Methoden:
    GetNode(x, y): Gibt eine Node an einem bestimmten Platz aus
    GetSurroundingNodes(x, y): Gibt die eine Node umgebenden Nodes aus
    GetRow(index): Gibt eine spezifische Reihe aus
    GetColumn(index): Gibt eine spezifische Spalte aus

    SetNode(x, y, node): Setzt den Wert einer Node
    SetRow(index, nodes[]): Setzt eine spezifische Reihe
    SetColumn(index, nodes[]): Setzt eine spezifische Spalte

    AddRow(index): Fügt eine neue Zeile ein
    RemoveRow(index): Löscht eine Zeile
    AddColumn(index): Fügt eine neue Spalte ein
    RemoveColumn(index): Löscht eine Spalte

    Save(path): Speichert die Map
    Load(path): Lädt eine Map

    Technik:

    Als Basis dient ein Jagged Array, damit man auch einzelne Zeilen und Spalten direkt ansprechen kann.
    ...ist mir klar, dass das besser verständlich ist...
    besser verständlcih als was?
    bisher enthält deine Kommentation doch keinerlei Erklärungen - das sind doch alles nur Tautologien.

    Wo das hingehört, ist mir egal. Du hast beim Coden jede Freiheit der Kommetation.
    Ich würde das als Header in die Datei setzen, wo die Heuristiken drinne sind.
    vielleicht auch als Summary der Heuristics-Klasse, vlt. verkürzt: "Enthält Delegaten, die verschiedene Strategien zur Distanz-Berechnung zweier Zellen anwenden. Einer davon wird dem A*-Algorithmus mitgegeben und beeinflusst, was als kürzester Weg betrachtetet wird."


    Jut - haste ein Map-Konzept - im wesentliche ein JaggedArray von Nodes - fehlt noch das Node-Konzept. Als Node täte m.E. ein einfacher Enum reichen, der verschiedene Status' der Zelle aussagt, obs ein Hindernis ist oder frei, ob schon besucht und dergleichen.
    Ich würde auch nicht von Nodes reden, sondern von Zellen. Nodes sind Objekte der Graphen-Theorie, und werden explizit miteinander verknüpft.
    Zellen sind einfach Elemente in einer Matrix, und ihre Nachbarn ergeben sich direkt aus der Zell-Position. Also aus etwas, was streng genommen in der Zelle garnet enthalten ist.
    Der Algo würde dann also nicht mit Nodes oder Zellen arbeiten, sondern mit Positionen, mit Points.



    Edit:
    Was bedeutet eiglich die TieBreak-Property der Heuristics-Klasse? (Siehste, solch Fragen tauchen erst auf, wennich mir das mal rauskopiere, und die Laberkommentare rausschmeisse)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    dann kann das weg, und du gibst die Konstante halt immer an. Gibst du 1 an, wird halt mit 1 multipliziert.

    Und wenn das weg kann, kannste die Salami wesentlich vereinfachen:

    C#-Quellcode

    1. /// <summary>
    2. /// Enthält Delegaten, die verschiedene Strategien zur Distanz-Berechnung zweier Zellen anwenden. Einer davon wird dem A*-Algorithmus mitgegeben und beeinflusst, was als kürzester Weg betrachtetet wird.
    3. /// </summary>
    4. public static class HeuristicFunctions {
    5. /// <summary> berechnet Anzahl der Schritte unter Vorraussetzung von 4 Nachbarzellen </summary>
    6. public static Func<Point, Point, double> Manhattan =(start, end) => Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y);
    7. /// <summary> berechnet Anzahl der Schritte unter Vorraussetzung auch diagonaler Nachbarn </summary>
    8. public static Func<Point, Point, double> Diagonal = (start, end) => Math.Max(Math.Abs(start.X - end.X), Math.Abs(start.Y - end.Y));
    9. /// <summary> berechnet Luftlinie </summary>
    10. public static Func<Point, Point, double> Euclidean = (start, end) => Math.Sqrt(Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2));
    11. /// <summary> berechnet quadrierte Luftlinie (etwas schneller als richtige Luftlinie zu berechnen)</summary>
    12. public static Func<Point, Point, double> EuclideanSqared = (start, end) => Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2);
    13. }
    Ok, ich habe das jetzt so eingearbeitet:

    C#-Quellcode

    1. /// <summary>
    2. /// Stellt eine Strategie zur Distanzberechnung zwischen zwei Zellen dar.
    3. /// Sie beeinflusst, welcher Weg als der kürzeste beachtet wird.
    4. /// </summary>
    5. public class HeuristicFunction
    6. {
    7. public Func<Point, Point, double> Function { get; set; }
    8. /// <summary>
    9. /// Erstellt eine neue HeuristicFunction-Klasse
    10. /// </summary>
    11. /// <param name="functionSource">Die Heuristische Funktion, Form: '(start, end) => H'</param>
    12. public HeuristicFunction(Func<Point, Point, double> function)
    13. {
    14. this.Function = function;
    15. }
    16. /// <summary>
    17. /// Berechnet die Anzahl der Schritte unter Vorraussetzung von 4 Nachbarzellen
    18. /// </summary>
    19. public static HeuristicFunction Manhattan = new HeuristicFunction((start, end) => Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y));
    20. /// <summary>
    21. /// Berechnet die Anzahl der Schritte unter Vorraussetzung auch diagonaler Nachbarzellen
    22. /// </summary>
    23. public static HeuristicFunction Diagonal = new HeuristicFunction((start, end) => Math.Max(Math.Abs(start.X - end.X), Math.Abs(start.Y - end.Y)));
    24. /// <summary>
    25. /// Berechnet die Entfernung per Luftlinie
    26. /// </summary>
    27. public static HeuristicFunction Euclidean = new HeuristicFunction((start, end) => Math.Sqrt(Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2)));
    28. /// <summary>
    29. /// Berechnet die quadrierte Entfernung per Luftlinie (etwas schneller als richtige Luftlinie zu berechnen)
    30. /// </summary>
    31. public static HeuristicFunction EuclideanSqared = new HeuristicFunction((start, end) => Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2));
    32. }

    Denkst du, das passt?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nafets3646“ ()

    wie gesagt: TieBreak kann weg, und die ganze Klasse kann aufgelöst werden, und als Statische Klasse designed - also nurnoch ein Sammelsurium von
    Func(Point, Point, Double)-Delegaten.
    Es ist nicht mehr als ein Sammelsurium solcher Delegaten, und daher solls auch nicht so tun als obs ein Objekt wäre, was man instanzieren müsste.

    Von meinen Vorschlägen scheinst du nur die Kommentation übernommen zu haben - nicht die Vereinfachung des Codes.

    Die eigentlich sinnlose HeuristicFunction-klasse erschwert enorm das Verständnis, weil sinnlosigkeiten sind am schwierigsten zu verstehen von allem (nämlich garnet), und dass etwas einfach sinnlos ist, darauf kommt man meist als letztes.
    Das TieBreak hatte ich entfernt, ich hatte nur zuerst den falschen Code kopiert ;). Und du findest wirklich nicht, dass ich die Klasse behalten soll? Ich persönlich finde die ja eher sogar übersichtlicher, da man nicht einfach irgendeine Function vorgesetzt bekommt, welche man implementieren muss bzw. erstmal die vorgefertigten Varianten finden muss.
    Nein, die Klasse ist von hinten durch die Brust ins Auge.
    Stell dir die Benutzung vor:

    C#-Quellcode

    1. var astar = new Astar();
    2. astar.Heuristic = new Heuristic(Heuristic.Diagonal);
    Wassn Crap!


    C#-Quellcode

    1. astar.Heuristic = Heuristic.Diagonal;
    Einfach anweisen, was zu tun ist, ohne ein sinnloses Heuristic-Objekt drumrum.

    Und derselbe Quatsch dann nochmal im Algo, wo die Benutzung eines Heuristic-Objects allein darin bestünde, dieFunction-Property da rauszuholen und zu nutzen.
    Also da kann man die Function auch direkt übergeben, dann muss der Algo sie nicht erst aus diesem Quatsch-Objekt herausholen.
    Die Benutzung funktioniert ja auch direkt, man muss nicht den Umweg über new gehen :P. So wie ich das konzipiert habe, ist Heuristic im Grunde genommen eine Klasse und gleichzeitig eine Enumeration, da muss man auch nichts mehr instanzieren -> meine Möglichkeit sieht auch wie die, welche du in deinem zweiten Beispiel gezeigt hast, aus.