M
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);
}