4 Gewinnt in C++



  • Hey Leute 🙂
    Ich möchte 4 Gewinnt in C++ programmieren. Die Oberfläche hab ich bereits, jedoch scheitert es an der Gewinnabfrage. Ich dachte mir, das es mit Feldern am einfachsten ist?!
    Könnt ihr mir bitte weiter helfen?

    mfg
    Danke.



  • Ja, Arrays sind schonmal eine gute Idee, in dem Fall vermutlich ein zweidimensionales Array, in dem du das Spielfeld verstaust - dort kannst du dann mit Schleifen durchlaufen und prüfen, wieviele gleiche Elemente hintereinander vorkommen.



  • Du kannst die Gewinnüberprüfung in 3 Schleifen erledigen.

    1. Horizontal
    2. Vertikal
    3. Schräg

    Wo genau ist dein Problem?



  • leider kenn ich mich mit 2dimensionalen nicht wirklich aus.
    wenn ich z.b ifeld[7][6] schreibe, ist das dann ein 2d array?

    mfg
    danke.



  • Ich weis leider nicht wie ich schreiben soll das das programm erkennt, das 4steine in einer reihe sind bzw. welcher spieler gewinnt.

    mfg
    Danke.



  • Du suchst einfach überall nach der Siegesbedingung, oder wo liegt das Problem?



  • Genau, du legst ein zweidimensionales Array an. Dann legst du Werte bzw. deren Bedeutung fest. z.B. 0 für kein Stein, 1 für Stein von Spieler 1 und 2 für Stein von Spieler 2. Ich habe dir mal eine Funktion geschrieben, die testet ob 4 Steine in einer Reihe sind:

    int game_end(char field[][5], int size_x, int size_y)
    {
      int count1 = 0, count2 = 0;
      for (int i = 0; i < size_x; ++i)
      {
        for (int j = 0; j < size_y; ++j)
        {
          if (field[i][j] == 1)
            ++count1, count2 = 0;
          else if (field[i][j] == 2)
            ++count2, count1 = 0;
          else
            count1 = count2 = 0;
          if (count1 >= 4)
            return 1;
          if (count2 >= 4)
            return 2;
        }
      }
      return 0;
    }
    
    int main()
    {
      char field[5][5] = 
      {
        {0, 0, 0, 0, 0,},
        {0, 0, 0, 0, 0,},
        {2, 0, 0, 0, 0,},
        {2, 0, 0, 0, 0,},
        {2, 1, 1, 1, 1,},
      };
      int rval = game_end(field, 5, 5);
      if (rval == 1)
        puts("Player1 wins!");
      else if (rval == 2)
        puts("Player2 wins!");
      else
        puts("Nobody wins ;)");
      getchar();
      return 0;
    }
    


  • Tanner schrieb:

    leider kenn ich mich mit 2dimensionalen nicht wirklich aus.

    In was für einer Datenstruktur verwaltest Du denn den Spielstand?



  • Belli schrieb:

    Tanner schrieb:

    leider kenn ich mich mit 2dimensionalen nicht wirklich aus.

    In was für einer Datenstruktur verwaltest Du denn den Spielstand?

    Datenstruktur? hab leider nicht viel ahnung davon .

    mfg
    Danke



  • Tanner schrieb:

    Datenstruktur?

    Wie sieht die Definition des Spielfeldes aus? 😉



  • EOutOfResources schrieb:

    Tanner schrieb:

    Datenstruktur?

    Wie sieht die Definition des Spielfeldes aus? 😉

    int feld[7][6] .
    habe ja von der Gewinnabfrage noch nicht viel



  • Tanner schrieb:

    int feld[7][6] .
    habe ja von der Gewinnabfrage noch nicht viel

    Hast du denn überhaupt schon implementiert, dass man Steine setzen und das Spielfeld ausgeben kann?



  • cooky451 schrieb:

    Tanner schrieb:

    int feld[7][6] .
    habe ja von der Gewinnabfrage noch nicht viel

    Hast du denn überhaupt schon implementiert, dass man Steine setzen und das Spielfeld ausgeben kann?

    habe es so:
    Sobald man Button1 drückt, wird das spiel erstellt, mittels Canvas->MoveTo bzw. Canvas->LineTo ....,
    und es kommen buttons über jede spalte, wenn man sie drückt fällt ein stein in diese spalte.

    mfg
    Danke



  • Und werden die Steine dann auch in dein Array geschrieben? Du musst Logik und Grafikteil schon verknüpfen 😃

    Guck dir doch einfach mein Beispiel für die horizontale Abfrage an, und bau das dann für die zwei verbleibenden Siegesbedingungen nach.



  • cooky451 schrieb:

    Und werden die Steine dann auch in dein Array geschrieben? Du musst Logik und Grafikteil schon verknüpfen 😃

    Guck dir doch einfach mein Beispiel für die horizontale Abfrage an, und bau das dann für die zwei verbleibenden Siegesbedingungen nach.

    //---------------------------------------------------------------------------
    void __fastcall TForm4::Button2Click(TObject *Sender)
    {
    spalte1++;
    spieler++;

    if(spalte1==1)
    {
    if(spieler%2)
    Canvas->Brush->Color=clRed;

    else
    Canvas->Brush->Color=clYellow;

    Canvas->Ellipse(x, y, x+d, y+d);

    }

    if(spalte1==2)
    {
    if(spieler%2)
    Canvas->Brush->Color=clRed;

    else
    Canvas->Brush->Color=clYellow;

    Canvas->Ellipse(x, y-90, x+d, y);

    }

    if(spalte1==3)
    { if(spieler%2)
    Canvas->Brush->Color=clRed;

    else
    Canvas->Brush->Color=clYellow;

    Canvas->Ellipse(x, y-180, x+d, y-90);
    }

    if(spalte1==4)
    { if(spieler%2)
    Canvas->Brush->Color=clRed;

    else
    Canvas->Brush->Color=clYellow;

    Canvas->Ellipse(x, y-270, x+d, y-180);
    }

    if(spalte1==5)
    { if(spieler%2)
    Canvas->Brush->Color=clRed;

    else
    Canvas->Brush->Color=clYellow;

    Canvas->Ellipse(x, y-360, x+d, y-270);
    }

    if(spalte1==6)
    { if(spieler%2)
    Canvas->Brush->Color=clRed;

    else
    Canvas->Brush->Color=clYellow;

    Canvas->Ellipse(x, y-450, x+d, y-360);
    }

    das habe ich für alle 7 spalten gemacht ?!

    mfg
    Danke



  • Ich glaube, du solltest erstmal die Grundlagen wie Schleifen etc. lernen. Wo hast du eigentlich spieler/spalte1 deklariert? Und bitte nutze Codetags, wenn du hier Code postest. (Unter den Smilies)



  • cooky451 schrieb:

    Ich glaube, du solltest erstmal die Grundlagen wie Schleifen etc. lernen. Wo hast du eigentlich spieler/spalte1 deklariert? Und bitte nutze Codetags, wenn du hier Code postest. (Unter den Smilies)

    ganz oben .. ist nur ein teil aus meinem programm.
    ok



  • "Ganz oben" soll heißen global? Globale Variablen sind böse! 😃

    Schreib dir doch erstmal eine Funktion, der du die Position des zu malenden Steins übergibst, soll heißen die Position im Spielfield, und dann die absoluten Koordinaten ausrechnest. Ich habe jetzt noch nie mit Canvas gearbeitet, aber könnte dann so aussehen:

    static const int PIXEL_ZAHL_DIE_DU_FESTLEGST_DAMIT_DAS_INS_SPIELFIELD_PASST = 50;
    static const int pixel = PIXEL_ZAHL_DIE_DU_FESTLEGST_DAMIT_DAS_INS_SPIELFIELD_PASST;
    static const int MUSSTE_TESTEN = 30;
    
    void DrawPlayerStone(int x, int y, int player, CANVAS* Canvas)
    {
      if (player % 2)
        Canvas->Brush->Color = clRed;
      else
        Canvas->Brush->Color = clYellow;
    
      Canvas->Ellipse(x * pixel, y * pixel, x + MUSSTE_TESTEN, y + MUSSTE_TESTEN);
    }
    


  • Man kann sich bei der Gewinnprüfung einen Haufen Arbeit sparen, wenn man bedenkt, dass eine gewinnende Reihe nur da zustande kommen kann, wo gerade ein Stein platziert wurde. Ich habe so etwas noch in C hier rumliegen:

    #define HEIGHT   5
    #define WIDTH    7
    #define REQUIRED 4
    
    ...
    
    typedef struct {
      /* board[0][0] ist hier links oben */
      int board[WIDTH][HEIGHT];
      /* tops beinhaltet die nächsten Positionen in den Schächten; diese sind
       * für die Gewinnabfrage nicht von Bedeutung. */
      int tops[WIDTH];
    } game_t;
    
    static int game_t_won(game_t const *this, size_t x, size_t y) {
      int colour = this->board[x][y];
      int i, j, tmp;
    
      /* senkrecht */
      tmp = 1;
      for(j = y + 1; j < HEIGHT && this->board[x][j] == colour; ++j) ++tmp;
      if(tmp >= REQUIRED) return 1;
    
      /* waagerecht */
      tmp = 1;
      for(i = x - 1; i >=     0 && this->board[i][y] == colour; --i) ++tmp;
      for(i = x + 1; i <  WIDTH && this->board[i][y] == colour; ++i) ++tmp;
      if(tmp >= REQUIRED) return 1;
    
      /* diagonal \ */
      tmp = 1;
      for(i = x - 1, j = y - 1; i >=     0 && j >=      0 && this->board[i][j] == colour; --i, --j) ++tmp;
      for(i = x + 1, j = y + 1; i <  WIDTH && j <  HEIGHT && this->board[i][j] == colour; ++i, ++j) ++tmp;
      if(tmp >= REQUIRED) return 1;
    
      /* diagonal / */
      tmp = 1;
      for(i = x - 1, j = y + 1; i >=     0 && j <  HEIGHT && this->board[i][j] == colour; --i, ++j) ++tmp;
      for(i = x + 1, j = y - 1; i <  WIDTH && j >=      0 && this->board[i][j] == colour; ++i, --j) ++tmp;
      if(tmp >= REQUIRED) return 1;
    
      return 0;
    }
    

    ...wobei x und y die Koordinaten des letzten Zuges sind.



  • Das heist, jedes mal wenn ich einen Stein setzte, soll überprüft werden , ob 4 steine in einer Reihe sind?! Das könnte ich mit einem Unterprogramm machn oder?

    Aber wie sollte die Funktion aussehn?
    z.B:
    if(ifeld[x][y]+ifeld[x][y+1]+ifeld[x][y+2]+ifeld[x][y+3]== was?^^)

    mfg


Anmelden zum Antworten