Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » [Konsole] Mastermind "Auswertung"

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 <
000
12.09.2005, 19:08 Uhr
sf



Nabend...

Ich habe ein par Probleme eine Auswertung eines MasterMind Programmes durchzuführen.

Ich habe ein Array pspielfeld[5], welches die 5 Zahlen enthält, welche am Anfang vom PC gezogen werden. Diese müssen beim Mastermind ja bekanntlich erraten werden.

Weiterhin habe ich ein Array peingabe[runde][zahl]

Hierbei gilt: runde = Aktuelle Ziehrunde (da es mehrere Runden gibt und ich alle Runden immer untereinander ausgegeben haben möchte speicher ich die Runde hierein um alle Runden exakt ansteuern zu können)
zahl = eine Zahl von 1 -7 welche für die Farbe steht, welcher der Nutzer will.
1 = rot
2 = gelb
3 = grün
4 = blau
5 = weiß
6 = braun
7 = orange

Nun laufen diese Eingaben ab und es soll in einer Funktion geguckt werden was alles richtig ist.

Ich habe da erstmal folgendes geprüft:


C++:
for ( i = 0; i > 5 ; i ++ ) {
    if ( pspielfeld[i] == peingabe[*prunde][i] ) {
        cout << "x";
    }
}
/*
Ich denke das ganze ist leicht erklärt. Der Pointer kommt durch Übergabe von der Funktion das passt so. Ich gucke ob an der Stelle im Spielfeld, welche ich gerade durchlaufe (mit der for-Schleife durchlaufe ich ja nacheinander alle 5 Felder) GENAU die gleiche Zahl in der Eingabe für DIESES Feld steht. Wenn das der Fall ist gebe ich ein X aus.

*/




Soweit klappt das ganze auch erstmal.

Wenn eine Farbe richtig ist, aber am falschen Ort so soll ein "O" ausgegeben werden.
Das bekomme ich zwar halbwegs hin, aber meinen Code hier hinzuschreiben wäre wohl wenig sinnvoll.
Kurz erklärt prüfe ich alle Felder der Eingabe, ob der gleiche Zahlenwert drinsteht wie im Spielfeld.



Das bringt mir jetzt einige Probleme:

1) Wenn eine Zahl doppelt gezogen wurde (vom PC) so gibt es Fehler und es ist z.B. ein "O" zu wenig, oder Ähnliches.
2) Wenn ich bei allen 5 Eingaben die ich habe die gleiche Zahl verwende und diese irgendwo vorkommt, so bekomme ich nicht nur 1x, sondern auch ein O.


Wie bekomme ich das hin, dass diese Abfrage richtig funktioniert?

Im Anhang findet ihr noch den kompletten C++ Code, welcher allerdings noch bissl buggy ist denke ich. Würde mich freuen, wenn jemand helfen kann!


C++:
// MASTERMIND
#include <iostream>
#include <stdlib.h>
#include <windows.h> //Wird für die Farben benötigt
#include <time.h> //Wird für Zufallsgenerator benötigt

//Farbdefinition
#define blau    9
#define turkise 11
#define gruen   10
#define rot     4
#define gelb    14
#define grau    8
#define white   15

const unsigned char BB = static_cast<unsigned char>(157);

using namespace std;
//---------
void textcolor(WORD color)           //Funktion fuer Farbe
{
    SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), color);
}
//---------

void zufall(int*); // zieht zufällig Zahlen für Array von Spielfeld
int zug(int*,int*); // Zug-Funktion

//Eingabe wird als Globale Variable deklariert , weil ich Probleme mit der Übergabe eines Multidimensionales Arrays an eine Funktion hatte
int eingabe[17][5];

int main()
{
int spielfeld[5];
int runde=1;
int i;
int sieg;

//Zufallfunktion
     zufall(spielfeld);
do
{
    sieg = zug ( spielfeld, &runde ); // ist unwichtig, weil noch nichts zurückgegeben wird...
    textcolor(15);
    cout << "\n------------------------------------------------------------\n";
    runde+=1;
}
while(sieg!=1);
  system("PAUSE");
  return 0;
}
void zufall(int* pspielfeld)
{
    int i;
    srand((unsigned)time(NULL));
    for(i=0;i<5;i++)
    {
        pspielfeld[i] =  rand()%6+1;
    }
}
int zug(int* pspielfeld,int* prunde)
{
    int i,j;
    cout << "(1) blau\n";
    cout << "(2) tuerkis\n";
    cout << "(3) gruen\n";
    cout << "(4) rot\n";
    cout << "(5) gelb\n";
    cout << "(6) grau\n";
    cout << "(7) weiss\n";
    for (i=0; i<5;i++)
    {
        cout << "Bitte waehlen Sie aus, welche Farbe Sie ins " <<i+1<<". Feld setzen moechten:\n";
        cin >> eingabe[*prunde][i];
    }
    
    cout << "\n--------------------------------------------------------------\n";
    cout << "RUNDE: "<<*prunde<<" - Sie haben folgende Steine gesetzt:\n";
    for (i=0; i<5;i++)
    {
        if ( eingabe[*prunde][i] == 1 )
        {
                textcolor(9);
                cout << BB << "\t";
        } else if ( eingabe[*prunde][i] == 2 )
        {
                textcolor(11);
                cout << BB << "\t";
        } else if ( eingabe[*prunde][i] == 3 )
        {
                textcolor(10);
                cout << BB << "\t";
        } else if ( eingabe[*prunde][i] == 4)
        {
                textcolor(4);
                cout << BB << "\t";
        } else if ( eingabe[*prunde][i] == 5 )
        {
                textcolor(14);
                cout << BB << "\t";
        } else if ( eingabe[*prunde][i] == 6 )
        {
                textcolor(8);
                cout << BB << "\t";
        } else if ( eingabe[*prunde][i] == 7 )
        {
                textcolor(15);
                cout << BB << "\t";
        }
    }
    textcolor(15);
    // AUSWERTUNG
    for(i=0; i<5; i++)
    {

        if ( pspielfeld[i] == eingabe[*prunde][i] )
        {
             cout << "x";
             eingabe[*prunde][i] == 8;
        }
        if ( pspielfeld[i] == eingabe[*prunde][1]  || pspielfeld[i] == eingabe[*prunde][2] || pspielfeld[i] == eingabe[*prunde][3] || pspielfeld[i] == eingabe[*prunde][4] || pspielfeld[i] == eingabe[*prunde][5] || pspielfeld[i] == eingabe[*prunde][6] )
        {
             cout << "o";
        }

            
    }
cout << "\n";
for (i=0; i<5;i++)
{
    cout << pspielfeld[i];
}
return 0;
}


 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
13.09.2005, 11:00 Uhr
Airdamn



Durch textcolor änderst Du die Farbe von der ganzen Konsole, nicht von dem einzelnen Zeichen.
Daher hab ichs weg gelassen. Ansonsten solltest Du die erweiterte Konsole benutzen (conioex)

C++:
// MASTERMIND
#include <iostream>
#include <stdlib.h>
#include <windows.h> //Wird für die Farben benötigt
#include <time.h> //Wird für Zufallsgenerator benötigt

//Farbdefinition
#define BLAU        9
#define TUERKIS     11
#define GRUEN       10
#define ROT            4
#define GELB        14
#define GRAU        8
#define WEISS       15
#define MAX_RUNDEN    17
#define ANZ_FELDER    5

const unsigned char BB = static_cast<unsigned char>( 157 );

using namespace std;
//---------
void textcolor( WORD color )           //Funktion fuer Farbe
{
    SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), color );
}
//---------

void zufall( int* ); // zieht zufällig Zahlen für Array von Spielfeld
int zug( int[][5], int*, int* ); // Zug-Funktion
int istVorhanden( int feld[ANZ_FELDER], int* pSuche );

int main()
{
    int eingabe[MAX_RUNDEN][ANZ_FELDER];
    int spielfeld[ANZ_FELDER];
    int runde = 1, sieg = 0;

    //Zufallfunktion
    zufall( spielfeld );
    
    do
    {
        sieg = zug( eingabe, spielfeld, &runde ); // sieg ist Anzahl richtiger Felder
        //textcolor( WEISS );
        cout << "\n------------------------------------------------------------\n";
        ++runde;
    }while( sieg < 5 && runde < MAX_RUNDEN );
    
    system( "PAUSE" );
        
    return 0;
}

void zufall( int* pspielfeld )
{
    srand((unsigned)time( NULL ));
    
    for( int i = 0; i < 5; ++i )
    {
        pspielfeld[i] = rand() % 6 + 1;
    }
}

int zug( int eingabe[][ANZ_FELDER], int* pSpielfeld, int* pRunde )
{
    int i, n;
    
    cout << "(1) blau\n";
    cout << "(2) tuerkis\n";
    cout << "(3) gruen\n";
    cout << "(4) rot\n";
    cout << "(5) gelb\n";
    cout << "(6) grau\n";
    cout << "(7) weiss\n";
    
    for( i = 0; i < ANZ_FELDER; ++i )
    {
        cout << "Bitte waehlen Sie aus, welche Farbe Sie ins " << i+1 <<". Feld setzen moechten:\n";
        cin >> eingabe[*pRunde][i];
    }
    
    cout << "\n--------------------------------------------------------------\n";
    cout << "RUNDE: "<< *pRunde <<" - Sie haben folgende Steine gesetzt:\n";
    
    for( i = 0; i < ANZ_FELDER; ++i )
    {
        /*switch( eingabe[*pRunde][i] )
        {
        case 1:
            {
                textcolor( BLAU );
                break;
            }
        case 2:
            {
                textcolor( TUERKIS );
                break;
            }
        case 3:
            {
                textcolor( GRUEN );
                break;
            }
        case 4:
            {
                textcolor( ROT );
                break;
            }
        case 5:
            {
                textcolor( GELB );
                break;
            }
        case 6:
            {
                textcolor( GRAU );
                break;
            }
        case 7:
            {
                textcolor( WEISS );
                break;
            }
        }*/

        
        cout << BB << "\t";
    }
    
    //textcolor( GRAU );
    int tmp[ANZ_FELDER];
    string sResult;
    memcpy( tmp, pSpielfeld, sizeof( tmp ));
        
    // AUSWERTUNG
    // die 'x' werden vorn gesetzt und die 'o' hinten angehängt
    // sonst ist evtl. ja klar welche Zahl richtig war und welche nicht
    for( i = 0, n = 0; i < ANZ_FELDER; ++i )
    {
        if( tmp[i] == eingabe[*pRunde][i] )
        {
            tmp[i] = -1;
            sResult += 'x';
            ++n;
        }
    }
    
    int nPos = -1;
    
    // Jede Zahl wird nur einmal verglichen -> eingabe 12345 zufallszahlen 11111 = 1 mal ein 'o'
    for( i = 0; i < ANZ_FELDER; ++i )
    {
        nPos = istVorhanden( tmp, &eingabe[*pRunde][i] );
    
        if( nPos >= 0 )
        {
            tmp[nPos] = -1;
            sResult += 'o';
        }
    }
    
    cout << sResult.c_str() << endl;

    for( i = 0; i < ANZ_FELDER; ++i )
    {
        cout << pSpielfeld[i];
    }
    
    return n;
}

int istVorhanden( int feld[ANZ_FELDER], int* pSuche )
{
    for( int i = 0; i < ANZ_FELDER; ++i )
    {
        if( feld[i] == *pSuche )
            return i;
    }
    
    return -1;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
13.09.2005, 12:10 Uhr
~sf
Gast


Hi Airdamn,

danke erstmal für deine Mühe! Freut mich riesig!

Also ich habe mir das ganze mal angeguckt und es scheint ja auch sehr gut zu funktionieren, aber ich habe da noch ein par Fragen:

Könntest du den Bereich der Auswertung nochmal für "dumme" User erklären?

Sprich User, welche sich bisher in CPP mit folgenden Themen beschäftigt haben:

Arrays, Schleifen, Bedingungen, Pointer, Funktionen, Referenzen

Einige Sachen wie memcpy oder so sind mir z.B. völlig unbekannt und bei manchen Sachen verstehe ich nicht genau, was das ganze bringt...


Wäre supernett, aber auch so schon riesen Dank an dich!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
13.09.2005, 15:11 Uhr
Airdamn



mit memcpy wird ein Speicherbereich kopiert. Ich kopiere damit das Feld mit den Zufallszahlen, damit ich in der Kopie Werte ändern kann.
Wenn eine Zahl an der richtigen Stelle steht oder wenn eine Zahl nicht an der richtigen Stelle steht, aber überhaupt vorkommt, dann wird an der Stelle eine -1 geschrieben.
Somit wird verhindert, dass bei doppelten Zahlen zu viele Treffer erzielt werden.
z.B. Du gibst zwei 1en ein und eine wird als richtig angezeigt und eine als falsche Stelle, obwohl es nur eine gibt - das wird damit vermieden.

Zuerst schau ich nach richtigen Treffern, z.B.:
Zufallszahlen: 113456
Eingabe: 122221
Tmp (kopie): -113456 <- den Treffer verändern, damit die nicht nochmal einbezogen wird
Ergebnis: x

Das selbe wird bei den Ziffern gemacht, die vorkommen, aber nicht an der richtigen Stelle stehen. Dabei wird die erste gefundene Ziffer -1 gesetzt, damit die nicht nochmal gefunden wird:
Zufallszahlen: 113456
Tmp (kopie): -11345-1
Eingabe: 226622
Ergebnis: o <- Nur ein o weil in den Zufallszahlen nur eine 6 vorkam, nicht 2

Hoffe es ist einigermaßen verständlich...

Dieser Post wurde am 13.09.2005 um 15:14 Uhr von Airdamn editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
14.09.2005, 16:39 Uhr
sf



Jo sehr verständlich glaube ich..

Aber dann könnte man statt dem memcpy doch auch einfach ne Funktion aufrufen, welche ja auch nur Kopien benutzt, oder sehe ich das falsch?

Noch eine Frage:

Was macht : sResult.c_str() ? Ich weiß zwar was in sResult drinsteht, aber irgendwie ist mir c_str unbekannt!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
14.09.2005, 17:12 Uhr
predator




Zitat:

Was macht : sResult.c_str() ? Ich weiß zwar was in sResult drinsteht, aber irgendwie ist mir c_str unbekannt!



MSDN heißt das Zauberwort

Zitat:

Converts the contents of a string as a C-style, null-terminated string.



Wenn eine Funktion mit string nichts anfangen kann, kannst du den string mit c_str() in einen C-String umwandeln.
--
Gruß
predator
Zitat von Edsger W. Dijkstra:
Es ist praktisch unmöglich, einem Studenten gutes Programmieren beizubringen, wenn er vorher in BASIC programmiert hat. Als potenzielle Programmierer sind sie geistig verstümmelt ohne Hoffnung auf Erholung.

Dieser Post wurde am 14.09.2005 um 17:12 Uhr von predator editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
15.09.2005, 08:30 Uhr
Airdamn



Arrays werden automatisch per Referenz an Funktionen/Methoden übergeben, von daher kriegst das nicht hin eine Funktion by Value aufzurufen, sodass sie mit ner Kopie arbeitet.
Da muss man schon selber kopieren.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
18.09.2005, 21:28 Uhr
~f.-th.
Gast


hallo
ich hoffe so funktionierts in farbe(getestet mit free bcc 5.5)

C++:
// MASTERMIND
#include <iostream>
#include <stdlib.h>
#include <windows.h> //Wird für die Farben benötigt
#include <time.h> //Wird für Zufallsgenerator benötigt

//Farbdefinition
#define BLAU        9
#define TUERKIS     11
#define GRUEN       10
#define ROT          4
#define GELB        14
#define HELLGRAU     7
#define DUNKELGRAU   8
#define WEISS       15
#define MAX_RUNDEN   17
#define ANZ_FELDER    5

const unsigned char BB = static_cast<unsigned char>( 157 );

using namespace std;
//---------
void textcolor( WORD color )           //Funktion fuer Farbe
{
    SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), color );
}
//  wenn einmal im quelltext 'textcolor' dann um sichere ergebnisse zu haben
//  vor jedem 'cout' 'textcolor' oder sehr ausgiebig testen!
//---------

void zufall( int* ); // zieht zufällig Zahlen für Array von Spielfeld
int zug( int[][5], int*, int* ); // Zug-Funktion
int istVorhanden( int feld[ANZ_FELDER], int* pSuche );

int main()
{
    int eingabe[MAX_RUNDEN][ANZ_FELDER];
    int spielfeld[ANZ_FELDER];
    int runde = 1, sieg = 0;

    //Zufallfunktion
    zufall( spielfeld );
    
    do
    {
        sieg = zug( eingabe, spielfeld, &runde ); // sieg ist Anzahl richtiger Felder
        textcolor( HELLGRAU );
        cout << "\n------------------------------------------------------------\n";
        ++runde;
    }while( sieg < 5 && runde < MAX_RUNDEN );
    
    system( "PAUSE" );
        
    return 0;
}

void zufall( int* pspielfeld )
{
    srand((unsigned)time( NULL ));
    
    for( int i = 0; i < 5; ++i )
    {
        pspielfeld[i] = rand() % 6 + 1;
    }
}

int zug( int eingabe[][ANZ_FELDER], int* pSpielfeld, int* pRunde )
{
    int i, n;
    
    cout << "(1) blau\n";
    cout << "(2) tuerkis\n";
    cout << "(3) gruen\n";
    cout << "(4) rot\n";
    cout << "(5) gelb\n";
    cout << "(6) dunkelgrau\n";
    cout << "(7) weiss\n";
    
    for( i = 0; i < ANZ_FELDER; ++i )
    {
        cout << "Bitte waehlen Sie aus, welche Farbe Sie ins " << i+1 <<". Feld setzen moechten:\n";
        cin >> eingabe[*pRunde][i];
    }
    
    cout << "\n--------------------------------------------------------------\n";
    cout << "RUNDE: "<< *pRunde <<" - Sie haben folgende Steine gesetzt:\n";
    
    for( i = 0; i < ANZ_FELDER; ++i )
    {
        switch( eingabe[*pRunde][i] )
        {
        case 1:
            {
                textcolor( BLAU );
                break;
            }
        case 2:
            {
                textcolor( TUERKIS );
                break;
            }
        case 3:
            {
                textcolor( GRUEN );
                break;
            }
        case 4:
            {
                textcolor( ROT );
                break;
            }
        case 5:
            {
                textcolor( GELB );
                break;
            }
        case 6:
            {
                textcolor( DUNKELGRAU );
                break;
            }
        case 7:
            {
                textcolor( WEISS );
                break;
            }
        default:
                textcolor( HELLGRAU );
        }
        
        cout << BB << "\t";
    }
    
    textcolor( HELLGRAU );
    int tmp[ANZ_FELDER];
    string sResult;
    memcpy( tmp, pSpielfeld, sizeof( tmp ));
        
    // AUSWERTUNG
    // die 'x' werden vorn gesetzt und die 'o' hinten angehängt
    // sonst ist evtl. ja klar welche Zahl richtig war und welche nicht
    for( i = 0, n = 0; i < ANZ_FELDER; ++i )
    {
        if( tmp[i] == eingabe[*pRunde][i] )
        {
            tmp[i] = -1;
            sResult += 'x';
            ++n;
        }
    }
    
    int nPos = -1;
    
    // Jede Zahl wird nur einmal verglichen -> eingabe 12345 zufallszahlen 11111 = 1 mal ein 'o'
    for( i = 0; i < ANZ_FELDER; ++i )
    {
        nPos = istVorhanden( tmp, &eingabe[*pRunde][i] );
    
        if( nPos >= 0 )
        {
            tmp[nPos] = -1;
            sResult += 'o';
        }
    }
    
    cout << sResult.c_str() << endl;

    textcolor( HELLGRAU );  // dieser eintrag muss sein sonst teilw. farbe wie 1. ziffer
    for( i = 0; i < ANZ_FELDER; ++i )
    {
        cout << pSpielfeld[i];
    }
    
    return n;
}

int istVorhanden( int feld[ANZ_FELDER], int* pSuche )
{
    for( int i = 0; i < ANZ_FELDER; ++i )
    {
        if( feld[i] == *pSuche )
            return i;
    }
    
    return -1;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


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: