TIA 4 Gewinnt Auswertung

bkizilkaya

Level-1
Beiträge
93
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Tag

Unten seht ihr meinen fast fertigen Code. Ich muss nur noch ermitteln wer gewonnen hat. Leider weiss ich nicht wie.

Ich habe einfach die idee mit einer For schleife zu machen. D.h. immer wenn eine Zelle gefüllt ist zählt die variable hoch bis 4,
aber sie müssen ja 4 nacheinander sein und dioagonale auch.

Könnt ihr mir helfen?


Anhang anzeigen code.doc
 
Zuletzt bearbeitet:
Da gibts es sicher viele Möglichkeiten. Am PC würde man das wohl mit Rekursion lösen, aber das hat die SPS ja nicht so gerne ;-)

Du startest an Punkt (0|0) unterste Reihe ganz links und gehst die 5 Nachbarn durch. Da das Feld von unten nach oben durchsucht wird, reicht es aus nur "nach oben zu schauen".

Hat ein Nachbarstein die gleiche Farbe, dann wird ein Zähler um 1 erhöht und sich die Richtung gemerkt (senkrecht hoch dy=1, dx=0, diagonal nach rechts dy=1,dx=1 usw.) an der der Stein liegt.
An dem Punkt mit der erkannten Farbe wird in der übergebenen Richtung weitergesucht, bis entweder der Zähler auf 4 steht, eine andere Farbe oder der Rand des Feldes erreicht wurde. Dann werden als erstes die anderen Nachbarn des Steines so bearbeitet, und wenn kein Vierer gefunden, mit dem Stein nebenan fortgesetzt.
Das machst du so lange, bis eine Reihe überhaupt keinen Stein mehr aufweist, oder du alle Felder durchhast.

Das sind drei ineinander verschachtelte Schleifen.
1) Startstein Reihen / Spalten durchgehen
2) Nachbarn des Startsteins abfragen
3) Linie des Nachbarsteins verfolgen
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke für deine Antwort.

Das Prinzip verstehe ich. Die Umsetzung ist am schwierigsten. Ich werde zuerst ein Struktrogramm herstellen, aber ich bin nicht begabt in Struktrogramm.
Vielleicht könntest du mir beim Struktrogramm helfen oder eine Starthilfe geben. :p

Gruss
 
Statt Struktogramm kannst du auch nen Programmablaufplan machen.

Wenn es ganz einfach sein soll sehe ich hier zwei Schleifen über das gesamte Raster::

Start mit Reihe=1 und Spalte=1

Abfrage:
1) Reihe nach Links (Reihe,Spalte und Reihe,Spalte+1 und Reihe,Spalte+2 und Reihe,Spalte+3 == Sieg)
2) Spalte nach Oben (Reihe,Spalte und Reihe+1,Spalte und Reihe+2,Spalte und Reihe+3,Spalte == Sieg)
3) Diagonale aufsteigend Links (Reihe,Spalte und Reihe+1,Spalte+1 und Reihe+2,Spalte+2 und Reihe+3,Spalte+3 == Sieg)
4) Diagonale aufsteigend Rechts (Reihe,Spalte und Reihe-1,Spalte-1 und Reihe-2,Spalte-2 und Reihe-3,Spalte-3 == Sieg)

Spalte=Spalte+1
IF Spalte > 7 THEN Spalte = 1; Reihe = Reihe + 1
IF Reihe > 6 THEN Goto Ende
Goto Abfrage
Ende


Vorzeitigen Abbruch beim Erreichen von Grenzen, insbesondere bei 4), hab ich jetzt mal nicht berücksichtigt.


Gruß MK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dachte es wäre selbsterklärend, naja:

du startest deine zwei Schleifen (eine für die Spalte und eine für die Reihe) bei (1,1).
Es gibt 4 Möglichkeiten zum Sieg:
4 gleiche in einer Reihe
4 gleiche in einer Spalte
4 gleiche diagonal aufsteigend nach rechts
4 gleiche diagonal aufsteigend nach links

geprüft werden nun durch ganz einfache Und-Verknüpfung in den 4 Fällen ob eine Vierergruppe vorhanden ist.
falls nicht:
dann wird die Spalte um eins erhöht (Schleifenzahler Spalte) und die nächste Prüfung gemacht.
Ist die Spaltennummer > 7 wird die Reihe um eins erhöht (Schleifenzähler Reihe) und der Schleifenzähler Spalten wieder auf 1 gesetzt.
Ist die Reihennummer > 6 wurden alle Felder ergebnislos durchlaufen.

sollte doch nicht so schwer sein:oops:
 
Mittagszeit, alten-C/C++Source-ins-Forum-kopier-Zeit

so hatte ich mal die Auswertung gemacht - aber mit Test der ganzen Linie
viel kleiner wird es wohl nicht gehen - oder?

keine Ahnung wie gut sich das nach SCL umsetzen laesst - wer machts mir pe PN aus Spass :)

Code:
#include <cstdio>


//--------------- 
// 4 gewinnt auswertung


const int BREITE = 7;
const int HOEHE = 6;
const int GEWINN_ANZAHL = 4;


//belegung: 0=leer, 1=spieler 1, 2=spieler 2, ...
int spielfeld[BREITE][HOEHE]={0};


int fuellhoehe[BREITE]={0};


bool setzen_moeglich(int x)
{
  return fuellhoehe[x] < HOEHE;
}


bool belegung_durchlaufen(int start_x, int start_y, int aktuell_x, int aktuell_y, int distanz, int richtung_x, int richtung_y, int erwartete_belegung)
{
  bool spielstein_gefunden = false;


  int anzahl = 0;


  for(int i = 0; i < distanz; ++i)
  {
    int test_x = start_x + i * richtung_x;
    int test_y = start_y + i * richtung_y;

    bool ist_erwartete_belegung = spielfeld[test_x][test_y] == erwartete_belegung;

    if(!spielstein_gefunden)
    {
      anzahl = ist_erwartete_belegung ? ++anzahl : 0;
      spielstein_gefunden = ( test_x == aktuell_x && test_y == aktuell_y );
    }
    else
    {
      if(!ist_erwartete_belegung) break;
      ++anzahl;
      if( anzahl == GEWINN_ANZAHL ) break;
    }
  }
  return anzahl == GEWINN_ANZAHL;
}


bool test_strecke(int aktuell_x, int aktuell_y, int distanz_zum_punkt, int distanz_vom_punkt, int richtung_x, int richtung_y, int erwartete_belegung)
{
  int start_x = aktuell_x - distanz_zum_punkt * richtung_x;
  int start_y = aktuell_y - distanz_zum_punkt * richtung_y;
  //int ende_x = start_x + (distanz - 1) * richtung_x;
  //int ende_y = start_y + (distanz - 1) * richtung_y;


  int distanz = distanz_zum_punkt + 1 + distanz_vom_punkt;
  if( distanz < GEWINN_ANZAHL ) return false; // kann keine gewinnstrecke sein


  return belegung_durchlaufen(start_x, start_y, aktuell_x, aktuell_y, distanz, richtung_x, richtung_y, erwartete_belegung);
}


int minimum(int a, int b)
{
  if( a > b ) return b;
  return a;
}


void print_spielfeld()
{
  for(int y = HOEHE-1; y >= 0; --y)
  {
    for(int x = 0; x < BREITE; ++x)
    {
      printf("%i ", spielfeld[x][y]);
    }
    printf("\n");
  }
  printf("-------------------\n");
}


bool setzen(int x, int belegung)
{
  //assert(setzen_moeglich(x));


  ++fuellhoehe[x];
  int y = fuellhoehe[x]-1;
  spielfeld[x][y] = belegung;


  //print_spielfeld();


  //gewonnen?


  //wie weit sind wir von den raendern weg?
  int distanz_oben = HOEHE - y - 1;
  int distanz_unten = y;
  int distanz_rechts = BREITE - x - 1;
  int distanz_links = x;


  //die distanzen diagonal
  int distanz_links_unten = minimum(distanz_links, distanz_unten);
  int distanz_rechts_oben = minimum(distanz_rechts, distanz_oben);
  int distanz_links_oben = minimum(distanz_links, distanz_oben);
  int distanz_rechts_unten = minimum(distanz_rechts, distanz_unten);


  bool links_unten_nach_rechts_oben = test_strecke(x, y, distanz_links_unten, distanz_rechts_oben, +1, +1, belegung);
  bool links_nach_rechts = test_strecke(x, y, distanz_links, distanz_rechts, 1, 0, belegung);
  bool links_oben_nach_rechts_unten = test_strecke(x, y, distanz_links_oben, distanz_rechts_unten, +1, -1, belegung);
  bool nach_unten = test_strecke(x, y, 0, distanz_unten, 0, -1, belegung);


  bool gewonnen = 
    links_unten_nach_rechts_oben
    || links_nach_rechts
    || links_oben_nach_rechts_unten
    || nach_unten;


  if( gewonnen ) printf("gewonnen!");


  return gewonnen;
}


int main(int argc, char** argv)
{
  //print_spielfeld();


  setzen(1,2);
  setzen(2,2);
  setzen(2,2);
  setzen(3,2);
  setzen(3,2);
  setzen(3,2);


  setzen(0,1);
  setzen(1,1);
  setzen(2,1);
  setzen(3,1); // gewonnen


  return 0;
}
 
Zuletzt bearbeitet:
Zurück
Oben