Wie kann ich für ein dynamisches Vier gewinnt eine Gewinnabfrage erstellen?

1 Antwort

int anzahlspalten = 40;
int anzahlzeilen = 9;
int[,] BallPosition; // = new int[anzahlspalten, anzahlzeilen];
int GewinnMenge = 4;

Das sind soweit die wichtigen Zeilen, die du für die Siegabfrage benötigst.

BallPosition wird bestimmt die Matrix sein, die den aktuellen Spielstand hält. Ich nehme an, dass der Wert 0 frei bedeutet und 1 bzw. 2 für Spieler 1 bzw. Spieler 2 steht.

Ich habe es zwar nicht getestet, aber für den vertikalen Sieg müsste folgende Funktion das Ergebnis zurückliefern:

public int istSiegerVertikal() {
    for (int i = 0; i < anzahlspalten; i++) {
        int counter = 0;
        int previousState = 0;

        for (int j = 0; j < anzahlzeilen; j++) {
            int currentState = BallPosition[i][j];

            // Feld leer, dann setze Bälle in Folge auf 0
            if (currentState == 0) {
                counter = 0;
            } else {
                // Wenn der aktuelle Zustand gleich dem vorherigen Zustand ist, dann erhöhe den Counter.
                // Ansonsten fange für anderen Spieler bei 1 an
                if (currentState == previousState) {
                    counter++;
                } else {
                    counter = 1;
                }
            }

            // Wenn GewinnMenge erreicht, dann hat der Spieler gewonnen
            if (counter == GewinnMenge) {
                return currentState;
            }

            previousState = currentState;
        }
    }
    // Es wurde kein Sieger gefunden
    return 0;
}

Ich habe es in Java umgesetzt, aber die Sprachen sind sehr ähnlich. Vielleicht musst du sogar nichts verändern.

Für Waagerecht musst du die Schleifen umdrehen, sodass du zuerst durch die Spalten gehst und danach durch die Zeilen.

In der einen Richtung für Diagional sollte dieser Code funktionieren:

public int isSiegerDiagonalTeil1() {
    for (int iStart = 0; iStart < anzahlspalten - GewinnMenge; iStart++) {
        for (int jStart = 0; jStart < anzahlzeilen - GewinnMenge; jStart++) {

            int counter = 0;
            int previousState = 0;

            for (int i = iStart, j = jStart; i < anzahlspalten && j < anzahlzeilen; i++, j++) {
                int currentState = BallPosition[i][j];

                // Feld leer, dann setze Bälle in Folge auf 0
                if (currentState == 0) {
                    counter = 0;
                } else {
                    // Wenn der aktuelle Zustand gleich dem vorherigen Zustand ist, dann erhöhe den Counter.
                    // Ansonsten fange für anderen Spieler bei 1 an
                    if (currentState == previousState) {
                        counter++;
                    } else {
                        counter = 1;
                    }
                }

                // Wenn GewinnMenge erreicht, dann hat der Spieler gewonnen
                if (counter == GewinnMenge) {
                    return currentState;
                }

                previousState = currentState;
            }
        }
    }
    return 0;
}

Es ist definitiv nicht die effizienteste Lösung sein, da er einige Spalten doppelt überprüfen wird. Da kannst du noch eine effizientere Lösung finden.

Dann musst du diese Diagonale Überprüfung auch in der anderen Richtung ausführen. Dazu musst du in der innersten for Schleife i oder j beim maximal möglichen Wert starten lassen und pro Iteration herunterzählen (z.B. i--).

Beim Zusammensetzen führst du alle 4 Varianten zum Gewinnen nacheinander aus. Wenn bereits eine 1 bzw. 2 für ein Sieg zurückgegeben wurde, kannst du direkt abbrechen und den Sieger verkünden. Falls durch eine 0 kein Sieger gefunden wurde, musst du die nächste Variante ausführen. Falls nach der vierten Variante wieder ein 0 kommt, hat einfach noch keiner gewonnen.

Teste den Code vorher auf jeden Fall nochmal!

Ich habe auch Java genutzt, welches sehr ähnlich zu C# ist. Das Konzept solltest du auf jeden Fall verstehen. Copy & Paste könnte mit eventuell leichten Anpassungen möglich sein.

Vor allem für den Diagonalen Weg lassen sich bestimmt noch bessere Algorithmen finden, die effizienter sind.


Neongenji09 
Beitragsersteller
 23.11.2023, 09:27

Danke erstmal, aktuell habe ich eine ähnliche Lösung mit dem Gedankengang, von dem aktuell platzierten Chip in jede Richtung zu gucken, ob nebenan noch andere Chips der selben Farbe liegen, allerdings treten ein paar komische logik fehler auf, hier ein beispiel:
private void CheckHorizontal(int YPosBall)

{

   

  //funktioniert nicht (abfrage nach rechts falsch)

  for (int i = 0; i <= GewinnMenge; i++)

  {

    try

    {

      if (BallPosition[count - i, YPosBall] == Spieler)

      {

        gewinnabfrage++;

      }

      {

        break;

      }

    }

    catch (Exception e)

    {

    }

  }

   

  //funktioniert (abfrage nach links richtig)

  for (int i = 0; i <= GewinnMenge; i++)

  {

    try

    {

      if (BallPosition[count + i, YPosBall] == Spieler)

      {

        gewinnabfrage++;

      }

      else

      {

        break;

      }

    }

    catch (Exception e)

    {

    }

  }
Ich denke, dass dieser lösungsansatz effizienter ist, wobei ich jedoch probleme bei der umsetzung habe

0
Neongenji09 
Beitragsersteller
 23.11.2023, 09:31
@Neongenji09

Korrektur, ich habe einfach nur ein else vergessen... also doch keine probleme, danke bei der hilfe xD

0