Hoelzchenspiel KI

Hallo,
und zwar hab ich das "Hoelzchenspiel" programmiert, kennen bestimmt die meisten hier für die die nicht wissen was ich meine:
Man hat 15 Hölzchen und kann wählen ob man 1,2 oder 3 Hölzchen ziehen möchte und dann is der andere dran und wer das letzte Hölzchen gezogen hat verliert...
und nun hab ich 2 fragen also
1.) in der Funktion KI( ) hab ich versucht eine kleine "KI" einzubauen, wie kann ich diese noch verbessern?
2.) könntet ihr euch mal den quelltext durchlesen und mir vielleicht ein paar typs geben wie ich das ganze besser programmieren könnte?
Danke schonmal im Vorraus
mfg Virus

Code:
#include <cstdlib>
#include <iostream>

using namespace std;
int spieler( int uebrig );
int computer( int uebrig2 );
bool anfaenger();
int KI( int abc );
int ziehen;
bool flag, loose=false; // flag true = spieler || flag false = computer

int main(int argc, char *argv[])
{
    int hoelzer=15;
    cout << "Hallo, Das Spiel beginnt..." << endl;
    system("pause");
    cout << endl;
    flag=anfaenger();
    while (!(loose==true)) {
    if (flag == true) {
    cout << "#####################################################################" << endl;
    if (hoelzer < 1) {
                         cout << "ENDE.." << endl;
                         system("pause");
                         return 0;
                         }
    hoelzer = spieler( hoelzer );
    }
    else if ( flag == false) {
    cout << "#####################################################################" << endl;
    if (hoelzer < 1) {
                         cout << "ENDE.." << endl;
                         system("pause");
                         return 0;
                         }
    hoelzer = computer( hoelzer );
    } 
    }
    system("pause"); 
    return 0;
}


int spieler( int uebrig ) {

    cout << "Sie sind am Zug, Es sind noch " << uebrig << " Hoelzer uebring!" << endl;
    cout << "Wieviele Hoelzer moechten sie ziehen? ";
    if (!(cin >> ziehen) || ziehen > 3 || ziehen < 1) {
             cout << endl << "FEHLER Bitte nur [1], [2] oder [3] eingeben!" << endl << endl;
             spieler( uebrig );
             }
    cout << endl << endl;
    uebrig = (uebrig - ziehen);
    flag = false;
    if ( uebrig < 1 ) {
                cout << "Sie haben verloren..." << endl << endl;
                loose=true;
                return uebrig;
                }
    return uebrig;
}

int computer ( int uebrig2 ) {
    cout << "Der Computer ist am Zug, Es sind noch " << uebrig2 << " Hoelzer uebring!" << endl;
    KI(uebrig2);
    uebrig2 = (uebrig2 - ziehen);
    system("pause");
    cout << "Die Auswahl des Computers ist: ";
    cout << ziehen << endl << endl;
    flag = true;
    if (uebrig2 < 1 ) {
                cout << "Der Computer hat verloren, Glückwunsch! " << endl;
                loose=true;
                return uebrig2;
                }
    return uebrig2;
}
    
int KI (int abc) {
    switch ( abc ) {
    case 15: {
         ziehen = 2;
         break;
         }
    case 14: {
         ziehen = 1;
         break;
         }
    case 13: {
         ziehen = 3;
         break;
         }
    case 12: {
         ziehen = 3;
         break;
         }
    case 11: {
         ziehen = 2;
         break;
         }
    case 10: {
         ziehen = 1;
         break;
         }
    case 9: {
         ziehen = 3;
         break;
         }
    case 8: {
         ziehen = 3;
         break;
         }
    case 7: {
         ziehen = 2;
         break;
         }
    case 6: {
         ziehen = 1;
         break; 
         }
    case 5: {
         ziehen = 1;
         break;
         }
    case 4: {
         ziehen = 3;
         break;
         }
    case 3: {
         ziehen = 2;
         break;
         }
    case 2: {
         ziehen = 1;
         break;
         }
    case 1: {
         ziehen = 1;
         break;
         }
    default : {
            srand(time(NULL));
            do {
               ziehen = rand()%4;
               }
            while ( ziehen == 0 );
            } 
}           
    return ziehen;
}

bool anfaenger() {
     int anfang;
     do {
     srand(time(NULL));
     anfang = rand()%3;
     }
     while ( anfang == 2 );
     if ( anfang == 0) {
          return true;
          }
     else if ( anfang == 1) {
             return false;
             }
     else {
          cout << "FEHLER!";
          }
}
 
Man soll "srand(time(NULL));" nur einmal am anfang des Programms aufrufen, da es sonst passieren kann, dass der zufallsgenerator mehrmal identisch initialisiert wird und damit auch die selben pseudo-zufallszahlen produziert.

Code:
do {
               ziehen = rand()%4;
               }
            while ( ziehen == 0 );
ließe sich zu "ziehen = 1 + rand()%3;" zusammenfassen, was sauberer und zudem auch eine bessere laufzeit hat
und "anfaenger()" ist ja wohl nen schlechter scherz, oder!? (es würde ein "return(rand()%2 == 0);" reichen...)

zudem ist dein default etwas überflüssig ;)
Von ki zu sprechen ist auch schon... zweifelhaft. Im übrigen reicht es, dass dein programm versucht auf (1+4n) stäbchen zu kommen. da bedarf es keiner so großen switchanweisung (die sich auch im aktueller form zusammen fassen ließe.)
 
mhm, yo hast schon recht aber ich prog auch noch net lang c++
und dass ich des alles net so kurz schreib hängt auch viel mit der übersichtlichkeit zusammen, aber schonma danke für die tipps...
mfg virus
 
Bei einem Programm von keinen 50 Zeilen ist es unnötig und umständlich alles auf Funktionen ausfzuspalten. Globale Variablen sind auch schlechter Stil.
Wenn du willst kann ich dir das Programm mal umschreiben, aber es wäre besser wenn du es erstmal selbst versuchst. Kannst es ja nochmal posten wenn du es hast, oder wenn es noch Fragen gibt ;)
 
yop also ich versuchs morgen oder übermorgen mal.. hab heut keine zeit mehr und morgen könnts auch knapp werden
mfg virus
 
Ich habe Dir einen Lösungsvorschlag - ist zwar in Blitz, aber Prinzipiell gehts ja um den Umgang mit den Variablen:

Code:
.start
holz=15
a$=Input$("Wer Beginnt? (c)omputer - (m)ensch?")
If a$="c" Goto computer
If a$="m" Goto mensch
Goto start

.computer

If holz=1 Then Print "Ich habe verloren, da ich ziehen muss":Goto ende
zug=((holz Mod 4)-1)

If (holz Mod 4)<1 Then zug=2
If holz<5 Then zug=(holz-1)
If zug=0 Then zug=1
holz=holz-zug
Print "ich nehme "+zug+" Hölzer - Rest:"+holz
If holz=1 Then Print "Ich habe gewonnen - Rest 1":Goto ende

.mensch
Print "hölzer="+holz
.abfr
c=Input$("wieviele Hölzer ziehen?:")
If c<1 Or c>3 Then Goto abfr
holz=holz-c
Print "Resthölzer:"+holz
Goto computer

.ende
Print "ende"
WaitKey()
End

Anm: Mod=Modulo - der Rest sollte klar.
Habe ne komp. .exe Angehängt, wenn der Computer startet verlierst Du leider ;)

Achja bevor ich es vergesse - i am back :D
 
Mein Weg in C++ ist etwas anders. Zudem ist goto (zumindest in C/C++) zu meiden ;)
Ich kenn das Spiel im übrigen, dass eine zufällige Anzahl Hölzchen da liegen, denn bei 15 gewinnt immer (entsprechendes wissen vorausgesetzt) immer der, der anfängt.
Code:
#include <cstdlib>
#include <iostream>

using namespace std;

int main()
{
	srand(time(0));
	int hoelzer = 13 + rand()%5, in; // start mit 13/17 (niederlage) 14/15/16 (sieg)
	bool ki = rand()%2; // wer faengt an? 3/5 siegchancen

	while (hoelzer) {
		cout << "Es sind noch " << hoelzer << " Hoelzer uebrig." << endl;
		if (ki) {
			in = (hoelzer - 1)%4; // was muss genommen werden um auf 1+4n hoelzer zu kommen
			if (in < 1)
				/* Schlecht, da menschlicher Spieler gewinnen kann, wenn er aufpasst.
				   Wir nehmen dann x Hoelzchen, Spieler muss dann 4-x nehmen, sonst
				   hat er schon verloren, weiß es aber wahrscheinlich noch nicht ;) */
				in = 1 + rand()%3;
			cout << "Pc nimmt " << in << "." << endl;
			hoelzer -= in;
			if (hoelzer == 0)
				cout << "Sie haben gewonnen!" << endl;
		} else {
			cout << "Wieviele nehmen Sie? [1" << ((hoelzer > 1)?",2":"") << ((hoelzer > 2)?",3":"") << "] " << flush;
			do
				cin >> in;
			while (in < 1 || in > 3 || in > hoelzer);
			cout << "Sie nehmen " << in << "." << endl;
			hoelzer -= in;
			if (hoelzer == 0)
				cout << "Sie haben verloren!" << endl;
		}
		ki = !ki;
	}
}
 
1. macht es überhaupt sinn ein programm für ein spiel zu schreiben, dessen ausgang vorbestimmt ist?
2. die ki-funktion hätte ich nicht mit case, sondern mit einer termberechnung gemacht, da es ja eine ideale strategie für das spiel gibt.

oder geht es nur um fingerübungen zum programmieren?
 
Hallo!

Noch ein kleiner Tipp...
die Formel ist nicht sonderlich lang und auch nicht komplex, nimm dir einen Zettel und einen Stift und spiel es in Gedanken durch.

Es gibt Stellen, wenn du auf die kommst, kannst du nur gewinnen, du darfst diese Stellen natürlich nicht wieder verlieren...

Gruß
Felix
 
Zurück
Oben