Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Borland C++ Builder » Vier gewinnt ANSI C

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
25.12.2007, 14:45 Uhr
~Speedy01
Gast


Hallo,

Ich muss für die Schule ein 'grafisches' Vier-Gewinnt Spiel unter Turbo-C schreiben.

Ich versuche nun schon seit Wochen, den Einzelspielermodus zum laufen zu bringen, aber es klappt einfach nicht.

Kann mir vielleicht jemand helfen?

http://forum.hackit-thegame.de/images/viergewinnt.txt <-- Hier ist mein kompletter Quellcode... nichts aufwendiges, aber fürs projekt ausreichend(wenn es funktionieren würde^^)

Schonmal Danke im Vorraus für die Hilfe

mfG
Speedy01

Ps: Der Rest funktioniert alles
Pps: Noch Frohe Weihnachtstage
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
25.12.2007, 19:46 Uhr
0xdeadbeef
Gott
(Operator)


"void main()" - sowas kauft der Compiler dir ab?

Naja, mit ANSI-C hat das erstmal herzlich wenig zu tun, also schieb ich das ganze mal rüber ins Borland-Forum.

Ansonsten, ne wirklich vernünftige KI zu schreiben, dürfte wohl über ein Schulprojekt hinausgehen - da bewegen wir uns in sehr komplexer Materie. Was deinen einfachen Algorithmus da angeht (Kann ich gewinnen? Gewinne! Kann Gegner gewinnen? Verhindere! Ansonsten, zieh zufällig.), das würd ich wohl mit der Gewinnprüfung verbinden; große Teile des Codes dürften sich ja überlagern. Denkbar wäre, über alle freien Felder zu iterieren, einen Zug zu simulieren und zu prüfen, ob der Zug gewinnt. Nicht die schnellste Methode, sollte aber für den Zweck ausreichen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
27.12.2007, 14:00 Uhr
~Speedy01
Gast


Danke für den Hinweis.
Ich habe auch schon daran gedacht, aber ich möchte jetzt ungern den Großteil meines Codes wegwerfen/überarbeiten... Zumal es auch nicht mehr so viel Zeit bis zur Abgabe gibt und auch die Planung(Struktogramme) schon soweit getippt sind.

Gibt es vielleicht jemanden, der sich mal den Code genauer ansehen könnte und eventuell den Fehler in der jetzigen Version findet?


Wäre echt super



mfG
Speedy01
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
27.12.2007, 21:35 Uhr
0xdeadbeef
Gott
(Operator)


Struktogramme? Ich erinner mich noch daran, das sollten wir in der Schule auch machen. Brauchste nie wieder, nicht mal in der Uni. Und da setzen sie dir nen Haufen völlig unanwendbarer Ideen über perfekte Softwareentwicklung in den Kopf .

Ich kann das hier nicht kompilieren, mangels Turbo-C (ein standardkonformer Compiler kauft dir den Code nicht ab, selbst wenn er die Bibliotheken kennt), aber was mir so direkt ins Auge fällt ist, dass in void Computer() die "Kann ich gewinnen?"-Zeile auskommentiert ist, der Computer also nicht prüft, ob er gewinnen kann.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 27.12.2007 um 21:36 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
28.12.2007, 03:09 Uhr
Hans
Library Walker
(Operator)


Hi,

also... meine Version 3.0 von Turbo-C meldet 2 Warnungen und einen Fehler:

Zeile 132:Warning: Function should return a value in der Funktion Spielende. Das ist wirklich eine gute Idee, weil die Funktion gemäss ihrer Definition einen Wert zurück geben soll. Das tut sie aber nicht.

C++:
int Spielende(int win) {
cleardevice();
switch(win)
{
case -1: outtext("unentschieden");
  break;
case 1: outtext("Spieler 1 gewinnt");
  break;
case 2: if(gModus == 2)
      outtext("Spieler2 gewinnt");
     else
      outtext("Computer gewinnt");
}
gModus = 3;
/* hier: return ... ;  einfügen */
}



Zeile 357: Warning: possibly incorect assignment in der Funktion Kann_Computer_gewinnen()
Da lesen wir:

C++:
   if(i=3)



Das ist nicht nur möglicherweise, sondern garantiert eine falsche Zuweisung, weil es ja gar keine Zuweisung sondern ein Vergleich sein soll. Also ersetzen durch:

C++:
   if(i==3)



Zeile 523: Error: Declaration not allowed here in der Funktion Aufbau_Spielfeld()


C++:
void Aufbau_Spielfeld() {
                /*         <---+       */
cleardevice();  /*             |       */
                /*             |       */
int s, z, r;    /* Das muss da ^ hin.  */
settextstyle(1, 0, 2);
...


Die Variablendefinition muss vor dem Aufruf der Funktion cleardevice() stehen.

Nachdem ich das geändert hatte, hat der Compiler nichts mehr zu meckern gehabt, und ich hab ein lauffähiges Programm erhalten. Ansonsten hab ich mir die Logik noch nicht näher angesehen. Vielleicht könntest Du mal beschreiben, wo es in dem Modus genau hakt. D.h. beschreiben, was eigentlich passieren sollte, aber nicht passiert, oder was stattdessen passiert.

Nebenbei:

Zitat von 0xdeadbeef:

Struktogramme?


Da sind wir doch mal wieder einer Meinung...
Und was hälst du von Flussdiagrammen?

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 28.12.2007 um 03:38 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
28.12.2007, 14:53 Uhr
~Speedy01
Gast


ok, also... das auskommentierte war nur noch da, weil ich erstmal den rest testen wollte.

das die Funktion Spielende keinen Rückgabewert hat ist derzeit auch richtig so... Das indirekte return ist die variable gModus.... Ist halt noch global. wird aber später, wenn alles läuft noch rausgenommen und übergeben.

Das mit der Deklaration in "Aufbau Spielfeld" und i == 3 habe ich auch geändert.

So nun zum Ablauf:

grob:
Er soll prüfen, ob der Computer gewinnen kann. Wenn das nicht möglich ist, prüft er, ob der Spieler gewinnen kann und wenn das auch nicht geht, setzt er zufällig einen Spielstein.

Das Problem liegt nur in den Funktionen "Kann_Computer_gewinnen" und "Kann_Gegner gewinnen"

Darin sollte zuerst geprüft werden, ob drei gleiche Steine vertikal, dannach horizontal und dann diagonal liegen. Wenn es so ist, soll er einen eigenen Stein an die vierte freie Stelle dann werfen.
Leider klappt das überhaupt nicht. Er setzt brav seine zufälligen Steine. Allerdings fängt er dann bei den Prüfungen komische Sachen an, sodass dann einfach mehrere Steine vom Computer gesetzt werden(auch außerhalb des Spielfeld). Das geht soweit, das sich das Programm dann "aufhängt" bzw. ich nicht mehr aus dem Spiel komme.. nur noch mit einem User-Break


Also kann es nur in den beiden oben genannten Funktionen zu Problemen kommen

mfG
Speedy01
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
01.01.2008, 23:21 Uhr
Hans
Library Walker
(Operator)


Hi,

also das Phänomen hatte ich auch bei meinem Testlauf: Steine neben dem Spielfeld, alle freien Felder vom Computer belegt, und nichts ging mehr, ausser das Ding "gewaltsam" zu beenden, d.h. die gesamte DOS-Box zu schliessen. Der User-break war bei mir übrigens auch blockiert, sofern ich das Selbe damit meine, wie Du.

Hast Du schon mal was von dem Debugger gehört? Das ist ein Programm, zur Fehlersuche. Du kannst zum Beispiel mit "Run/Trace into" Dein Programm Schrittweise ausführen lassen. Da er dabei häufig zwischen der Grafik und dem Textbildschirm hin und her schaltet, sieht die Grafik irgendwann nicht mehr ganz so toll aus, aber so sollte nicht zu sehr stören. Interessant sind auch noch die "watches". Damit lassen sich Variablenwerte beobachten. Einfach per "Debug/Watches/Add watch" einen Variablennamen angeben. Es wird dann ein zusätzliches Fenster geöffnet, wo man die Variablenwerte beobachten kann, wenn das Programm läuft. Es ist nämlich zu vermuten, das irgendwo eine Variable einen Wert annimmt, den sie nicht annehmen darf. Am besten probierst Du das erst mal mit einem Programm aus, das keine Grafik benutzt. Wenn das Prinzip klar ist, kannst Du mit diesem Wissen das 4-Gewinnt-Programm untersuchen.

So, das ist jetzt vielleicht nicht gerade das, was Du erwartet hast, aber ein Weg, wie Du den Fehler selber finden kannst.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
02.01.2008, 00:39 Uhr
Hans
Library Walker
(Operator)


Hi, ich noch mal.

Ich hab mir das Programm auch noch mal mit dem Debugger vorgenommen, bin aber nicht sehr weit gekommen, weil sich der Debugger nicht mit Windows verträgt. Das äusserte sich dadurch, das der PC auf einmal einen Neustart durchgeführt hat, obwohl er eigentlich nur den nächsten Befehl des Programms ausführen sollte... - Da ich nicht weis, wo in diesem Fall der Hase begraben liegt, komm ich auch nicht weiter.

(Für die Spezialisten: Turbo C++ V3.0 für DOS, in einem DOS-Fenster unter Windoof 95b. Bei einem Druck auf F7 (Trace) kam der Neustart. - Ich nehme an, das hat was damit zu tun, das der Debugger zwischen dem Grafik- und dem Textmodus hin und her schaltet, und dabei irgendwelche Zeiger von Windows verbiegt, oder (versehentlich?) gleich (an Windows vorbei) in die Warmstartroutine des BIOS springt... - Hab aber keine wirkliche Ahnung. )

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 02.01.2008 um 00:40 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
02.01.2008, 00:59 Uhr
0xdeadbeef
Gott
(Operator)


Da hab ich doch mal...ah, hier:

C++:
#include <stddef.h>
#include <stdio.h>
#include <string.h>

#ifndef HOEHE
#define HOEHE  5
#endif

#ifndef BREITE
#define BREITE 7
#endif

#ifndef GEWINNT
#define GEWINNT 4
#endif

#define RED    31
#define YELLOW 33

#define COLOR_CHANGE_I(num)  "\x1B[" #num "m"
#define COLOR_CHANGE(num)    COLOR_CHANGE_I(num)

#define COLOR_CHANGE_FMT     COLOR_CHANGE(%d)
#define COLOR_CHANGE_DEFAULT COLOR_CHANGE(0)

typedef struct {
  int spielfeld[BREITE][HOEHE];
  int tops[BREITE];
} spiel_t;

static int const players[] = { RED, YELLOW };

static void spiel_t_init(spiel_t *this) {
  size_t i;

  memset(this->spielfeld, 0, sizeof(this->spielfeld));
  for(i = 0u; i < BREITE; ++i) {
    this->tops[i] = HOEHE;
  }
}

static int spiel_t_gewonnen(spiel_t const *this, size_t x, size_t y) {
  int farbe = this->spielfeld[x][y];
  int i, j, tmp;

  /* senkrecht */
  tmp = 1;
  for(j = y + 1; j < HOEHE && this->spielfeld[x][j] == farbe; ++j, ++tmp);
  if(tmp >= GEWINNT) return 1;

  /* waagerecht */
  tmp = 1;
  for(i = x - 1; i >=      0 && this->spielfeld[i][y] == farbe; --i, ++tmp);
  for(i = x + 1; i <  BREITE && this->spielfeld[i][y] == farbe; ++i, ++tmp);
  if(tmp >= GEWINNT) return 1;

  /* diagonal \ */
  tmp = 1;
  for(i = x - 1, j = y - 1; i >=      0 && j >=     0 && this->spielfeld[i][j] == farbe; --i, --j, ++tmp);
  for(i = x + 1, j = y + 1; i <  BREITE && j <  HOEHE && this->spielfeld[i][j] == farbe; ++i, ++j, ++tmp);
  if(tmp >= GEWINNT) return 1;

  /* diagonal / */
  tmp = 1;
  for(i = x - 1, j = y + 1; i >=      0 && j <  HOEHE && this->spielfeld[i][j] == farbe; --i, ++j, ++tmp);
  for(i = x + 1, j = y - 1; i <  BREITE && j >=     0 && this->spielfeld[i][j] == farbe; ++i, --j, ++tmp);
  if(tmp >= GEWINNT) return 1;

  return 0;
}

static void spiel_t_print(spiel_t const *this) {
  int x, y;

  for(y = 0; y < HOEHE; ++y) {
    for(x = 0; x < BREITE; ++x) {
      if(this->spielfeld[x][y] == 0) {
        printf("| ");
      } else {
        printf("|" COLOR_CHANGE_FMT "*" COLOR_CHANGE_DEFAULT, this->spielfeld[x][y]);
      }
    }
    puts("|");
  }

  for(x = 0; x < BREITE * 2 + 1; ++x) putchar('-');
  putchar('\n');
  for(x = 0; x < BREITE; ++x)
    printf("%2d", x + 1);
  putchar('\n');
}

static int spiel_t_eingabe(spiel_t const *this, int farbe) {
  char zeile[100];
  int slot;

  do {
    printf(COLOR_CHANGE_FMT "1-%d: " COLOR_CHANGE_DEFAULT, farbe, BREITE);
    fflush(stdout);

    fgets(zeile, 100, stdin);
  } while(sscanf(zeile, "%d", &slot) != 1 ||
      slot < 1 ||
      slot > BREITE ||
      this->tops[slot - 1] == 0);

  return slot - 1;
}

static int spiel_t_play(spiel_t *this) {
  int player_ix = 1, x, y;

  spiel_t_init(this);
  spiel_t_print(this);

  do {
    player_ix = (player_ix + 1) % 2;

    x = spiel_t_eingabe(this, players[player_ix]);

    y = --this->tops[x];

    this->spielfeld[x][y] = players[player_ix];
    spiel_t_print(this);
  } while(!spiel_t_gewonnen(this, x, y));

  return player_ix;
}

int main(void) {
  spiel_t spiel;

  printf(COLOR_CHANGE_FMT "GEWONNEN!" COLOR_CHANGE_DEFAULT "\n", players[spiel_t_play(&spiel)]);

  return 0;
}


...das benutzt jetzt ANSI escape sequences für die Farben, die sind unter Windows von Haus aus, glaube ich, nicht aktiv. Unter DOS konnte man das mit der ansi.sys laden, unter Windows...ging das auch irgendwie. Wenn du das nicht rauskriegst, sollte es aber leicht genug anpassbar sein, halt überall, wo die COLOR_CHANGE-Makros benutzt werden, die Farbe mit den Borland-Funktionen ändern.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 02.01.2008 um 01:14 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
02.01.2008, 14:29 Uhr
~Speedy01
Gast


Also mit dem Debugger habe ich es schon versucht... nur ist dieser unter Turbo C mehr als schlecht und macht alles, aber nicht das, was er soll

Somit habe ich das ganze dann auch schnell wieder gelassen und suche nun seid Tagen schon Denkfehler, aber ich finde da einfach nicht.... und der Abgabetermin rückt immer und immer näher^^
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ Borland C++ Builder ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: