S
Ich habs mir mal selbst programmiert, weil ich dafür mit dem Alpha-Beta KI-Algotithmus üben will.
Ich habe das Spielfeld immer komplett umgegraben, weil ich alle möglichen Gewinnsituationen für die Bewertung brauche.
Der Stil ist wahrscheinlich nicht so toll - aber hey, bin ja noch Anfänger
Hier für zwei Spieler komplett in C für WIN32:
Am besten einfach mal compilen.
/*
VIER GEWINNT (c) 2007 by Simonek
Vier Gewinnt! Für zwei Spieler komplett in C geschrieben.
*/
// INCLUDE-DATEIEN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
// DEFINIERUNGEN
#define JA 1
#define NEIN 0
#define SPIELER1 1
#define SPIELER2 0
#define ZEICHEN1 '#' // Zeichen der Spielsteine für Spieler 1 (kann hier geändert werden)
#define ZEICHEN2 '/' // Zeichen der Spielsteine für Spieler 2 (kann hier geändert werden)
#define SPEED 100 // Legt die Geschwindigkeit der Animation fest
// GLOBALE VATIABLEN
char name1[20]; // Name von Spieler 1
char name2[20]; // Name von Spieler 2
int f[8][8]; // Das Spielfeld
int a[3][27]; // Animationsfelder über dem Spielfeld
//FUNKTIONS-PROTOTYPEN
// *** SPIELRELEVANTE FUNKTIONEN
void init(int namen); // Initialisiert die Spieldaten vor dem Spiel
void zeige_spielfeld(void); // Zeigt das Spielfeld an
void animation(int nach, int hohe, int wer);
void ziehen(int wer); // Spieler zieht
int winchk(int wer); // Überprüft, ob jemand gewonnen hat
void highlight(int ax,int ay, int bx, int by,
int cx, int cy, int dx, int dy);
void win(int wer); // Gibt Gewinnmeldung aus
// *** ALLGEMEINE FUNKTIONEN
int jn_frage(void); // Übersetzt jJnN in 1 oder 0
int int_eingabe(int min, int max); // Erzwingt Eingabe im Wertebereich
void sleep(long dauer); // Stoppt Programm für einen gewissen Zeitraum
int main(void) // PROGRAMMSTART: HERE WE GO...
{
int spielende = NEIN;
int neuesspiel = NEIN;
int namen = NEIN;
srand(time(NULL));
system("cls");
puts("\n\nWillkommen bei 4Gewinnt!\n");
puts("\nDieses Spiel wurde komplett in C geschrieben.");
puts("\nCopyright (c) 2007 by Simonek");
puts("\n\nMit beliebiger Taste starten...");
getch();
while ( 1 )
{
init(namen);
namen = JA;
zeige_spielfeld();
while ( spielende == NEIN ) // Spielablauf:
{
ziehen(SPIELER1); // Spieler 1 zieht...
zeige_spielfeld(); // Zeige den Zug an...
spielende = winchk(SPIELER1); // Überprüft, ob Spieler 1 gewinnt...
if ( spielende == JA ) // Wenn ja, dann Schleife abbrechen...
break;
ziehen(SPIELER2); // Ansonsten: Spieler 2 zieht...
zeige_spielfeld(); // Zeige den Zug an...
spielende = winchk(SPIELER2); // Überprüft, ob Spieler 2 gewinnt und springt ggf. aus der Schleife
}
printf("\nM%cchten Sie ein neues Spiel starten (J)a/(N)ein?\n", 148);
printf("\n==> ");
neuesspiel = jn_frage();
if ( neuesspiel == NEIN )
break;
else
spielende = NEIN;
}
return EXIT_SUCCESS;
}
void init(int namen) // INITIALISIERT DIE SPIELDATEN
{
char leerzeichen[2] = " ";
char tmp_name[20];
int count, count1, count2;
int laenge;
int starten = 0;
int los = 1001;
if ( namen == NEIN )
{
system("cls"); // Namen eingeben
puts("Spieler 1: Geben Sie bitte Ihren Namen ein.");
printf("\n\n==> ");
fgets(name1, 20, stdin);
system("cls");
puts("Spieler 2: Geben Sie bitte Ihren Namen ein.");
printf("\n\n==> ");
fgets(name2, 20, stdin);
laenge = strlen(name1); // Namen anpassen
name1[laenge-1] = ' ';
laenge = strlen(name2);
name2[laenge-1] = ' ';
}
else
;
system("cls");
printf("Wer soll starten?\n");
printf("\n1. %s\n", name1);
printf("2. %s\n", name2);
printf("3. Zuf%cllig\n", 132);
starten = int_eingabe(1, 3);
if ( starten == 1 )
printf("\n\n%sstartet...", name1);
else if ( starten == 2 )
{
strcpy(tmp_name, name1);
strcpy(name1, name2);
strcpy(name2, tmp_name);
printf("\n\n%sstartet...", name1);
}
else
{
printf("\nTaste dr%ccken um auszulosen, wer starten darf...\n", 129); // Auslosung wer startet
getch();
while ( los > 1000 )
{
los = rand();
}
system("cls");
for(count1=0;count1<15;count1++) // Simuliere optische Auslosung
{
printf("--> %s\n", name1);
printf(" %s\n", name2);
sleep(120);
system("cls");
printf(" %s\n", name1);
printf("--> %s\n", name2);
sleep(120);
system("cls");
}
if ( los > 499 )
{
printf(" %s\n", name1);
printf("--> %s\n", name2);
printf("\n\n%s startet...", name2);
strcpy(tmp_name, name1);
strcpy(name1, name2);
strcpy(name2, tmp_name);
}
else
{
printf("--> %s\n", name1);
printf(" %s\n", name2);
printf("\n\n%s startet...", name1);
}
}
sleep(2500);
system("cls"); // Leer den Bildschirm, kann ggf. verbessert werden
printf("\n\nInitialisierung");
for(count1=0;count1<8;count1++) // Initialisiert die Spielfelder mit einem Leerzeichen
{
for(count2=0;count2<8;count2++)
{
f[count1][count2] = ' ';
}
}
for(count1=0;count1<3;count1++) // Initialisiert die Spielfelder mit einem Leerzeichen
{
for(count2=0;count2<27;count2++)
{
a[count1][count2] = ' ';
}
}
for(count1=0;count1<60;count1++) // Simuliert Ladevorgang...
{
sleep(10);
printf(".");
}
}
void ziehen(int wer) // SPIELZUG DER SPIELER
{
int ch;
int count;
int wohin = 0;
int hohe = 0;
int gesetzt = NEIN;
if ( wer == SPIELER1 ) // Initialisiert die Zeichen
{
ch = ZEICHEN1;
printf("\n\n\n%sist am Zug: ", name1);
}
else
{
ch = ZEICHEN2;
printf("\n\n\n%sist am Zug: ", name2);
}
printf("Welche Reihe (1-7)?\n\n");
while ( gesetzt == NEIN )
{
wohin = int_eingabe(1, 7); // Spieler wählt Reihe aus...
for(count=1;count<8;count++) // Ermittelt die Höhe
{
if ( count == 7 )
{
puts("Die Reihe ist voll! Bitte wiederholen Sie den Zug.");
break;
}
if ( f[wohin][count] == ' ' )
{
hohe = count;
gesetzt = JA;
break;
}
}
}
animation(wohin, hohe, wer); // Aktualisiert Zeichen für Spielzug
}
int winchk(int wer)
{
int ch;
int count1, count2;
int ax=0,bx=0,cx=0,dx=0;
int ay=0,by=0,cy=0,dy=0;
int run = 5;
if ( wer == SPIELER1 ) // Zu überprüfendes Zeichen...
ch = ZEICHEN1;
else
ch = ZEICHEN2;
for(count1=1;count1<8;count1++) // ***** Überprüft waagrechte Linien: -
{
ax=1; bx=2; cx=3; dx=4;
for(count2=1;count2<5;count2++)
{
if ( (ch == f[ax][count1]) && (ch == f[bx][count1]) && (ch == f[cx][count1]) && (ch == f[dx][count1]) )
{
highlight(ax,count1,bx,count1,cx,count1,dx,count1);
win(wer);
return JA;
}
ax++; bx++; cx++; dx++;
}
}
for(count1=1;count1<8;count1++) // ***** Überprüft senkrechte Linien: |
{
ay=1; by=2; cy=3; dy=4;
for(count2=1;count2<5;count2++)
{
if ( (ch == f[count1][ay]) && (ch == f[count1][by]) && (ch == f[count1][cy]) && (ch == f[count1][dy]) )
{
highlight(count1,ay,count1,by,count1,cy,count1,dy);
win(wer);
return JA;
}
ay++; by++; cy++; dy++;
}
}
for(count1=1;count1<5;count1++) // Überprüft diagonale Linien: / (untere Hälfte)
{
ay=0; by=1; cy=2; dy=3;
ax=count1-1; bx=count1+0; cx=count1+1; dx=count1+2;
for(count2=1;count2<run;count2++)
{
if ( (ch == f[count2+ax][count2+ay]) && (ch == f[count2+bx][count2+by]) && (ch == f[count2+cx][count2+cy]) && (ch == f[count2+dx][count2+dy]) )
{
highlight((count2+ax),(count2+ay),(count2+bx),(count2+by),(count2+cx),(count2+cy),(count2+dx),(count2+dy));
win(wer);
return JA;
}
}
run--;
}
run = 5;
for(count1=1;count1<5;count1++) // Überprüft diagonale Linien: / (obere Hälfte)
{
ay=count1-1; by=count1+0; cy=count1+1; dy=count1+2;
ax=0; bx=1; cx=2; dx=3;
for(count2=1;count2<run;count2++)
{
if ( (ch == f[count2+ax][count2+ay]) && (ch == f[count2+bx][count2+by]) && (ch == f[count2+cx][count2+cy]) && (ch == f[count2+dx][count2+dy]) )
{
highlight((count2+ax),(count2+ay),(count2+bx),(count2+by),(count2+cx),(count2+cy),(count2+dx),(count2+dy));
win(wer);
return JA;
}
}
run--;
}
run = 5;
for(count1=4;count1>0;count1--) // Überprüft diagonale Linien: \ (untere Häfte)
{
ay=0; by=1; cy=2; dy=3;
ax=count1+3; bx=count1+2; cx=count1+1; dx=count1+0;
for(count2=1;count2<run;count2++)
{
if ( (ch == f[ax][count2+ay]) && (ch == f[bx][count2+by]) && (ch == f[cx][count2+cy]) && (ch == f[dx][count2+dy]) )
{
highlight((ax),(count2+ay),(+bx),(count2+by),(cx),(count2+cy),(dx),(count2+dy));
win(wer);
return JA;
}
ax--; bx--; cx--; dx--;
}
run--;
}
run = 5;
for(count1=1;count1<5;count1++) // Überprüft diagonale Linien: \ (obere Häfte)
{
ay=count1-1; by=count1+0; cy=count1+1; dy=count1+2;
ax=7; bx=6; cx=5; dx=4;
for(count2=1;count2<run;count2++)
{
if ( (ch == f[ax][count2+ay]) && (ch == f[bx][count2+by]) && (ch == f[cx][count2+cy]) && (ch == f[dx][count2+dy]) )
{
highlight((ax),(count2+ay),(bx),(count2+by),(cx),(count2+cy),(dx),(count2+dy));
win(wer);
return JA;
}
ax--; bx--; cx--; dx--;
}
run--;
}
return NEIN; // Gibt 'Nein' zurück, wenn niemand gewonnen hat
}
void highlight(int ax,int ay, int bx, int by, int cx, int cy, int dx, int dy)
{
int ch;
int count;
ch = f[ax][ay];
for(count=0;count<17;count++)
{
f[ax][ay] = ' ';
f[bx][by] = ' ';
f[cx][cy] = ' ';
f[dx][dy] = ' ';
zeige_spielfeld();
sleep(100);
f[ax][ay] = ch;
f[bx][by] = ch;
f[cx][cy] = ch;
f[dx][dy] = ch;
zeige_spielfeld();
sleep(100);
}
}
void win(int wer) // GIBT GEWINNMELDUNG AUS
{
puts("\n\n");
if ( wer == SPIELER1 )
{
printf("%shat gewonnen!\n", name1);
getch();
}
else
{
printf("%shat gewonnen!\n", name2);
getch();
}
}
void zeige_spielfeld(void) // ZEIGT DAS SPIELFELD AN
{
system("cls");
printf("\n\n=============================)\n");
printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", a[0][1], a[0][2], a[0][3], a[0][4], a[0][5], a[0][6], a[0][7], a[0][8], a[0][9], a[0][10], a[0][11], a[0][12], a[0][13], a[0][14], a[0][15], a[0][16], a[0][17], a[0][18], a[0][19], a[0][20], a[0][21], a[0][22], a[0][23], a[0][24], a[0][25], a[0][26] );
printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", a[1][1], a[1][2], a[1][3], a[1][4], a[1][5], a[1][6], a[1][7], a[1][8], a[1][9], a[1][10], a[1][11], a[1][12], a[1][13], a[1][14], a[1][15], a[1][16], a[1][17], a[1][18], a[1][19], a[1][20], a[1][21], a[1][22], a[1][23], a[1][24], a[1][25], a[1][26] );
printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", a[2][1], a[2][2], a[2][3], a[2][4], a[2][5], a[2][6], a[2][7], a[2][8], a[2][9], a[2][10], a[2][11], a[2][12], a[2][13], a[2][14], a[2][15], a[2][16], a[2][17], a[2][18], a[2][19], a[2][20], a[2][21], a[2][22], a[2][23], a[2][24], a[2][25], a[2][26] );
printf(" 6 |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][6], f[1][6], f[2][6], f[2][6], f[3][6], f[3][6], f[4][6], f[4][6], f[5][6], f[5][6], f[6][6], f[6][6], f[7][6], f[7][6] );
printf(" |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][6], f[1][6], f[2][6], f[2][6], f[3][6], f[3][6], f[4][6], f[4][6], f[5][6], f[5][6], f[6][6], f[6][6], f[7][6], f[7][6] );
printf(" 5 |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][5], f[1][5], f[2][5], f[2][5], f[3][5], f[3][5], f[4][5], f[4][5], f[5][5], f[5][5], f[6][5], f[6][5], f[7][5], f[7][5] );
printf(" |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][5], f[1][5], f[2][5], f[2][5], f[3][5], f[3][5], f[4][5], f[4][5], f[5][5], f[5][5], f[6][5], f[6][5], f[7][5], f[7][5] );
printf(" 4 |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][4], f[1][4], f[2][4], f[2][4], f[3][4], f[3][4], f[4][4], f[4][4], f[5][4], f[5][4], f[6][4], f[6][4], f[7][4], f[7][4] );
printf(" |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][4], f[1][4], f[2][4], f[2][4], f[3][4], f[3][4], f[4][4], f[4][4], f[5][4], f[5][4], f[6][4], f[6][4], f[7][4], f[7][4] );
printf(" 3 |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][3], f[1][3], f[2][3], f[2][3], f[3][3], f[3][3], f[4][3], f[4][3], f[5][3], f[5][3], f[6][3], f[6][3], f[7][3], f[7][3] );
printf(" |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][3], f[1][3], f[2][3], f[2][3], f[3][3], f[3][3], f[4][3], f[4][3], f[5][3], f[5][3], f[6][3], f[6][3], f[7][3], f[7][3] );
printf(" 2 |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][2], f[1][2], f[2][2], f[2][2], f[3][2], f[3][2], f[4][2], f[4][2], f[5][2], f[5][2], f[6][2], f[6][2], f[7][2], f[7][2] );
printf(" |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][2], f[1][2], f[2][2], f[2][2], f[3][2], f[3][2], f[4][2], f[4][2], f[5][2], f[5][2], f[6][2], f[6][2], f[7][2], f[7][2] );
printf(" 1 |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][1], f[1][1], f[2][1], f[2][1], f[3][1], f[3][1], f[4][1], f[4][1], f[5][1], f[5][1], f[6][1], f[6][1], f[7][1], f[7][1] );
printf(" |%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|%c%c|\n", f[1][1], f[1][1], f[2][1], f[2][1], f[3][1], f[3][1], f[4][1], f[4][1], f[5][1], f[5][1], f[6][1], f[6][1], f[7][1], f[7][1] );
printf(" ======================\n");
printf(" 1 2 3 4 5 6 7 \n");
}
void animation(int nach, int hohe, int wer)
{
int count, count1, count2; // Diverse Counter
int ch; // Zeichen der Spieler
int schritte; // Schritte nach rechts auf der X-Achse
int position; // Schritte nach unten auf der Y-Achse
position = hohe;
if ( wer == SPIELER1 ) // Zeichen setzen
ch = ZEICHEN1;
else
ch = ZEICHEN2;
switch ( nach ) // Schritte auf der X-Achse anpassen...
{
case 1: schritte = 7; break;
case 2: schritte = 10; break;
case 3: schritte = 13; break;
case 4: schritte = 16; break;
case 5: schritte = 19; break;
case 6: schritte = 22; break;
case 7: schritte = 25; break;
default: puts("Fehler");
} ;
// Der Kran erscheint links...
a[0][1] = '|';
a[1][1] = ch;
a[2][1] = ch;
zeige_spielfeld();
sleep(SPEED);
a[0][2] = '|';
a[1][2] = ch;
a[2][2] = ch;
zeige_spielfeld();
sleep(SPEED*2);
for(count=1;count<schritte;count++) // Findet X-Position und stoppt
{
a[0][count] = ' ';
a[1][count] = ' ';
a[2][count] = ' ';
a[0][count+2] = '|';
a[1][count+2] = ch;
a[2][count+2] = ch;
zeige_spielfeld();
sleep(SPEED-(count*3));
}
// Stein vom Kran lösen...
a[0][count+0] = '|';
a[0][count+1] = '|';
a[1][count+0] = ' ';
a[1][count+1] = ' ';
a[2][count+0] = ' ';
a[2][count+1] = ' ';
f[nach][6] = ch;
zeige_spielfeld();
sleep(SPEED+50);
for(count1=(6);count1>position;count1--) // Stein in Spalte fallen lassen
{
f[nach][count1] = ' ';
f[nach][count1-1] = ch;
zeige_spielfeld();
sleep(SPEED);
}
for( ; count>(-1);count--) // Fährt "Heber" zurück
{
a[0][count+1] = ' ';
a[0][count-1] = '|';
zeige_spielfeld();
sleep(SPEED);
}
sleep(SPEED*2);
for(count1=0;count1<3;count1++) // Initialisiert den oberen Bereich mit einem Leerzeichen
{
for(count2=0;count2<27;count2++)
{
a[count1][count2] = ' ';
}
}
}
void sleep(long dauer) // HÄLT DAS SYSTEM FÜR GEWISSE ZEIT AN
{
if ( dauer < 1 )
;
else
{
long tstart = clock();
long tend = 0;
while ( (tend - tstart) < dauer )
tend = clock();
}
}
int int_eingabe(int min, int max) // ERZWINGT EINGABE IM ANGEGEBENEN BEREICH
{
int cnt;
int var = (max+1);
int is_zahl = 0;
int austritt = NEIN;
int austritt2 = NEIN;
int tmp_int;
unsigned int lange = 0;
char tmp_string[10+1];
while ( austritt2 == NEIN ) // Legt Wertebereich fest
{
while ( austritt == NEIN )
{
printf("\nEingabe ==> ");
fgets(tmp_string, (10+1), stdin); // LIEßT STING EIN
lange = strlen(tmp_string);
for(cnt=0; cnt<(lange-1); cnt++) // lange-1, weil wir '\0' nicht vergleichen wollen
{
tmp_int = tmp_string[cnt];
is_zahl = isdigit(tmp_int);
if ( is_zahl == 0 ) // Wenn keine Ziffer --> Schleife startet neu
{
austritt = 0;
break;
}
else
austritt = 1; // Wenn nur Ziffern --> Beendet Schleife
}
var = atoi(tmp_string); // Umwandlung in ein Integer
if ( var < min || var > max )
{
austritt2 = NEIN;
austritt = NEIN;
}
else
austritt2 = JA;
}
}
return var;
}
int jn_frage(void) // ÜBERSETZT J/N in 1/0
{
char a = 'a';
char puf[20];
while ( strchr( "NnJj", a ) == NULL )
{
fgets(puf, 20, stdin);
a = *puf;
}
if (a == 'j' || a == 'J') {
return 1;
}
else
return 0;
}