Reversi Beta
-
hy
ich hab für mein Schule das Spiel Reversi OOP dies wir d als pratisches Leistung bewertet für mein abschluss. Ich kann euch leider nichts zhalen da ich armer Schüler bin. Wer aber trozdem schön wenn ihr des Spiel testen würdet.
Ich danke euch schon mal im vorraus.#include <iostream.h> #include <fstream> #include <conio.h> #include <time.h> #include <stdio.h> #include <iomanip.h> #include <windows.h> bool rand(int,int,int,int); int steinsucheminus(int feldf[], int d , int e,int w,int gw); int steinsucheplus(int feldf[] ,int d ,int e ,int w ,int gw); class Reversi { private: int feld[64]; bool wer_ist_dran ; bool gewiner ; ifstream hilfe; public: Reversi(); bool checksetze(int stelle, string richtung); void setze(int stelle, string richtung); void gewinner(void); bool spielende(void); void aenderwer_ist_dran(); void ausgabehilfe(void); void ausgabezeichenSpielfeld(void); void ausgabe_wer_ist_dran(void); void ausgabepassen(void); void ausgabegewinner(void); }; Reversi::Reversi() { for(int i=0;i<65;i++) { feld[i]=i+1; } hilfe.open("hilfe.txt") ; //------standard einstellung feld[27]=66; feld[28]=66; feld[35]=99; feld[36]=99; randomize() ; wer_ist_dran=rand()%2; hilfe.open("Regeln.txt"); } void Reversi::aenderwer_ist_dran() { if(wer_ist_dran==true) { wer_ist_dran=false; } else { wer_ist_dran=true; } } bool Reversi::spielende(void) { int i=0, moeglichkeiten=1, besetzt=0; bool erg; for(i;i<64;i++) { if(feld[i]!=99|feld[i]!=66) { erg=this->checksetze(i,"N"); if(erg==true) moeglichkeiten++; erg=this->checksetze(i,"NO"); if(erg==true) moeglichkeiten++; erg=this->checksetze(i,"O"); if(erg==true) moeglichkeiten++; erg=this->checksetze(i,"SO"); if(erg==true) moeglichkeiten++; erg=this->checksetze(i,"S"); if(erg==true) moeglichkeiten++; erg=this->checksetze(i,"SW"); if(erg==true) moeglichkeiten++; erg=this->checksetze(i,"W"); if(erg==true) moeglichkeiten++; erg=this->checksetze(i,"NW"); if(erg==true) moeglichkeiten++; } if(feld[i]==99|feld[i]==66) { besetzt=besetzt+1; } } if(besetzt==63) { this->gewinner(); } else if(moeglichkeiten>1) { return true; } else { this->ausgabepassen();; } return false ; } bool Reversi::checksetze(int stelle, string richtung) { int a=0, Gestein=0, dran=0, gegner=0; bool erg; //------Umwandlung von string in int für switch/case Anweisung if(richtung=="N") a=1; if(richtung=="NO") a=2; if(richtung=="O") a=3; if(richtung=="SO") a=4; if(richtung=="S") a=5; if(richtung=="SW") a=6; if(richtung=="W") a=7; if(richtung=="NW") a=8; if(a==0) return false ; if(wer_ist_dran==true) { dran=66 ; gegner=99; } else { dran=99; gegner=66; } if(feld[stelle]==66) return false ; if(feld[stelle]==99) return false ; switch(a) { case 1: // N if(stelle>15) // horizontaler Rand 1-16 { stelle=stelle-8; Gestein=steinsucheminus(feld,stelle,8,gegner,dran); if(Gestein<=0) return false; if(Gestein==stelle) return false ; return true; } else return false; case 2:// N0 erg=rand(8,stelle,8,72);// vertiakler Rand 8,16,24,32,40,48,56,64 if(erg==true) if(stelle>7)// horizontaler Rand 1-8 { stelle=stelle-7; Gestein=steinsucheminus(feld,stelle,7,gegner,dran); if(Gestein<=0) return false; if(Gestein==stelle) return false ; return true; } return false; case 3: // O erg=rand(8,stelle,8,72); // vertiakler Rand 8,16,24,32,40,48,56,64 if(erg==true) { stelle=stelle+1; Gestein=steinsucheplus(feld,stelle,1,gegner,dran); if(Gestein<=0) return false; if(Gestein==stelle) return false ; return true; } return false; case 4: // so erg=rand(8,stelle,8,72); // vertiakler Rand 8,16,24,32,40,48,56,64 if(erg==true) if(stelle<56)// horizontaler Rand 57-64 { stelle=stelle+9; Gestein=steinsucheplus(feld,stelle,9,gegner,dran); if(Gestein<=0) return false; if(Gestein==stelle) return false ; return true; } return false; case 5: // s if(stelle<48)// horizontaler Rand 49-64 { stelle=stelle+8; Gestein=steinsucheplus(feld,stelle,8,gegner,dran); if(Gestein<=0) return false; if(Gestein==stelle) return false ; return true; } return false; case 6: // SW erg=rand(1,stelle,8,65); // vertiakler Rand 1,9,17,25,33,41,49,57 if(erg==true) if(stelle>15) // horizontaler Rand 1-16 { stelle=stelle+7; Gestein=steinsucheplus(feld,stelle,7,gegner,dran); if(Gestein<=0) return false; if(Gestein==stelle) return false; return true; } return false; case 7: // W if(stelle<48) // horizontaler Rand 49-64 { stelle=stelle-1; Gestein=steinsucheminus(feld,stelle,1,gegner,dran); if(Gestein<=0) return false; if(Gestein==stelle) return false; return true; } return false; case 8:// NW erg=rand(1,stelle,8,65); // vertiakler Rand 1,9,17,25,33,41,49,57 if(erg==true) if(stelle>7) //horizontaler Rand 1-8 if(erg==true) { stelle=stelle-9 ; Gestein=steinsucheminus(feld,stelle,9,gegner,dran); if(Gestein<=0) return false; if(Gestein==stelle) return false ; return true; } } return false; } void Reversi::setze(int stelle, string richtung) { int a=0, dran=0, gegner=0; bool erg; //------Umwandlung von string in int für switch/case Anweisung if(richtung=="N") a=1; if(richtung=="NO") a=2; if(richtung=="O") a=3; if(richtung=="SO") a=4; if(richtung=="S") a=5; if(richtung=="SW") a=6; if(richtung=="W") a=7; if(richtung=="NW") a=8; if(wer_ist_dran==true) { dran=66; gegner=99; } else { dran=99; gegner=66; } switch(a) { case 1: // N feld[stelle]=dran; if(feld[stelle-8]==gegner) this->setze(stelle-8,"N"); break; case 2: // NO feld[stelle]=dran; if(feld[stelle-7]==gegner) this->setze(stelle-7,"NO"); break; case 3: // 0 feld[stelle]=dran; if(feld[stelle+1]==gegner) this->setze(stelle+1,"O"); break; case 4: // SO feld[stelle]=dran; if(feld[stelle+9]==gegner) this->setze(stelle+9,"SO"); break; case 5: // S feld[stelle]=dran; if(feld[stelle+8]==gegner) this->setze(stelle+8,"S"); break; case 6: // SW feld[stelle]=dran; if(feld[stelle+7]==gegner) this->setze(stelle+7,"SW"); break; case 7: // W feld[stelle]=dran; if(feld[stelle-1]==gegner) this->setze(stelle-1,"O"); break; case 8: // NW feld[stelle]=dran; if(feld[stelle-9]==gegner) this->setze(stelle-9,"NW"); } } void Reversi::gewinner() { int Spieler1=0 , Spieler2=0; for(int d=0;d<64;d++) { if(feld[d]==66) { Spieler1++ ; } if(feld[d]==99) { Spieler2++ ; } } if(Spieler1>Spieler2) { gewiner=true; } else { gewiner=false; } } //------------------------------------------------------Ausgabe Methoden ab hier------------------------------------------------------------------ void Reversi::ausgabegewinner() { if(gewiner=true) { cout << endl << "Spieler1 hat gewonnen"; } else { cout << endl << "Spieler2 hat gewonnen"; } } void Reversi::ausgabehilfe() { char a; clrscr(); if(hilfe==0) { cout << " Konnte Datein nicht öffnen!" << endl; } else { while(!hilfe.eof()) { hilfe.get(a); cout << a ; } cout << endl << "Bei Tasten druch zurueck ins Spiel" ; gotoxy(1,1); getch(); getch(); getch(); clrscr(); } hilfe.close(); hilfe.open("Regeln.txt"); } void Reversi::ausgabepassen() { if(wer_ist_dran==true) { cout << endl << "Spieler 1 muss passen" ; wer_ist_dran=false; } else { cout << endl << "Spieler 2 muss passen"; wer_ist_dran=true; } cout << endl << "Bei Tasten druck geht es weiter"; getch(); } void Reversi::ausgabezeichenSpielfeld() { int g=0, a=0 ; clrscr(); for(a=0;a<64;a++) { if(g==8) { g=0; cout << endl ; } switch(feld[a]) { case 66 : cout<< setw(3); cout << "X" ; break; case 99 : cout<< setw(3); cout << "O" ; break; default: cout<< setw(3); cout << feld[a]; } g++; } cout<< endl; cout<< endl; } void Reversi::ausgabe_wer_ist_dran(void) { if(wer_ist_dran==true) { cout << "Spieler1 ist dran" ; } else { cout << "spieler2 ist dran" ; ; } cout << endl << "Bei druecken von F1 erscheint die Hilfe." ; cout << endl<< "Auf welche Stelle soll gesetzt werden ? : "; } //-------------------------------------------Hauptprogramm--------------------------------------------------------------------------- void main(void) { Reversi b; int wert1=1 , a=0 , i=0; bool erg=false; int stell=0, wert=1; string richtun="Nix"; short KeyState = 0; cout << "Reversi das Spiel " << endl ; cout << "Spieler1 ist X " << endl; cout << "Spieler2 ist 0" << endl; cout << "Bei Tasten druck geht es los "; getch(); do { stell=0; short ArrKeyState[256]={0}; KeyState = 0; b.ausgabezeichenSpielfeld(); b.ausgabe_wer_ist_dran(); erg=b.spielende(); if(erg==true) // überprüfung ob Spieler setzen kann { while (wert<2) { for (i = 0; i < 256; i++) // Abprüfen der Gesammtentastertur { KeyState = GetAsyncKeyState(i); ArrKeyState[i] = KeyState; } if(kbhit()) { if (ArrKeyState[112]==-32767) // Überprüfen ob F1 gedrückt wurde { b.ausgabehilfe(); wert=2; } else { for (a = 48; a <58 ; a++) { if(ArrKeyState[a]!=0) { wert=2; wert1=3; i=59; } } } } } if(wert1==3) { cin>>stell; cout << endl << "Welche Richtung ?"; cin >> richtun ; erg=b.checksetze(stell-1, richtun); if(erg==true) { b.setze(stell-1,richtun); wert=1; wert1=1; erg=false; b.aenderwer_ist_dran(); } else // wenn sezten der sonst eingabe nich in ordnung war { cout << endl <<" Spielzug oder eingabe nicht zulaessig" <<endl; cout << "Bei Tasten druck geht es weiter "; getch(); wert=1; wert1=1; } } else //wenn hilfe ausgegeben wurde trifft dieser fall ein { wert=1; } } else { b.ausgabegewinner(); } } while(wert1<2); getch(); } bool rand( int c, int b,int plus, int abbruch) { bool erg; if(c==b) // wenn die stelle am rand leigt dan diese anweisung return false ; if(c==abbruch) //wenn die stelle nicht am rand liegt return true ; rand(c+plus,b,plus,abbruch); } int steinsucheminus(int feldf[], int d , int e,int w,int gw) { if(feldf[d]!=w) { if(feldf[d]==gw) { return d; } else return 0; } if(d<=0) return 0 ; steinsucheminus(feldf,d-e,e,w,gw); } int steinsucheplus(int feldf[] ,int d ,int e ,int w ,int gw) { if(feldf[d]!=w) { if(feldf[d]==gw) return d; else return 0; } if(d<=0) return 0 ; steinsucheplus(feldf,d+e,e,w,gw); }
-
habs net getestet, aber net immer if(richung== blabla) verwenden sondern if, else if... . Sonst werden alle fälle unnötigerweise durchprobiert
-
ist vlt nicht so wichtig,
aber#include <iostream.h>
und
void main()
muss nicht sein
edit
// Abprüfen der Gesammtentastertur
die rechtschreibung, das heißt tastatur
und da es sich um keinen satz handelt, ist es fraglich warum du prüfen groß schreibst
ich meine eigentlich sind die kommentare ja egal, aber das muss nicht sein, wenn du das abgeben willst
-
steff3 schrieb:
und da es sich um keinen satz handelt, ist es fraglich warum du prüfen groß schreibst
Das Abprüfen -> substantiviertes Verb -> groß.
Scheiße würde es doch aussehen wenns klein geschrieben wäre:
// abprüfen der Tastatur
--> wer prüft hier ab??? blöd. Außerdem könnte es man so nie korrekt stehen lassen. denn sobald jemand prüft, tut er nicht abprüfen sondern er prüft ab.
--> XY prüft die Tastatur ab
--> blöd.
aber:
// Abprüfen der Tastatur
--> das beschreibt kompakt und korrekt einen Vorgang.
-
Da kann man einiges noch in Funktionen auslagern. Das macht den Code sehr viel kompakter. Solche Copy & Paste-Orgien sollte man sich erst garnicht angewöhnen.
-
zunächst einmal benutzt du hier veraltete header. eine anpassung ist notwendig, damit überhaupt mehr als eine handvoll leute hier etwas testen kann. einfach mal ins passende forum schauen http://www.c-plusplus.net/forum/viewtopic-var-t-is-131915.html
die anpassung ist relativ problemlos - im wesentlichenm die .h header durch die endungslose variante ersetzen (der <string> header fehlte noch). using namespace, so wie gebraucht.class Reversi { private: int feld[64]; bool wer_ist_dran ; bool gewiner ; ifstream hilfe; public: Reversi(); bool checksetze(int stelle, string richtung); void setze(int stelle, string richtung); void gewinner(void); bool spielende(void); void aenderwer_ist_dran(); void ausgabehilfe(void); void ausgabezeichenSpielfeld(void); void ausgabe_wer_ist_dran(void); void ausgabepassen(void); void ausgabegewinner(void); };
die wahl der bezeichner ist ein bißchen eigenwillig und uneinheitlich. void in leeren parameterlisten ist ein anachronismus. was mich allerdings stört, ist feld - ich hätte hier eher eine zweidimensionale variante erwartet. das eigentliche problem ist allerdings der datentyp, und wie damit umgegangen wird (stichwort magische konstanten) - was spricht gegen ein einfaches enum mit unbesetzt, spieler1, spieler2 o.ä.? gewinner schreibt sich mit 2 n
ein ifstream als member halte ich nicht unbedingt für günstig (nicht kopierbar)- gemessen daran, wofür er verwendet wird.void main() wurde erwähnt
ifs der form if(irgendwas==true) sind ... immer ein grund, sie zu erwähnen, dabei hat sich im übrigen ein fehler in ausgabegewinner() eingeschlichen.
in der rand funktion fehlt offenbar ein return (nebenbei: die namenswahl kollierdiert u.U. mit std::rand, das ist zumindest unschön). gleiches gilt für die steinsuche funktionen.
in bool Reversi::spielende(void) haben wir ein for(i;i<64;i++)
i hier nochmal einzeln zu erwähnen ohne es zu initialisieren ist sinnlos. generell: variablen erst definieren, wenn sie gebraucht werden und dann gleich initialisieren. erst alles zu definieren war in C++ noch nie und C schon lange nicht mehr guter stil (bzw. in C notwendigkeit).beim spiel habe ich keine ahnung, was ich eingeben soll - bei dem reversi, das ich kenne, legt man einen zielpunkt fest, und das wars. genügt das nicht?
ansonsten schließe ich mich meinen vorrednern an - copy&paste-stil ist nie gut. und eine analyse der eigentlichen spiel-funktion ist das auch noch nicht.
-
Black Shadow schrieb:
steff3 schrieb:
und da es sich um keinen satz handelt, ist es fraglich warum du prüfen groß schreibst
Das Abprüfen -> substantiviertes Verb -> groß.
Scheiße würde es doch aussehen wenns klein geschrieben wäre:
// abprüfen der Tastatur
--> wer prüft hier ab??? blöd. Außerdem könnte es man so nie korrekt stehen lassen. denn sobald jemand prüft, tut er nicht abprüfen sondern er prüft ab.
--> XY prüft die Tastatur ab
--> blöd.
aber:
// Abprüfen der Tastatur
--> das beschreibt kompakt und korrekt einen Vorgang.ich habe von prüfen gesprochen, weil ich der meinung bin das abprüfen kein richtiges deutsch ist und wenn ich nach dem wort suche erhalte ich auch ganze
48 0000 treffer, bei prüfen sind es 31.600.000 treffer
-
Hy
so erst mal danke für eure Vorschläge.
Ich hab euch nicht alles über mein Schulprojekt gesagt, Bitte nicht böse sein.
Also ich musste für das Spiel schon ein Umldiagramm mit Erklärung abgeben. Ich sollte eigentlich meinem Umldigramm treu bleiben, natürlich ist jetzt die Frage bleib ich treu oder mach ich es richtig. Ich denk richtig machen ist besser weil man ja den Fehler da noch indeckt hat. So geb ich euch mal die Beschreibung meines Umldiagramm. Und die Hilfe
.
Reversi
-feld[65]:int
-wer_ist_dran:bool
-gewinner:bool
-hilfe: ifstreamOperations:
+Reversi()
Intialisiert das Spielfeld Array mit den Zahlen von 1- 64.
Die Stelle 27 und 28 im Array werden mit der Zahl 66 überschrieben.
Die Stelle 35 und 36 im Array werden mit der Zahl 99 überschrieben.hilfe wird Datei "Hilfe.txt" zu gewiesen.
Wer_ist_dran wird durch Zufall bestimmt.
true = Spieler1
flase = Spieler2+ausgabehilfe(): void
Gibt die Hilfe aus.bei Tastendruck zurück zum Spiel
+ausgabezeichneSpielfeld(): void
Bildschrim wird gelöscht.Ausgabe des Spielfeldes in folgender Form
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 X X 30 31 32
33 34 35 O O 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64Beispiel für Aktion der Spieler
Nach dem setzen Spieler 1 auf Feld 45
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 X X 30 31 32
33 34 35 O X 38 39 40
41 42 43 44 X 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64Nach dem setzen Spieler 2 auf Feld 38
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 X X 30 31 32
33 34 35 O O O 39 40
41 42 43 44 X 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64+ ausgabe_wer_ist_dran(): void
Die Methode gibt aus- wer dran ist
- auf welches Feld gesetzt werden soll
- Bei drücken von F1 erscheint die Hilfe
+ checksetze(stelle: int, richtung: string): bool
Überprüfung ob das Setzen des Steines und die Richtung zulässig sind.
Rückgabewert für
zulässig = true
unzulässig = false+ setze(stelle: int, richtung: string): void
Methode wird gestartet wenn Rückgabewert von checksetze true ist.
Im Array wird der Stein vermerkt.
Wenn nötig werden Steine umgedreht
Für die Steine von Spieler 1 wird die Zahl 66 benutzt
für Spieler 2 die 99+ ausgabe_wer_ist_dran(): void
Die Methode gibt aus
- wer dran ist
- auf welches Feld gesetzt werden soll
- Bei drücken von F1 erscheint die Hilfe
+ checksetze(stelle: int, richtung: string): bool
Überprüfung ob das Setzen des Steines und die Richtung zulässig sind.
Rückgabewert für
zulässig = true
unzulässig = false+ setze(stelle: int, richtung: string): void
Methode wird gestartet wenn Rückgabewert von checksetze true ist.
Im Array wird der Stein vermerkt.
Wenn nötig werden Steine umgedreht
Für die Steine von Spieler 1 wird die Zahl 66 benutzt
für Spieler 2 die 99+ spielende(): bool
Überprüfung ob es noch Felder frei sind.
Überprüfung ob der Spieler der dran kommt noch setzen kann.
Bei Spielende wir Methode gewinner aufgerufen
Wenn der Spieler nicht setzen kann, dann Aufruf der Methode ausgabepassen+ gewinner(): void
Überprüfung wer gewonnen hat
setze das Attribut "gewinner" auf :
Spieler 1 = true
Spieler 2 = false+ ausgabepassen(): void
Gibt aus, dass der Spieler der dran ist passen muss.+ ausgabegewinner(): void
Gibt aus wer gewonnen hat.//................................Hilfe.txt....................................
Spielregeln zu Reversi:Spieler1 ist X
Spieler2 ist 0Einschliessen:
Nun setzt jeder Spieler abwechselnd nur noch einen Stein, und zwar muss er
diesen so setzen, dass er einen oder mehrere in einer geraden,
zusammenhaengenden Reihe liegende Steine des Gegners einschliesst. Dies
kann nach jeder beliebigen Seite geschehen in senkrechter, waagrechter oder
diagonaler Richtung. Die von 2 Steinen seiner Zeichen eingeschlossenen
gegnerischen Steine darf man umdrehen und dadurch zu Steinen seiner eigenen
Zeichen machen. Die gewonnenen Steine werden also nicht vom Plan genommen,
sondern sie bleiben umgedreht liegen. Wird ein Stein gesetzt,der gleichzeitig
mehrere gegnerische Reihen schliesst, so duerfen nur die Steine einer Reihe
umgedreht und zu Steinen eigener Zeichen gemacht werden. Deshalb geben sie
die Richtung wie folgte ein, N ist immer oben am Bildschirm.NW N NO
W Stein O
SW S SO
Im Laufe eines Spieles kann ein Stein seine Zeichen mehrmals wechseln. Wenn
ein Spieler keinen Stein seiner Zeichen so setzen kann, dass dieser
gegnerische Steine einschliesst, muss er passen, und der andere Spieler
kommt an die Reihe.Strategie im Spiel:
Es ist zu empfehlen, moeglichst rasch die Eckpunkte mit eigenen Steinen zu
besetzen und den Gegner am Besetzen dieser Positionen zu hindern.Spielende:
Das Spiel ist beendet, wenn alle 64 Felder belegt sind oder wenn mangels
Gelegenheit zum Einschliessen kein Stein mehr gesetzt werden kann. Wer nun
die meisten Steine seiner Zeichen auf dem Plan liegen hat, ist Sieger
-
hy
Ich mach zu zeit das 2 jahrige Berufskolleg für Kommunkiation- und Informationtechnik. Und also lerne ich seit 2 Jahre c++ und soviel haben wir auch nicht durch gemacht wie man was gut Programmiert und so große Projekte OOP noch nie.so mal zu euren vorschlägen die ich nicht verstehe.
-
"die wahl der bezeichner ist ein bißchen eigenwillig und uneinheitlich"
Was ist bezeichner ? -
magische konstanten
Ich was nicht was das ist, und in google find ich nichts -
if(irgendwas==true)
Und jetzt wurde mir so bei gebracht. -
die namenswahl kollierdiert u.U. mit std::rand, das ist zumindest unschön).
gleiches gilt für die steinsuche funktionen.
Ich vesthe nicht was du mit meinst nicht -
using namespace, so wie gebraucht.
Was meinst du ? -
Für was brauch ich den String header ?
-
der link funzt nicht mehr
Wenn die Fragen sich geklärt haben werde ich sie umsetzen und dan mein neue code posten.
-
-
steff3 schrieb:
ich habe von prüfen gesprochen, weil ich der meinung bin das abprüfen kein richtiges deutsch ist und wenn ich nach dem wort suche erhalte ich auch ganze
48 0000 treffer, bei prüfen sind es 31.600.000 treffer// prüfen der Tastatur
ist aber genauso falsch, da dieser Satz Prädikat + Objekt, aber kein Subjekt enthält.
Dagegen ist
// Prüfen der Tastatur
völlig korrekt, da es einen Vorgang beschreibt und es hier um DAS Prüfen geht.
MfG
-
MacGyver1929 schrieb:
Was ist bezeichner ?
Die Namen Deiner Variablen und Funktionen.
- if(irgendwas==true)
Und jetzt wurde mir so bei gebracht.
Dann war's ein schlechter Lehrer. Die Bedingung eines if hat den Typ Boolean, Deine Variable auch. Du vergleichst also irgendwas mit true und der Compiler vergleich das Ergebnis dieses Vergleiches mit true
doppelt gemoppelt (aber allein für den Tippaufwand würde ich mir die 6 Zeichen sparen)
if (irgendwas)
- using namespace, so wie gebraucht.
Was meinst du ?
Wenn Du die Header ohne .h einbindest, liegen alle Funktionen und Klassen im Namespace std (habt ihr in den zwei Jahren Namespaces nicht wenigstens mal erwähnt?) - Du musst z.B. cout mit std::cout qualifizieren oder den Namespace std durch "using namespace std;" verfügbar machen (aber nicht in Headerfiles!)
- Für was brauch ich den String header ?
Für die Klasse std::string
- if(irgendwas==true)
-
LordJaxom schrieb:
- using namespace, so wie gebraucht.
Was meinst du ?
Wenn Du die Header ohne .h einbindest, liegen alle Funktionen und Klassen im Namespace std (habt ihr in den zwei Jahren Namespaces nicht wenigstens mal erwähnt?) - Du musst z.B. cout mit std::cout qualifizieren oder den Namespace std durch "using namespace std;" verfügbar machen (aber nicht in Headerfiles!)
Vielleicht noch als Anmerkung: Du solltest die Header ohne .h einbinden, da die ohne h nicht standardisiert sind und genau genommen damit garkein gültiges C++ sind. Daß das auf einigen Compilern trotzdem noch funktioniert hat vor allem historische Gründe.
- using namespace, so wie gebraucht.
-
hy
-
die wahl der bezeichner ist ein bißchen eigenwillig und uneinheitlich.
Was genau meinst du damit. -
Namespace std
Nein haben wir nicht. Ich schau mal im Forum was des ist. -
#include<string.h>
Für was brauch ich den die wenn ich keinen Befehl habe der auf diesen Header
zurückgreift -
magische Konstante
hab raus gefunden was des ist -
Was ist der vorteil von einem 2 dimsonalen Array zu einem 1 dimsonalen Array .
(feld[64] vs feld[8][8]) -
die namenswahl kollierdiert u.U. mit std::rand, das ist zumindest unschön).
gleiches gilt für die steinsuche funktionen.
Ich verstehe nicht was du mit meinst nicht -
Da kann man einiges noch in Funktionen auslagern.
Wie viel soll ich den auslagern.
-
-
- die wahl der bezeichner ist ein bißchen eigenwillig und uneinheitlich.
Was genau meinst du damit.
einige namen sind gut gewählt, andere dagegen völlig nichtssagend - was is das a in checksetze() und was tut checksetze (das ist jetzt keine aufforderung mir das zu erklären, nur die feststellung, das sich das aus dem namen ganz und gar nicht ableiten lässt). oder was tut z.b. rand? - man kann noch vermuten, dass es irgendwas mit dem spielfeldrand zu tun hat, aber ein bisschen eindeutiger sollte es schon sein. gute namenfindung ist so ungefähr das schwierigste, wenn man programme entwickelt, und es werden viele kontrowerse diskussionen darüber geführt, deshalb nur ein paar tips:
- ein name sollte genauso heißen, wie das, was er bezeichnet; funktionen führen etwas aus, im regelfall sollten sie also eine tätigkeit bezeichnen, das ist in ansätzen schon da
- ein abkürzen bei sehr langen namen ist mitunter sinnvoll, aber ein einzelbuchstabe ist fast nie eine gute wahl (ein gelegentliches i,j in trivialen schleifen kann man sicher vertreten)
- ein einheitlicher stil; in deinem code verwendest du direkt zusammengeschriebenes (wie checksetze), mit unterstirchen (ausgabe_wer_ist_dran), gemischte groß-/kleinschreibung (ausgabezeichenSpielfeld), oder sogar mehrere dieser varianten zugleich (aenderwer_ist_dran)
(und bei allen diesen bezeichnern handelt es sich trotzdem nur um normale funktionen - es kann sinnvoll sein, verschiedene stile für verschiedene kategorien zu benutzen - z.b. ein stil für typen, ein anderer für variablen)
das erhöht definitv nicht die lesbarkeit.- #include<string.h>
Für was brauch ich den die wenn ich keinen Befehl habe der auf diesen Header
zurückgreift
den brauchst du nicht. was du benötigst, ist der header <string>. in diesem ist die definition der stringklasse enthalten.
- magische Konstante
hab raus gefunden was des ist
dann sollte auch klar sein, warum das schlecht ist. du magst wissen, was sich hinter 66 und 99 verbirgt - jemanden, der das zum ersten mal sieht, erschließt sich das aber überhaupt nicht. auch hier gilt es, einen guten bezeichenr zu finden, und dann diesen symbolischen namen zu verwenden. z.b.
const int stein_spieler1 = 66; const int stein_spieler1 = 99;
das ist nicht unbedingt eine gute namenswahl, sondern nur zur demonstration.
- Was ist der vorteil von einem 2 dimsonalen Array zu einem 1 dimsonalen Array .
(feld[64] vs feld[8][8])
kein prinzipieller (und dem compiler ist es sowieso egal). allerdings reflektiert feld ein 2dimensionales spielbrett, und es ist erfahrungsgemäß einfacher, mit koordinaten, als mit durchnummerierten feldnummern zu arbeiten. günstig wäre auch hier, zahlen durch symbolische konstanten zu ersetzen - im prinzip könnte man reversi auch auf einem 10*10 oder einem 8*12 spielbrett spielen. versteckt man diese hinter konstanten, so ist es leichter, die eigentliche spiellogik von diesen randbedingungen zu trennen. all das lässt sich auch mit einem eindimensionalen array erreichen, in meinen augen ist es eben nur ein bisschen umständlicher. was mir allerdings wirklich nicht gefällt, ist der elementtyp des arrays. es gibt ja, wie erwähnt, für jedes einzelne spielfeld nur 3 mögliche zustände: unbesetzt,besetzt von spieler1, besetzt von spieler2. in deinem fall siehht das anders aus, die bestezten zustände werden durch magische konstanten dargestellt, der unbesetzte zustand dagegen hat keinen bestimmten wert - in diesem falle ist der wert lediglich mit dem index direkt verknüpft, was im grunde sinnlos ist. ich würde vorschlagen, hier eine aufzählung einzusetzen, z.b.
class Reversi { static const int spielfeld_zeilen = 8; static const int spielfeld_spalten = 8; enum feldzustand { unbesetzt, besetzt_von_spieler1, besetzt_von_spieler2 }; feldzustand spielfeld[ spielfeld_zeilen ] [ spielfeld_spalten ]; // usw.
- die namenswahl kollierdiert u.U. mit std::rand, das ist zumindest unschön).
gleiches gilt für die steinsuche funktionen.
Ich verstehe nicht was du mit meinst nicht
siehe auch punkt 1). es gibt auch eine standardfunktion rand (die du im konstruktor der klasse Reversi auch einsetzt. da sich die parameter von denen deiner eigenen funktion unterscheiden, ist das nicht unbedingt ein problem, nur unschön, und wie erwähnt als (deutscher) name einer funktion sowieso eher ungeeignet.
- Da kann man einiges noch in Funktionen auslagern.
Wie viel soll ich den auslagern.
wiederholung ist nie gut. eine gute faustregel ist: wenn du 3 mal dasselbe tun musst (vielleicht nur mit unterschiedlichen parametern), mach eine funktion daraus.
- die wahl der bezeichner ist ein bißchen eigenwillig und uneinheitlich.
-
hy
so endlich ich hoff ich hab es. Ich habe fast alle vorschläge reingebracht
Ihr könnte nun testen
bis morgen um 9 uhr weil um 11 muss cih des abgeben.Hier nochmal einen herlichen Danke an alle die ihre Vorschläge zum besten gegeben habe
so feherl gefunden und ausgebessert rervseri B.2
#include <iostream> #include <fstream> #include <conio> #include <time> #include <stdio> #include <iomanip> #include <windows> #include <string> using namespace std; enum feldzustand{ unbesetzt, besetztvonspieler1, besetztvonspieler2 }; bool stein_suche_richtung_W_NW_N_NO(feldzustand feldf[],int spiefeldspaltenorignal,int spielfeldspalten, int vereinfachungdate,int besetztvongegner,int besetztvonwerdranist, int endespielfeld); bool stein_suche_richtung_O_SO_S_SW(feldzustand feldf[],int spiefeldspaltenorignal,int spielfeldspalten, int vereinfachungdate,int besetztvongegner,int besetztvonwerdranist, int endespielfeld); bool spielfeldrand(int startspielfeldrand ,int spielfeldspalten,int endespielfeldrand,int vereinfachungdate); int finde_lezte_setzbare_stelle(int Vstartspielfeldrand, int Vendespielfeldrand ,int vertikalgehen,int Hstartspielfeldrand, int Hendespielfeldrand,int spielfeldspalten,int vereinfachungdate); int richtung(string richtung); class Reversi { private: static const int spielfeldspalten = 64; enum feldzustand spielfeld[ spielfeldspalten ]; bool weristdran ; bool Gewinner; ifstream hilfe; public: Reversi(); bool pruefe_stein_setzen_zulaessig(int spielfeldspalten,int richtung); void setze_stein(int stelle,int richtung); void gewinner(); bool spielende(); void aenderwer_ist_dran(); void ausgabe_hilfe(); void ausgabe_zeichen_Spielfeld(); void ausgabe_wer_ist_dran(); void ausgabe_passen(); void ausgabe_gewinner(); }; Reversi::Reversi() { for(int i=0;i<63;i++) { spielfeld[i]=unbesetzt; } //standart eisntellung spielfeld[27]=besetztvonspieler1; spielfeld[28]=besetztvonspieler1; spielfeld[35]=besetztvonspieler2; spielfeld[36]=besetztvonspieler2; randomize() ; weristdran=false; hilfe.open("Hilfe.txt"); } void Reversi::aenderwer_ist_dran() { if(weristdran) { weristdran=false; } else { weristdran=true; } } bool Reversi::spielende(void) { int moeglichkeiten=1, besetzt=0; bool erg; for(int i=0;i<64;i++) { if(spielfeld[i]!=besetztvonspieler1||spielfeld[i]!=besetztvonspieler2) for(int a=1;a<9;a++) { erg=this->pruefe_stein_setzen_zulaessig(i,a); if(erg==true) moeglichkeiten++; erg=false; } else if(spielfeld[i]!=unbesetzt) besetzt=besetzt+1; } if(besetzt==63) { this->gewinner(); } else if(moeglichkeiten>1) { return true; } else { this->ausgabe_passen(); } return false ; } bool Reversi::pruefe_stein_setzen_zulaessig(int spielfeldspalten,int richtung) { bool Gestein=false; int leztestelle; feldzustand besetztvongegner, besetztvonwerdranist ; if(weristdran) { besetztvonwerdranist=besetztvonspieler1 ; besetztvongegner=besetztvonspieler2; } else { besetztvonwerdranist=besetztvonspieler2 ; besetztvongegner=besetztvonspieler1;; } switch(richtung) { case 1: // N leztestelle=finde_lezte_setzbare_stelle(0,0,0,0,7,spielfeldspalten,-8); // horizontaler Rand 0-15 if(leztestelle>=0) Gestein=stein_suche_richtung_W_NW_N_NO(spielfeld,spielfeldspalten,spielfeldspalten,8,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 2:// N0 leztestelle=finde_lezte_setzbare_stelle(7,63,8,0,7,spielfeldspalten,-7); // vertiakler Rand 7,15,23,31,39,47,55,63 horizontaler Rand 0-7 if(leztestelle>=0) Gestein=stein_suche_richtung_W_NW_N_NO(spielfeld,spielfeldspalten,spielfeldspalten,7,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 3: // O leztestelle=finde_lezte_setzbare_stelle(7,63,8,0,0,spielfeldspalten,1); // vertiakler Rand 7,15,23,31,39,47,55,63 if(leztestelle>=0) Gestein=stein_suche_richtung_O_SO_S_SW(spielfeld,spielfeldspalten,spielfeldspalten,1,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 4: // so leztestelle=finde_lezte_setzbare_stelle(7,63,8,56,63,spielfeldspalten,9); // vertiakler Rand 7,15,23,31,39,47,55,63 horizontaler Rand 56-63 if(leztestelle>=0) Gestein=stein_suche_richtung_O_SO_S_SW(spielfeld,spielfeldspalten,spielfeldspalten,9,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 5: // s leztestelle=finde_lezte_setzbare_stelle(0,0,0,56,63,spielfeldspalten,8); // horizontaler Rand 56-63 if(leztestelle>=0) Gestein=stein_suche_richtung_O_SO_S_SW(spielfeld,spielfeldspalten,spielfeldspalten,8,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 6: // SW leztestelle=finde_lezte_setzbare_stelle(0,56,8,56,63,spielfeldspalten,7); //vertiakler Rand 0,8,16,24,32,40,48,56 horizontaler Rand 0-15 if(leztestelle>=0) Gestein=stein_suche_richtung_O_SO_S_SW(spielfeld,spielfeldspalten,spielfeldspalten,7,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 7: // W leztestelle=finde_lezte_setzbare_stelle(0,56,8,0,0,spielfeldspalten,-1); //vertiakler Rand 0,8,16,24,32,40,48,56 if(leztestelle>=0) Gestein=stein_suche_richtung_W_NW_N_NO(spielfeld,spielfeldspalten,spielfeldspalten,1,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 8:// NW leztestelle=finde_lezte_setzbare_stelle(0,56,8,0,7,spielfeldspalten,-9); // vertiakler Rand 0,8,16,24,32,40,48,56 //horizontaler Rand 1-7 if(leztestelle>=0) Gestein=stein_suche_richtung_W_NW_N_NO(spielfeld,spielfeldspalten,spielfeldspalten,9,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; } return Gestein; } void Reversi::setze_stein(int spielfeldspalten,int richtung) { feldzustand besetztvongegner, besetztvonwerdranist ; bool erg; if(weristdran) { besetztvonwerdranist=besetztvonspieler1 ; besetztvongegner=besetztvonspieler2; } else { besetztvonwerdranist=besetztvonspieler2 ; besetztvongegner=besetztvonspieler1;; } switch(richtung) { case 1: // N spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten-8]== besetztvongegner) this->setze_stein(spielfeldspalten-8,1); break; case 2: // NO spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten-7]== besetztvongegner) this->setze_stein(spielfeldspalten-7,2); break; case 3: // 0 spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten+1]== besetztvongegner) this->setze_stein(spielfeldspalten+1,3); break; case 4: // SO spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten+9]== besetztvongegner) this->setze_stein(spielfeldspalten+9,4); break; case 5: // S spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten+8]== besetztvongegner) this->setze_stein(spielfeldspalten+8,5); break; case 6: // SW spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten+7]== besetztvongegner) this->setze_stein(spielfeldspalten+7,6); break; case 7: // W spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten-1]== besetztvongegner) this->setze_stein(spielfeldspalten-1,7); break; case 8: // NW spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten-9]== besetztvongegner) this->setze_stein(spielfeldspalten-9,8); } } void Reversi::gewinner() { int Spieler1=0 , Spieler2=0; for(int d=0;d<64;d++) { if(spielfeld[spielfeldspalten]==besetztvonspieler1) { Spieler1++ ; } if(spielfeld[spielfeldspalten]==besetztvonspieler2) { Spieler2++ ; } } if(Spieler1>Spieler2) { Gewinner=true; } else { Gewinner=false; } } //------------------------------------------------------Ausgabe Methoden ab hier------------------------------------------------------------------ void Reversi::ausgabe_gewinner() { if(Gewinner) { clrscr(); textcolor(4); cprintf("Spieler X hat gewonnen"); textcolor(0); } else { clrscr(); textcolor(4); cprintf("Spieler X hat gewonnen"); textcolor(0); } } void Reversi::ausgabe_hilfe() { char a; clrscr(); if(hilfe==0) { cout << "Konnte Datein nicht oeffnen!" << endl; cout << endl << "Bei Tastendruck zurueck ins Spiel" ; getch(); getch(); getch(); } else { while(!hilfe.eof()) { hilfe.get(a); cout << a ; } cout << endl << "Bei Tastendruck zurueck ins Spiel" ; gotoxy(1,1); getch(); getch(); getch(); } hilfe.close(); hilfe.open("Regeln.txt"); } void Reversi::ausgabe_passen() { if(weristdran) { textcolor(4); cprintf("Spieler X muss passen"); textcolor(0); cout << endl; weristdran=false; } else { cout << endl << "Spieler O muss passen"; weristdran=true; } cout << endl << "Bei Tastendruck geht es weiter"; getch(); } void Reversi::ausgabe_zeichen_Spielfeld() { int g=0, a=0 ; clrscr(); for(a=0;a<64;a++) { if(g==8) { g=0; cout << endl; for(int b=0;b<31;b++) { cout << "="; } cout << endl; } if(spielfeld[a]==besetztvonspieler1) { textcolor(4); cprintf(" X"); textcolor(0); cout << "|"; } else if(spielfeld[a]==besetztvonspieler2) { textcolor(2); cprintf(" O") ; textcolor(0); cout << "|"; } else { cout<< setw(3); cout << a+1; cout << "|"; } g++; } cout<< endl; cout<< endl; } void Reversi::ausgabe_wer_ist_dran(void) { if(weristdran) { textcolor(4); cprintf("Spieler X ist dran"); textcolor(0); cout << endl; } else { textcolor(2); cprintf("Spieler O ist dran"); textcolor(0); cout << endl; } cout << endl << "Bei druecken von F1 erscheint die Hilfe." ; cout << endl<< "Auf welche Stelle soll gesetzt werden? : "; } //-------------------------------------------Hauptprogramm--------------------------------------------------------------------------- void main(void) { Reversi b; int wert1=1 , spielfeldspalten, wert=1; bool erg=false; string richtun="Nix"; short KeyState = 0; do { spielfeldspalten=0; short ArrKeyState[256]={0}; KeyState = 0; b.ausgabe_zeichen_Spielfeld(); b.ausgabe_wer_ist_dran(); erg=b.spielende(); if(erg) // überprüfung ob Spieler setzen kann { while (wert<2) { for (int i = 0; i < 256; i++) // Abprüfen der Gesammtentastertur { KeyState = GetAsyncKeyState(i); ArrKeyState[i] = KeyState; } if(kbhit()) { if (ArrKeyState[112]==-32767) // Überprüfen ob F1 gedrückt wurde { b.ausgabe_hilfe(); wert=2; } else { for (int a = 48; a <58 ; a++) { if(ArrKeyState[a]!=0) { wert=2; wert1=3; } } } } } if(wert1==3) { cin>>spielfeldspalten; cout << endl << "Welche Richtung? :"; cin >> richtun ; if(spielfeldspalten>64||spielfeldspalten<1) erg=false; else { erg=b.pruefe_stein_setzen_zulaessig(spielfeldspalten-1,richtung(richtun)); } if(erg) { b.setze_stein(spielfeldspalten-1,richtung(richtun)); wert=1; wert1=1; erg=false; b.aenderwer_ist_dran(); } else // wenn sezten der sonst Eingabe nich in ordnung war { cout << endl <<"Spielzug oder Eingabe nicht zulaessig" <<endl; cout << "Bei Tastendruck geht es weiter "; getch(); wert=1; wert1=1; } } else //wenn hilfe ausgegeben wurde trifft dieser fall ein { wert=1; } } else { b.ausgabe_gewinner(); wert1=2; } } while(wert1<2); getch(); } bool spielfeldrand(int startspielfeldrand ,int spielfeldspalten,int endespielfeldrand ,int vereinfachungdate ) { if(startspielfeldrand ==spielfeldspalten) // wenn die stelle am rand leigt dan diese anweisung return true ; if(startspielfeldrand ==endespielfeldrand) //wenn die stelle nicht am rand liegt return false ; if(spielfeldspalten<0) return false; if(spielfeldspalten>64) return false; spielfeldrand(startspielfeldrand +vereinfachungdate,spielfeldspalten,endespielfeldrand,vereinfachungdate); } bool stein_suche_richtung_W_NW_N_NO(feldzustand feldf[],int spiefeldspaltenorignal, int spielfeldspalten, int vereinfachungdate,int besetztvongegner,int besetztvonwerdranist,int endespielfeld) { if( spielfeldspalten>=endespielfeld && feldf[spielfeldspalten]==besetztvonwerdranist) { if(feldf[spielfeldspalten-vereinfachungdate]!=besetztvonwerdranist && feldf[spielfeldspalten-vereinfachungdate]!=besetztvongegner) return false; if(spielfeldspalten==(spiefeldspaltenorignal-vereinfachungdate)) return false; else return true; } if(feldf[spiefeldspaltenorignal-vereinfachungdate]!=besetztvonwerdranist && feldf[spiefeldspaltenorignal-vereinfachungdate]!=besetztvongegner) // für den fall das des spaltenzeile+verinfachung unbesetzt ist return false; if(spielfeldspalten<endespielfeld) { return false; } stein_suche_richtung_W_NW_N_NO(feldf,spiefeldspaltenorignal,spielfeldspalten-vereinfachungdate,vereinfachungdate,besetztvongegner,besetztvonwerdranist,endespielfeld); } bool stein_suche_richtung_O_SO_S_SW(feldzustand feldf[],int spiefeldspaltenorignal,int spielfeldspalten, int vereinfachungdate,int besetztvongegner,int besetztvonwerdranist ,int endespielfeld ) { if(spielfeldspalten<=endespielfeld && feldf[spielfeldspalten]==besetztvonwerdranist) { if(feldf[spielfeldspalten+vereinfachungdate]!=besetztvonwerdranist && feldf[spielfeldspalten+vereinfachungdate]!=besetztvongegner) return false; if(spielfeldspalten==(spiefeldspaltenorignal-vereinfachungdate)) { return false; } else return true; } if(feldf[spiefeldspaltenorignal+vereinfachungdate]!=besetztvonwerdranist && feldf[spiefeldspaltenorignal+vereinfachungdate]!=besetztvongegner) // für den fall das des spaltenzeile+verinfachung unbesetzt ist return false; if(spielfeldspalten>endespielfeld) { return false; } stein_suche_richtung_O_SO_S_SW(feldf,spiefeldspaltenorignal,spielfeldspalten+vereinfachungdate,vereinfachungdate,besetztvongegner,besetztvonwerdranist,endespielfeld); } int richtung(string richtung) { if(richtung=="N") return 1; else if(richtung=="NO") return 2; else if(richtung=="O") return 3; else if(richtung=="SO") return 4; else if(richtung=="S") return 5; else if(richtung=="SW") return 6; else if(richtung=="W") return 7; else if(richtung=="NW") return 8; else return false ; } int finde_lezte_setzbare_stelle(int Vstartspielfeldrand, int Vendespielfeldrand ,int vertikalgehen,int Hstartspielfeldrand, int Hendespielfeldrand,int spielfeldspalten,int vereinfachungdate) { bool erg1=false, erg=false; if(Vendespielfeldrand>0) { erg=spielfeldrand(Vstartspielfeldrand,spielfeldspalten,Vendespielfeldrand,vertikalgehen); // vertikaler rand if(Hendespielfeldrand>0) erg1=spielfeldrand(Hstartspielfeldrand,spielfeldspalten,Hendespielfeldrand,1);// horizontaler Rand if(erg==true||erg1==true) return spielfeldspalten; } else { erg=spielfeldrand(Hstartspielfeldrand,spielfeldspalten,Hendespielfeldrand,1);// horizontaler Rand if(erg) return spielfeldspalten; } finde_lezte_setzbare_stelle(Vstartspielfeldrand,Vendespielfeldrand ,vertikalgehen,Hstartspielfeldrand,Hendespielfeldrand,spielfeldspalten+vereinfachungdate,vereinfachungdate); }
-
hy
so wider fehler selbst gefunde und verbessert
Reversi beta.3
Problem wenn ihr tastatur mässig schrott ein gebt kommt er durch einander und nimmt dann kein eingaben mehr an zwar f1 macht er noch aber mehr nicht.static const int spielfeldspalten = 64;
Warum reicht den const nicht aus ?muss ich für variable die negativ sein könne singed verwenden, weil er macht es auch ohne
#include <iostream> #include <fstream> #include <conio> #include <time> #include <stdio> #include <iomanip> #include <windows> #include <string> using namespace std; enum feldzustand{ unbesetzt, besetztvonspieler1, besetztvonspieler2 }; bool stein_suche_richtung_W_NW_N_NO(feldzustand feldf[],int spiefeldspaltenorignal,int spielfeldspalten, int vereinfachungdate,int besetztvongegner,int besetztvonwerdranist, int endespielfeld); bool stein_suche_richtung_O_SO_S_SW(feldzustand feldf[],int spiefeldspaltenorignal,int spielfeldspalten, int vereinfachungdate,int besetztvongegner,int besetztvonwerdranist, int endespielfeld); bool spielfeldrand(int startspielfeldrand ,int spielfeldspalten,int endespielfeldrand,int vereinfachungdate); int finde_lezte_setzbare_stelle(int Vstartspielfeldrand, int Vendespielfeldrand ,int vertikalgehen,int Hstartspielfeldrand, int Hendespielfeldrand,int spielfeldspalten,int vereinfachungdate); int richtung(string richtung); class Reversi { private: static const int spielfeldspalten = 64; enum feldzustand spielfeld[ spielfeldspalten ]; bool weristdran ; bool Gewinner; ifstream hilfe; public: Reversi(); bool pruefe_stein_setzen_zulaessig(int spielfeldspalten,int richtung); void setze_stein(int stelle,int richtung); void gewinner(); bool spielende(); void aenderwer_ist_dran(); void ausgabe_hilfe(); void ausgabe_zeichen_Spielfeld(); void ausgabe_wer_ist_dran(); void ausgabe_passen(); void ausgabe_gewinner(); }; Reversi::Reversi() { for(int i=0;i<63;i++) { spielfeld[i]=unbesetzt; } //standart eisntellung spielfeld[27]=besetztvonspieler1; spielfeld[28]=besetztvonspieler1; spielfeld[35]=besetztvonspieler2; spielfeld[36]=besetztvonspieler2; randomize() ; weristdran=true; hilfe.open("Hilfe.txt"); } void Reversi::aenderwer_ist_dran() { if(weristdran) { weristdran=false; } else { weristdran=true; } } bool Reversi::spielende(void) { int moeglichkeiten=1, besetzt=0; bool erg; for(int i=0;i<64;i++) { if(spielfeld[i]!=besetztvonspieler1||spielfeld[i]!=besetztvonspieler2) for(int a=1;a<9;a++) { erg=this->pruefe_stein_setzen_zulaessig(i,a); if(erg==true) moeglichkeiten++; erg=false; } else if(spielfeld[i]!=unbesetzt) besetzt=besetzt+1; } if(besetzt==63) { this->gewinner(); } else if(moeglichkeiten>1) { return true; } else { this->ausgabe_passen(); } return false ; } bool Reversi::pruefe_stein_setzen_zulaessig(int spielfeldspalten,int richtung) { bool Gestein=false; int leztestelle; feldzustand besetztvongegner, besetztvonwerdranist ; if(weristdran) { besetztvonwerdranist=besetztvonspieler1 ; besetztvongegner=besetztvonspieler2; } else { besetztvonwerdranist=besetztvonspieler2 ; besetztvongegner=besetztvonspieler1;; } switch(richtung) { case 1: // N leztestelle=finde_lezte_setzbare_stelle(0,0,0,0,7,spielfeldspalten,-8); // horizontaler Rand 0-15 if(leztestelle>=0) Gestein=stein_suche_richtung_W_NW_N_NO(spielfeld,spielfeldspalten,spielfeldspalten,8,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 2:// N0 leztestelle=finde_lezte_setzbare_stelle(7,63,8,0,7,spielfeldspalten,-7); // vertiakler Rand 7,15,23,31,39,47,55,63 horizontaler Rand 0-7 if(leztestelle>=0) Gestein=stein_suche_richtung_W_NW_N_NO(spielfeld,spielfeldspalten,spielfeldspalten,7,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 3: // O leztestelle=finde_lezte_setzbare_stelle(7,63,8,0,0,spielfeldspalten,1); // vertiakler Rand 7,15,23,31,39,47,55,63 if(leztestelle>=0) Gestein=stein_suche_richtung_O_SO_S_SW(spielfeld,spielfeldspalten,spielfeldspalten,1,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 4: // so leztestelle=finde_lezte_setzbare_stelle(7,63,8,56,63,spielfeldspalten,9); // vertiakler Rand 7,15,23,31,39,47,55,63 horizontaler Rand 56-63 if(leztestelle>=0) Gestein=stein_suche_richtung_O_SO_S_SW(spielfeld,spielfeldspalten,spielfeldspalten,9,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 5: // s leztestelle=finde_lezte_setzbare_stelle(0,0,0,56,63,spielfeldspalten,8); // horizontaler Rand 56-63 if(leztestelle>=0) Gestein=stein_suche_richtung_O_SO_S_SW(spielfeld,spielfeldspalten,spielfeldspalten,8,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 6: // SW leztestelle=finde_lezte_setzbare_stelle(0,56,8,56,63,spielfeldspalten,7); //vertiakler Rand 0,8,16,24,32,40,48,56 horizontaler Rand 0-15 if(leztestelle>=0) Gestein=stein_suche_richtung_O_SO_S_SW(spielfeld,spielfeldspalten,spielfeldspalten,7,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 7: // W leztestelle=finde_lezte_setzbare_stelle(0,56,8,0,0,spielfeldspalten,-1); //vertiakler Rand 0,8,16,24,32,40,48,56 if(leztestelle>=0) Gestein=stein_suche_richtung_W_NW_N_NO(spielfeld,spielfeldspalten,spielfeldspalten,1,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; case 8:// NW leztestelle=finde_lezte_setzbare_stelle(0,56,8,0,7,spielfeldspalten,-9); // vertiakler Rand 0,8,16,24,32,40,48,56 //horizontaler Rand 1-7 if(leztestelle>=0) Gestein=stein_suche_richtung_W_NW_N_NO(spielfeld,spielfeldspalten,spielfeldspalten,9,besetztvongegner,besetztvonwerdranist,leztestelle); return Gestein; } return Gestein; } void Reversi::setze_stein(int spielfeldspalten,int richtung) { feldzustand besetztvongegner, besetztvonwerdranist ; bool erg; if(weristdran) { besetztvonwerdranist=besetztvonspieler1 ; besetztvongegner=besetztvonspieler2; } else { besetztvonwerdranist=besetztvonspieler2 ; besetztvongegner=besetztvonspieler1;; } switch(richtung) { case 1: // N spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten-8]== besetztvongegner) this->setze_stein(spielfeldspalten-8,1); break; case 2: // NO spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten-7]== besetztvongegner) this->setze_stein(spielfeldspalten-7,2); break; case 3: // 0 spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten+1]== besetztvongegner) this->setze_stein(spielfeldspalten+1,3); break; case 4: // SO spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten+9]== besetztvongegner) this->setze_stein(spielfeldspalten+9,4); break; case 5: // S spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten+8]== besetztvongegner) this->setze_stein(spielfeldspalten+8,5); break; case 6: // SW spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten+7]== besetztvongegner) this->setze_stein(spielfeldspalten+7,6); break; case 7: // W spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten-1]== besetztvongegner) this->setze_stein(spielfeldspalten-1,7); break; case 8: // NW spielfeld[spielfeldspalten]=besetztvonwerdranist; if(spielfeld[spielfeldspalten-9]== besetztvongegner) this->setze_stein(spielfeldspalten-9,8); } } void Reversi::gewinner() { int Spieler1=0 , Spieler2=0; for(int d=0;d<64;d++) { if(spielfeld[spielfeldspalten]==besetztvonspieler1) { Spieler1++ ; } if(spielfeld[spielfeldspalten]==besetztvonspieler2) { Spieler2++ ; } } if(Spieler1>Spieler2) { Gewinner=true; } else { Gewinner=false; } } //------------------------------------------------------Ausgabe Methoden ab hier------------------------------------------------------------------ void Reversi::ausgabe_gewinner() { if(Gewinner) { clrscr(); textcolor(4); cprintf("Spieler X hat gewonnen"); textcolor(0); } else { clrscr(); textcolor(4); cprintf("Spieler X hat gewonnen"); textcolor(0); } } void Reversi::ausgabe_hilfe() { char a; clrscr(); if(hilfe==0) { cout << "Konnte Datein nicht oeffnen!" << endl; cout << endl << "Bei Tastendruck zurueck ins Spiel" ; getch(); getch(); getch(); } else { while(!hilfe.eof()) { hilfe.get(a); cout << a ; } cout << endl << "Bei Tastendruck zurueck ins Spiel" ; gotoxy(1,1); getch(); getch(); getch(); } hilfe.close(); hilfe.open("Regeln.txt"); } void Reversi::ausgabe_passen() { if(weristdran) { textcolor(4); cprintf("Spieler X muss passen"); textcolor(0); cout << endl; weristdran=false; } else { cout << endl << "Spieler O muss passen"; weristdran=true; } cout << endl << "Bei Tastendruck geht es weiter"; getch(); } void Reversi::ausgabe_zeichen_Spielfeld() { int g=0, a=0 ; clrscr(); for(a=0;a<64;a++) { if(g==8) { g=0; cout << endl; for(int b=0;b<31;b++) { cout << "="; } cout << endl; } if(spielfeld[a]==besetztvonspieler1) { textcolor(4); cprintf(" X"); textcolor(0); cout << "|"; } else if(spielfeld[a]==besetztvonspieler2) { textcolor(2); cprintf(" O") ; textcolor(0); cout << "|"; } else { cout<< setw(3); cout << a+1; cout << "|"; } g++; } cout<< endl; cout<< endl; } void Reversi::ausgabe_wer_ist_dran(void) { if(weristdran) { textcolor(4); cprintf("Spieler X ist dran"); textcolor(0); cout << endl; } else { textcolor(2); cprintf("Spieler O ist dran"); textcolor(0); cout << endl; } cout << endl << "Bei druecken von F1 erscheint die Hilfe." ; cout << endl<< "Auf welche Stelle soll gesetzt werden? : "; } //-------------------------------------------Hauptprogramm--------------------------------------------------------------------------- void main(void) { Reversi b; int wert1=1 , spielfeldspalten, wert=1; bool erg=false; string richtun="Nix"; short KeyState = 0; do { spielfeldspalten=0; short ArrKeyState[256]={0}; KeyState = 0; b.ausgabe_zeichen_Spielfeld(); b.ausgabe_wer_ist_dran(); erg=b.spielende(); if(erg) // überprüfung ob Spieler setzen kann { while (wert<2) { for (int i = 0; i < 256; i++) // Abprüfen der Gesammtentastertur { KeyState = GetAsyncKeyState(i); ArrKeyState[i] = KeyState; } if(kbhit()) { if (ArrKeyState[112]==-32767) // Überprüfen ob F1 gedrückt wurde { b.ausgabe_hilfe(); wert=2; } else { for (int a = 48; a <58 ; a++) { if(ArrKeyState[a]!=0) { wert=2; wert1=3; } } } } } if(wert1==3) { cin>>spielfeldspalten; cout << endl << "Welche Richtung? :"; cin >> richtun ; if(spielfeldspalten>64||spielfeldspalten<1) erg=false; else { erg=b.pruefe_stein_setzen_zulaessig(spielfeldspalten-1,richtung(richtun)); } if(erg) { b.setze_stein(spielfeldspalten-1,richtung(richtun)); wert=1; wert1=1; erg=false; b.aenderwer_ist_dran(); } else // wenn sezten der sonst Eingabe nich in ordnung war { cout << endl <<"Spielzug oder Eingabe nicht zulaessig" <<endl; cout << "Bei Tastendruck geht es weiter "; getch(); wert=1; wert1=1; } } else //wenn hilfe ausgegeben wurde trifft dieser fall ein { wert=1; } } else { b.ausgabe_gewinner(); wert1=2; } } while(wert1<2); getch(); } bool spielfeldrand(int startspielfeldrand ,int spielfeldspalten,int endespielfeldrand ,int vereinfachungdate ) { if(startspielfeldrand ==spielfeldspalten) // wenn die stelle am rand leigt dan diese anweisung return true ; if(startspielfeldrand ==endespielfeldrand) //wenn die stelle nicht am rand liegt return false ; if(spielfeldspalten<0) return false; if(spielfeldspalten>64) return false; spielfeldrand(startspielfeldrand +vereinfachungdate,spielfeldspalten,endespielfeldrand,vereinfachungdate); } bool stein_suche_richtung_W_NW_N_NO(feldzustand feldf[],int spiefeldspaltenorignal, int spielfeldspalten, int vereinfachungdate,int besetztvongegner,int besetztvonwerdranist,int endespielfeld) { // abfrage ob Spielfeldspalte kleiner als Spiefeldrand und Spielfeldspalte besetzt von wer dran ist und das da das Ziel nicht gleich der Stelle sein darf auf der man gesetzt hatt if( spielfeldspalten>=endespielfeld && feldf[spielfeldspalten]==besetztvonwerdranist && spielfeldspalten!=(spiefeldspaltenorignal-vereinfachungdate)) return true; // wenn die nächste spielfeldspalten nicht besetzt ist dan gibt false zurück if(feldf[spiefeldspaltenorignal-vereinfachungdate]!=besetztvonwerdranist && feldf[spiefeldspaltenorignal-vereinfachungdate]!=besetztvongegner) return false; // wenn die erste Stell von der gesetzten Stelle nicht dem Gegner gehört sonder wer dran ist if(feldf[spiefeldspaltenorignal-vereinfachungdate]==besetztvonwerdranist) return false; // abfrage ob Spielfeldspalte kleiner als Spiefeldrand um stack überlauf zu verhindern if(spielfeldspalten<endespielfeld) { return false; } stein_suche_richtung_W_NW_N_NO(feldf,spiefeldspaltenorignal,spielfeldspalten-vereinfachungdate,vereinfachungdate,besetztvongegner,besetztvonwerdranist,endespielfeld); } bool stein_suche_richtung_O_SO_S_SW(feldzustand feldf[],int spiefeldspaltenorignal,int spielfeldspalten, int vereinfachungdate,int besetztvongegner,int besetztvonwerdranist ,int endespielfeld ) { // abfrage ob Spielfeldspalte größer als Spiefeldrand und Spielfeldspalte besetzt von wer dran ist und das da das Ziel nicht gleich der Stelle sein darf auf der man gesetzt hatt if(spielfeldspalten<=endespielfeld && feldf[spielfeldspalten]==besetztvonwerdranist && spielfeldspalten!=(spiefeldspaltenorignal-vereinfachungdate)) return true; // wenn die nächste spielfeldspalten nicht besetzt ist dan gibt false zurück if(feldf[spiefeldspaltenorignal+vereinfachungdate]!=besetztvonwerdranist && feldf[spiefeldspaltenorignal+vereinfachungdate]!=besetztvongegner) return false; // wenn die erste Stell von der gesetzten Stelle nicht dem Gegner gehört sonder wer dran ist if(feldf[spiefeldspaltenorignal+vereinfachungdate]==besetztvonwerdranist) return false; // abfrage ob Spielfeldspalte kleiner als Spiefeldrand um stack überlauf zu verhindern if(spielfeldspalten>endespielfeld) { return false; } stein_suche_richtung_O_SO_S_SW(feldf,spiefeldspaltenorignal,spielfeldspalten+vereinfachungdate,vereinfachungdate,besetztvongegner,besetztvonwerdranist,endespielfeld); } int richtung(string richtung) { if(richtung=="N") return 1; else if(richtung=="NO") return 2; else if(richtung=="O") return 3; else if(richtung=="SO") return 4; else if(richtung=="S") return 5; else if(richtung=="SW") return 6; else if(richtung=="W") return 7; else if(richtung=="NW") return 8; else return false ; } int finde_lezte_setzbare_stelle(int Vstartspielfeldrand, int Vendespielfeldrand ,int vertikalgehen,int Hstartspielfeldrand, int Hendespielfeldrand,int spielfeldspalten,int vereinfachungdate) { bool erg1=false, erg=false; if(Vendespielfeldrand>0) { erg=spielfeldrand(Vstartspielfeldrand,spielfeldspalten,Vendespielfeldrand,vertikalgehen); // vertikaler rand if(Hendespielfeldrand>0) erg1=spielfeldrand(Hstartspielfeldrand,spielfeldspalten,Hendespielfeldrand,1);// horizontaler Rand if(erg==true||erg1==true) return spielfeldspalten; } else { erg=spielfeldrand(Hstartspielfeldrand,spielfeldspalten,Hendespielfeldrand,1);// horizontaler Rand if(erg) return spielfeldspalten; } finde_lezte_setzbare_stelle(Vstartspielfeldrand,Vendespielfeldrand ,vertikalgehen,Hstartspielfeldrand,Hendespielfeldrand,spielfeldspalten+vereinfachungdate,vereinfachungdate); }