Als ich mir Abalone als Spiel aussuchte dachte ich mir "Hmm die Regeln sind ja recht einfach. Das sollte nicht sonderlich schwer sein umzusetzen". Als ich mit der Implementierung der Spielmechanik begonnen hatte, hat sich meine Annahme als Irrtum herausgestellt. Es fängt mit so einfachen Dingen an wie "Liegen die gewählten Kugeln in einer Reihe?" und hört bei "Wo liegen die Kugeln nach dem Verschieben?" auf.
Als Beispiel erläutere ich, wie ich erkenne, ob Kugeln in einer Reihe liegen. Generell benötige ich diese Funktionalität beim Selektieren der einzelnen Kugeln und beim Verschieben einer Reihe.
Ich betrachte in der Methode immer eine Menge von Kugeln. Da ich mein Spielfeld als zweidimensionales Array darstelle haben meine Kugeln eine X und eine Y Koordinate.
Als erste Variante habe ich einfach versucht über die Kugeln zu iterieren um zu schauen, ob die nachfolgende Kugel in Reihe zu der vorherigen Kugel liegt. Der Versuch schlug schon nach erstem Probieren Fehl. Erstens weiß ich nicht in welcher Richtung die Kugeln liegen und zweitens können die Kugeln völlig unsortiert sein. Es könnte also passieren, dass ich drei Kugeln in Reihe habe die durchnummeriert sind aber in der Iteration die Reihenfolge 1:3:2 haben. Somit würde diese Variante spätestens bei der zweiten Kugel in der Liste davon ausgehen, dass es keine Reihe ist.
Ich benötige also eine Möglichkeit die wahrscheinliche Richtung meiner Kugeln zu bestimmen, so dass ich später nur noch die Position in die Richtung verschieben und schauen muss, ob dort eine Kugel gibt.
Hier also der Algorithmus:
- Bilde die Differenz zwischen der Maximalen und der Minimalen X und Y Koordinate die die zu Prüfenden Kugeln haben.
- Ist die Differenz größer 0 so muss später bei der Iteration die X / Y Koordinate hochgezählt werden.
- Iteriere so über das Spielfeld, dass bei der Kugel mit geringstem X, Y Wert begonnen wird
- Suche in der Liste nach Kugeln die diese Koordinate haben
- Inkrementiere die X / Y Koordinate je nach Ergebnis in Schritt 2.
- Wiederhole den Vorgang bis entweder eine Kugel nicht gefunden wird (bedeutet dass die Kugeln nicht in Reihe liegen) oder alle Kugeln eine der erwarteten Koordinaten haben
public bool IsInRow(List<Ball> balls) {Irgend wie müsste ich das Ganze nochmal Refactorn. Die for-Schleife ist mir noch eine Nummer zu kryptisch. Als ich nach etwa einem 3/4 Jahr nochmal draufgeschaut habe dachte ich mir "Huch was hast du denn da verbrochen" :-)
if (balls.Count <= 1) {
return true;
}
//finde kugel mit kleinstem x und kleinstem y
int minX = balls.Min(ball => ball.PosX);
int minY = balls.Min(ball => ball.PosY);
int dx = balls.Max(ball => ball.PosX) - minX;
int dy = balls.Max(ball => ball.PosY) - minY;
int xinc = Convert.ToInt32(dx > 0);
int yinc = Convert.ToInt32(dy > 0);
for (int i = 0, x = 0, y = 0; (x <= dx && y <= dy) ||
i < balls.Count; x += xinc, y += yinc, i++) {
if (balls.Find(ball => ball.PosX == (x + minX) &&
ball.PosY == (y + minY)) == null) {
return false;
}
}
return true;
}
PS: Hat jemand eine Ahnung, wie man hier Quelltexte vernünftig darstellen kann?
Keine Kommentare:
Kommentar veröffentlichen