Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » 4 Gewinnt Prüfprobleme

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
26.01.2011, 14:51 Uhr
Tjelfe



Hallo, ich habe ein kleines Problem, ich muss für ein schulprojekt 4 Gewinnt programmieren, und bekomme die Prüfungen nicht hin.

Da ich nicht haufenweise if Abfragen machen möchte, habe ich versucht über eine for Schleife mit nur einer If Abfrage für jeweils senkrecht, waagerecht und diagonal auszukommen.

hoffe Ihr könnt mir weiterhelfen.

Lg Tjelfe

C++:
// 4_Gewinnt.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//


#include "stdafx.h"
#include "iostream"
#include "conio.h"
#include "string"
#include "windows.h" //Wird für die Funktion system("cls") benutzt um den Bildschirm
                    //zu säubern

using namespace std;

class spiel
{
private:
    string spielfeld[7][8]; //Spielfeld[Spalte][reihe]
    int i,j,s0,s1,s2,s3,s4,s5,s6,temp; // s Variablen zum runterzählen des Spielfeldes
    bool win; //Boolische Werte arbeiten mit true und false:
             //true kann man mit 1 gleichsetzen und false mit 0 wie beim binärsystem
public:
    void erstell_feld() //Funktion zum erstellen des ersten Feldes mit dem + als Platzhalter
    {
        for (i=0;i<6;i++)
        {
            for (j=0; j<7;j++)
            {
                spielfeld[i][j]='+';
            }
        }
    }
    void neu_erstell() //Funktion wird jedesmal nach dem setzen aufgerufen
    {                  //um den Platzhalter mit dem Spieler zu füllen
        cout<<"*****Willkommen bei 4-Gewinnt*****\n\n";
        for (int i=0;i<6;i++)
        {
            for(int j=0;j<8;j++)
            {
                cout<<spielfeld[i][j];
            }
            cout<<"\n";
        }
        cout<<"-------\n1234567\n\n"; //Ausgabe der zu wählenden Zahlen
    }
    void temp0(){temp=5;}
    void variable()
    {
            s0=5; s1=5; s2=5; s3=5; s4=5; s5=5,s6=5; //alle Spaltenvariablen werden auf 5 gesetzt
    }                                                 //da jedes Feld mit spielfeld[?][5] beginnt
                                                    //und beim Setzen runtergezählt werden müssen
    
    void stein_werfen(int spalte,string spieler)//Aus dem Hauptprogramm werden die spalte und der
    {                                           //Spieler übergeben.
        if(spalte==0)                          //wenn die angegebene Spalte zwischen 1 und 7
        {                                     //liegt, wird der Spieler gesetzt und die Variable um 1 verringert
                spielfeld[s0][spalte]=spieler;s0--;temp=s0;
        }                                          
        else if(spalte==1)
        {    
                spielfeld[s1][spalte]=spieler;s1--;temp=s1;
        }
        else if(spalte==2)
        {    
                spielfeld[s2][spalte]=spieler;s2--;temp=s2;
        }
        else if(spalte==3)
        {    
                spielfeld[s3][spalte]=spieler;s3--;temp=s3;
        }
        else if(spalte==4)
        {    
                spielfeld[s4][spalte]=spieler;s4--;temp=s4;
        }
        else if(spalte==5)
        {    
                spielfeld[s5][spalte]=spieler;s5--;temp=s5;
        }
        else if(spalte==6)
        {    
                spielfeld[s6][spalte]=spieler;s6--;temp=s6;
        }
    }
    //Prüfen ob 4 Steine senkrecht,waagerecht oder diagonal dem selben spieler gehören.
    bool prüfe(int spalte, string spieler)
    {
        win=false; //win wird gleich auf false gesetzt, damit wenn jemand 4 in einer Reihe hat
                   //win als true gekennzeichnet werden kann und das spiel somit beendet
        
    
        
        
        //senkrecht
        for(i=0;i<4;i++)
        {
            if(spielfeld[temp][spalte]==spieler&& spielfeld[temp-1][spalte]==spieler
                && spielfeld[temp-2][spalte]==spieler)
            {
                win=true;
                return win;
            }
        }
        //waagerecht
            for(i=5;i<=3;i--)
            {
                if(spielfeld[temp][i]==spieler&& spielfeld[temp][i-1]==spieler
                    && spielfeld[temp][i-2]==spieler && spielfeld[temp][i-3]==spieler)
                {
                    win=true;
                    return win;
                }
            }

            //diagonal
            for(i=5;i<0;i--)
            {
                if(spielfeld[i][spalte]==spieler &&spielfeld[i-1][spalte+1]==spieler &&
                    spielfeld[i-2][spalte+2]==spieler)
                {
                    win=true;
                    return win;
                }
            }
    }
        
    

                int rückgabe(int spalte) //Rückgabe der Werte der Spalten zum Prüfen ob die Spalte voll ist
                {                        //+1 da die Spalte den Wert 0 Erreichen muss um das Feld zu füllen
                    if(spalte==0)        
                    {
                        return s0+1;
                    }
                    if(spalte==1)
                    {
                        return s1+1;
                    }
                    if(spalte==2)
                    {
                        return s2+1;
                    }
                        if(spalte==3)
                    {
                        return s3+1;
                    }
                    if(spalte==4)
                    {
                        return s4+1;
                    }
                    if(spalte==5)
                    {
                        return s5+1;
                    }
                        if(spalte==6)
                    {
                        return s6+1;
                    }
    
                }
};        


int _tmain(int argc, _TCHAR* argv[])
{    
    spiel sp;
    int s0,prüf;
    int weiter,h,spalte;
    bool win=false;
    string spieler[3]; //Spieler werden als Array abglegt um einfacher zwischen ihnen zu wechseln
    spieler[1]="0";
    spieler[2]="X";
    
    sp.erstell_feld();
    sp.variable();
    do
    {
        for(h=1;h<=2;h++)
        {sp.temp0();
            do
            {    
                sp.neu_erstell();
                cout<<"Spieler "<<spieler[h]<<" welche spalte: ";
                cin>>spalte;
                prüf=sp.rückgabe(spalte-1);    
                
            }
            while(spalte<1 || spalte>7||prüf==0);

            win=sp.prüfe(spalte-1,spieler[h]);    
            sp.stein_werfen(spalte-1,spieler[h]);    //mit -1 übergeben, wegen dem Aufbau des Feldes
            if(win==true){cout<<"\nSpieler "<<spieler[h]<<" hat gewonnen"; break;}
            system("cls");//Clearscreenbefehl
        }
    }
    while(win==false);//läuft solange durch wie die Variable win auf false gesetzt ist
    getch();
    return 0;
}


Dieser Post wurde am 26.01.2011 um 16:55 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
26.01.2011, 18:21 Uhr
Lensflare



Hi Tjelfe,

wenn du s0 bis s6 als Array der Größe 7 anlegst, statt 7 einzelne Variablen, wird sich dein Problem wahrscheinlich fast von alleine lösen.


EDIT:

Habe es mir nochmal genauer angeschaut und festgestellt dass du weiter unter schon arrays verwendest, so wie es sein sollte.
Also um alle 4er kombinationen zu prüfen kannst du es folgendermaßen machen:
Beispiel für die Zeilen: stelle dir eine Schablone vor, durch die du eine zeile von 4 steinen sehen kannst. du musst diese schablone jetzt nur noch verschieben und für jede position prüfen, ob die 4 steine, die durch die schablone sichtbar sind, gleich sind.
Die aktuelle position kann man sich merken mit 2 int variablen (aktuelle höhe und breite). Diese beiden Variablen werden in einer 2-fach verschatelten for schleife so erhöht, dass alle positionen durchprobiert werden (schieben). die möglichen positionen ergeben sich folgendermaßen:
nach oben sind es die positionen 0 bis spielfeldhöhe.
nach rechts sind es die positionen 0 bis spielfeldbreite-4.
Das "gucken" durch die schablone ist dann nichts anderes als von der aktuellen schablonenposition aus die nächsten 4 steine rechts prüfen.

Spalten und Diagonalen lassen sich dann auch auf diese weise abprüfen.

Die variablen s0 bis s6 solltest du aber trotzdem als array machen, dann kannst die ganzen ifs

C++:
        if(spalte==0)
        {
                spielfeld[s0][spalte]=spieler;s0--;temp=s0;
        }                                          
        else if(spalte==1)
        {    
                spielfeld[s1][spalte]=spieler;s1--;temp=s1;
        }
        ...
        ...
        ...


so abkürzen:

C++:
         spielfeld[s[spalte]][spalte]=spieler;s[spalte]--;temp=s[spalte];



Da scheint mir auch noch etwas redundant zu sein. das müsste ich mir dann auch noch genauer anschauen.
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)

Dieser Post wurde am 26.01.2011 um 18:49 Uhr von Lensflare editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
26.01.2011, 18:55 Uhr
Tjelfe



Hey Lensflare, habe deinen Rat befolgt und es mal umgeschrieben, nun geht es immer noch nicht...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
26.01.2011, 20:01 Uhr
Lensflare



etwas genauer? ^^
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
26.01.2011, 20:11 Uhr
Tjelfe



Naja, zuerst hatte ich nur deinen ersten Beitrag gelesen, und so die s Variablen umgestellt darauf bezog sich meine Nachricht^^
Das mit der Verkürzung ist eine gute Idee, so erspare ich mir viel Platz!

mit den in zwei int Variablen speichern kann ich grad irgendwie nicht nachvollziehn, denn die Höhe der reihe speicher ich ja extra in der temp Variable, und somit kann ich ja bei jedem durchlauf von dort aus Prüfen, wie ich es auch schon tat... nur komme ich so nicht auf das gewünschte ergebnis...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
26.01.2011, 20:57 Uhr
Lensflare




Zitat:
mit den in zwei int Variablen speichern kann ich grad irgendwie nicht nachvollziehn, denn die Höhe der reihe speicher ich ja extra in der temp Variable, und somit kann ich ja bei jedem durchlauf von dort aus Prüfen, wie ich es auch schon tat... nur komme ich so nicht auf das gewünschte ergebnis...


Wenn ich dich richtig verstanden habe, dann machst du das aktuell so, dass du von der spalte aus, in die zuletzt ein stein gelegt wurde, die 4er kombi prüfst.
Das würde so auch gehen, aber das ist meiner meinung nach nicht so praktisch, weil du ja dann um 4er zeilen zu prüfen, nach links UND rechts gehen müsstest und um 4er spalten zu prüfen, nach oben UND unten.
Und du müsstest überprüfen, ob du dich am rand des spielfeldes befindest, damit du zum beispiel bei spalte 0 nicht noch weiter nach links gehst um eine 4er zeile zu prüfen.

Mein vorschlag wäre unabhängig von der spalte, wo der letzte stein rein fiel, einfach alle möglichen spalten/zeilen/diagonalen durch zu probieren.

etwa so:

C++:
//prüfe alle 4er Zeilen
for(int spalte=0; spalte<spielfeldBreite-4; spalte++)
{
    for(int zeile=0; zeile<spielfeldHoehe; zeile++)
    {
        //beginne bei spalte und zeile und prüfe
        //    von der position aus die nächsten 4 steine rechts
        //    also spalte+0, spalte+1, spalte+2 und spalte+3
    }
}



(du solltest vielleicht andere variablennamen als "spalte" und "zeile" verwenden, falls du diese bereits vergeben hast)

und dann so ähnlich auch für 4er spalten und auch für 4er diagonalen. bei den diagonalen würde ich auch unterscheiden zwischen schräg nach oben rechts und schräg nach unten rechts.

insgesamt also 4 von solchen konstrukten (spalten, zeilen, diagonalen1, diagonalen2)

bestimmt gibt es noch viele andere lösungswege. dies ist einer der mir am einfachsten erscheint.
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)

Dieser Post wurde am 26.01.2011 um 21:00 Uhr von Lensflare editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
28.01.2011, 12:50 Uhr
Tjelfe



Hey Lensflare,
habe es nochmal so umgeschrieben, wie du es mir empfohlen hattest. Die Prüfung fällt immernoch gleich aus. Er konntrolliert, ob drei aneinander gereiht sind, legt spieler zwei einen Stein dazwischen, und spieler 1 dadrüber noch einen, hat spieler 1 dennoch gewonnen, obwohl er es nicht geschafft hat, 4 Steine aneinander zu reihen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
28.01.2011, 16:58 Uhr
Lensflare



Das hört sich nach folgenem code an:

C++:
int x = 0;
for(int spalte=0; spalte<spielfeldBreite-4; spalte++)
{
    for(int zeile=0; zeile<spielfeldHoehe; zeile++)
    {
        if(spielfeld[spalte][zeile] == spieler)
        {
            x++;
            if(x==4)
            {
                win = true;
                return win;
            }
        }
    }
}


und das wäre nicht richtig.

Zeige mir bitte den deinen code, wo die 4er geprüft werden.

Mir ist noch was aufgefallen, was nicht zu dem problem gehört, aber trotzdem unschön ist:
Die Klasse "spiel" besitzt die private variable "win". Diese Variable ist aber bei der Klasse überflüssig. die Funktion "prüfe()" gibt ja schon einen boolean per return zurück.

C++:
win=sp.prüfe(spalte-1,spieler[h]);


Du verwendest ab da nur den Wert, der über return zurück kam, aber nicht den, der in der Klassenvariablen "win" drin steht.

Du kannst also die Klassenvariable "win" aus der Klasse löschen und bei der funktion "prüfe()" die zeilen

C++:
                win = true;
                return win;


ersetzen mit

C++:
                return true;


--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
28.01.2011, 17:12 Uhr
Tjelfe



Okay, stimmt habe nicht drann gedacht, dass es reicht, true zurück zu geben...

dies ist mein Code für die Senkrechte Prüfung

//senkrecht
for(b=0;b<8-4;b++)
{
for(h=0;h<6;h++)
{
if(spielfeld[b][h]==spieler && spielfeld[b+1][h]==spieler
&&spielfeld[b+2][h]==spieler)
{
win=true;
return win;
}
}
}
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
28.01.2011, 18:01 Uhr
Lensflare



also wenn b für breite steht, dann müsste das die prüfung für die waagerechte sein, weil du da ja entlang der breite prüfst.

aktuell prüfst du 3 steine nebeneinander:
b, b+1, b+2

du musst aber 4 prüfen:
b, b+1, b+2, b+3


C++:
if(spielfeld[b][h]==spieler &&
  spielfeld[b+1][h]==spieler &&
  spielfeld[b+2][h]==spieler &&
  spielfeld[b+3][h]==spieler)
{
  return true;
}


--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)

Dieser Post wurde am 28.01.2011 um 18:03 Uhr von Lensflare editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: