PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tic Tac Toe


yxcvbnm3
14.08.2008, 12:05
Moin,
ich bin im moment dabei ( als zeitvertreib ) mir Tic tac toe zu coden...
ich habe eine frage zu den Routine abläufen, sprich: Siegüberprüfungen und Unentschieden...
ich werde beide gleich mal posten, für meine begriffe ist die Siegüberprüfung aufjedenfall zu lang... aber im endeffekt für mich der einzig händelbare weg, da ich nicht über große Pascalkenntnisse verfüge.
(kann auch nur mit der crt unit umgehen ...)

nun meine frage, hat einer von euch ne idee, wie man die siegüberprüfung im rahmen "meiner möglichkeiten ( so dass ich es noch verstehe ;) )" kürzen könnte?

procedure Sieger(courser:char;Spieler:string; var Sieg:boolean);
begin
if (Feld[1,1]=courser) and (Feld[1,2]=courser) and (Feld[1,3]=courser) then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
Sieg:=true;
end else
begin
if (Feld[2,1]=courser) and (Feld[2,2]=courser) and (Feld[2,3]=courser) then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
Sieg:=true;
end else
begin
if (Feld[3,1]=courser) and (Feld[3,2]=courser) and (Feld[3,3]=courser) then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
Sieg:=true;
end else
begin
if (Feld[1,1]=courser) and (Feld[2,1]=courser) and (Feld[3,1]=courser) then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
Sieg:=true;
end else
begin
if (Feld[1,2]=courser) and (Feld[2,2]=courser) and (Feld[3,2]=courser) then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
Sieg:=true;
end else
begin
if (Feld[1,3]=courser) and (Feld[2,3]=courser) and (Feld[3,3]=courser) then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
Sieg:=true;
end else
begin
if (Feld[1,1]=courser) and (Feld[2,2]=courser) and (Feld[3,3]=courser) then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
Sieg:=true;
end else
begin
if (Feld[1,3]=courser) and (Feld[2,2]=courser) and (Feld[3,1]=courser) then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
Sieg:=true;
end
else Sieg:=false;
end;
end;
end;
end;
end;
end;
end;
end;


Xpyder
14.08.2008, 15:15
Vielleicht hilft Dir das weiter. Ich habe es nicht getestet, weil ich jetzt grade keine Lust hatte, das TicTacToe Spiel selber drum herum zu programmieren. Aber es sollte eigentlich funktionieren. Such Dir eine der beiden Procedures aus und füge sie in Dein Programm ein.


{Erklaerung: Mit Feld2 leg ich ein eindimensionales Array auf das
zweidimensionale Array Feld. Damit wird die Abfrage leichter.
Das Feld2 setzt dabei die Felder auf diese Werte:
1 2 3
4 5 6
7 8 9
Ich fange normalerweise immer bei 0 an zu zaehlen - bei Indizes
oder in Arrays oder.... ueberall wenn ich programmiere. Weil Du
mit 1 arbeitest, fang ich hier auch mal mit 1 an.
Das "absolute" legt eine Variable "auf" eine andere drauf -
auf dieselbe Speicherstelle. Es gibt noch eine zweite
Moeglichkeit der Verwendung von "absolute" (betrifft Pointer),
aber das ist jetzt hier unwichtig.
Achso, falls nicht bekannt: inc(i) erhoeht die Variable i um 1.
(Man kann auch z.B. inc(i,5) machen, um sie um 5 zu erh”hen.)
Ich benutze das lieber (weils schnelleren Code erzeugt) als
das alte i:=i+1 }
procedure Sieger(courser:char;Spieler:string; var Sieg:boolean);
var Feld2: array[1..9]of char absolute Feld;
const Kombi: array[1..8,1..3]of byte=(
(1,2,3),(4,5,6),(7,8,9),(1,4,7),(2,5,8),(3,6,9),(1,5,9),(3,5,7));
var i:byte;
begin
i:=1;
repeat
sieg:=(Feld2[Kombi[i,1]]=courser) and (Feld2[Kombi[i,2]]=courser) and (Feld2[Kombi[i,3]]=courser);
inc(i);
until sieg or (i>8);
if sieg then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
end;
end;
{Zweite Variante - hier benutze ich noch eine weitere Variable und eine
weitere Schleife - um dann auch noch die zweiten Indizes von Kombi 1 bis 3
abzufragen}
procedure Sieger(courser:char;Spieler:string; var Sieg:boolean);
var Feld2: array[1..9]of char absolute Feld;
const Kombi: array[1..8,1..3]of byte=(
(1,2,3),(4,5,6),(7,8,9),(1,4,7),(2,5,8),(3,6,9),(1,5,9),(3,5,7));
var i,j:byte;
begin
i:=1;
repeat j:=1;
while (j<4) and (Feld2[Kombi[i,j]]=courser) do inc(j);
sieg:=j=4;
inc(i);
until sieg or (i>8);
if sieg then
begin
gotoxy(5,20);
write('Sieg!!! ',Spieler,' hat gewonnen! ');
end;
end;

Xpyder
14.08.2008, 15:22
Nachtrag:
Ich habe mal (1997) ein "4 Gewinnt" programmiert, mit (fast) beliebig groß wählbarem "Spielfeld". Dazu habe ich dann eine andere Methode benutzt, die damit arbeitet, von einem Spielstein aus die Wege "abzuschreiten" (mit Additions-/Subtraktions-Konstanten, also 0, -1 oder +1). Aber das wäre bei TicTacToe (weil das Feld konstante Größe hat und auch so klein ist und es maximal 8 Gewinnkombinationen gibt) mit Kanonen auf Spatzen geschossen.
Wenn trotzdem an sowas interessiert, kannst Du Dich ja nochmal melden.

yxcvbnm3
14.08.2008, 19:26
sry wenn ich jetzt nochmal nachfrage, aber ich wills halt verstehen und nicht einfach "vielen dank" und es dann in meinen code editieren...

mir fehlt gerade irgendwie die verknüpfung in folgendem stück:

var Feld2: array[1..9]of char absolute Feld;
const Kombi: array[1..8,1..3]of byte=(
(1,2,3),(4,5,6),(7,8,9),(1,4,7),(2,5,8),(3,6,9),(1,5,9),(3,5,7));

dass du das array feld2 über mein eigentliches Spielfeld gelegt hast, ist mir klar, aber ich kann mit dem "Kombi array" nix anfangen.
in den runden klammern stehen die möglichen sieg kombis, aber wie sind die mit array[1..8,1..3] verknüpft ??

PS: wegen dem beliebig großen Spielfeld, vllt komm ich später noch drauf zurück, aber im moment versuche ich mit dem Spiel zu "wachsen". sprich, erst mal nur eingabe, dann die routinen, mittlerweile bin ich bei ner ki, die man in 3 stufen einstellen kann ( leicht [setzt zufällig], normal [reagiert auf die züge des Spielers{ funktioniert nur leider nicht so ^^} und schwer [verfolgt seinen eigenen Plan])
also, mal sehen vllt demnächst ;)

Xpyder
14.08.2008, 19:55
Also erstmal: Es freut mich, daß sich mal einer auch wirklich dafür interessiert und sich nicht nur alles "vorbeten" läßt.

Also: zweidimensionales Array. Ich schreib es mal als Tabelle auf:


waagerecht = 1. Dimension, senkrecht = 2. Dimension

Index 1 2 3 4 5 6 7 8
--------------------------------------
1 1 4 7 1 2 3 1 2
2 2 5 8 4 5 6 5 5
3 3 6 9 7 8 9 9 7

An Stelle Kombi[3,2] steht also z.B. eine 8.


Die äußeren Klammern geben immer die ersten Dimensionen an, die inneren die letzten.

Beispiel für ein 3-Dimensionales Feld, das jeweils von Indizes von 1 bis 2 hat:

const Beispiel:array[1..2,1..2,1..2]=(((1,2),(3,4)),((5,6),(7,8)));


Kann ich jetzt schlecht grafisch darstellen, wäre ja dreidimensional und damit ein Würfel...

Hoffe, daß die Erklärung ausreicht.

yxcvbnm3
14.08.2008, 22:16
ok, nachdem ich mich jetzt noch mal 10 min hingesetzt habe, hab ich das jetzt verstanden :D wenn man sowas noch nie gesehen hat, dann muss man dass erst mal irgendwie verarbeiten ...
jetzt sag ich erst mal vielen dank ;) und vermutlich bis demnächst, kommen bestimmt noch ein paar fragen ;)


PS: hab die nächste idee, ich werde die einzelnen Spielmodi auslagern, wird sonst viel zu viel in einer datei, blick da jetzt schon nicht mehr durch ...

Xpyder
24.08.2008, 04:36
Ich hab neulich ein Konzept entwickelt, wie man den Computer intelligent kriegt. Funktioniert immer. Wenn Interesse, melde Dich.

yxcvbnm3
28.08.2008, 13:31
Ich habe mittlerweile die Spielroutine fertig, obwohl ich natürlich weiß, dass einige leute jetzt auf die barrikaden gehen werden, werde ich hier "nur" die .exe veröffentlichen... auf nachfrage, werde ich aber falls gewünscht hilfestellung geben.
zu meinen gründen sag ich nur, dass ich es hasse, wenn sich leute die programme aus dem internet besorgen und dann in der schule vorzeigen, dafür auch noch gute noten bekommen... Oft genug gesehen und auch mir schon oft genug passiert! Wenn die leute sich wenigstens mit der Materie noch beschäftigen würden ... nein, programm ist doch schon fertig. warum noch ?


PS: ich denke jeder, der pascal in der schule hatte, weiß, dass vor allem tictactoe sehr beliebt ist, als kleine aufgabe ... von daher möchte ich hier einfach nur nen anreiz geben, wie es aussehen könnte

Diogenes
28.08.2008, 19:26
Als Konsolengeschichte schonmal nicht schlecht. Ich hätt aber was zur UI zu sagen:


Die Menüauswahl sollte kein ENTER brauchen, nimm ReadKey und KeyPressed (unit CRT, glaub ich) statt des Read bzw. ReadLn.
Bei der Eingabe der Koordinaten hätt' ich mich von der Schachnotation inspirieren lassen (a1 für links oben usw.), um das auf eine Eingabe zu reduzieren.


Im Übrigen bist Du ja keineswegs verpflichtet, den Quellcode zu veröffentlichen. Ich verstehe deinen Grant, daß man Dir den Code stiehlt - so war das nämlich ursprünglich gemeint mit dem Urheberrecht und nicht so, wie sich's jetzt abspielt.

yxcvbnm3
29.08.2008, 09:20
Die Menüauswahl sollte kein ENTER brauchen, nimm ReadKey und KeyPressed (unit CRT, glaub ich) statt des Read bzw. ReadLn.
Bei der Eingabe der Koordinaten hätt' ich mich von der Schachnotation inspirieren lassen (a1 für links oben usw.), um das auf eine Eingabe zu reduzieren.

das mit dem readkey hatte mir Xpyder auch schon gesagt, nur ich persönlich finde, die lösung mir readkey nicht so dolle... du gibst ne zahl ein und direkt wird die umgesetzt... mir z.b. passierts andauernt, dass ich mich vertippe, da ist das natürlich doof, da man nicht mehr wirklich korrigieren kann.
aber mal ne andere frage, ich hab das eben mal auf meinem rechner zu hause durchlaufen lassen und da wurde als die einblendung mit sieg kam, mein spielfeld ( die striche) unleserlich. habt ihr das bei euch auch ? Ich frag, weil auf dem pc auf der arbeit nicht der fall ist.

Diogenes
29.08.2008, 11:49
das mit dem readkey hatte mir Xpyder auch schon gesagt, nur ich persönlich finde, die lösung mir readkey nicht so dolle... du gibst ne zahl ein und direkt wird die umgesetzt... mir z.b. passierts andauernt, dass ich mich vertippe, da ist das natürlich doof, da man nicht mehr wirklich korrigieren kann.
aber mal ne andere frage, ich hab das eben mal auf meinem rechner zu hause durchlaufen lassen und da wurde als die einblendung mit sieg kam, mein spielfeld ( die striche) unleserlich. habt ihr das bei euch auch ? Ich frag, weil auf dem pc auf der arbeit nicht der fall ist.
Punkt 1: Ein ESC zum vorigen Menüpunkt einbauen. Damit ist eine traversierende Navigation im Menübaum möglich.

Punkt 2: Ich hab das auf einem in einer VirtualBox isntallierten XP gemacht. Grafik ist da immer eigenartig, also kann ich da nix sagen.

yxcvbnm3
29.08.2008, 12:13
Punkt 1: Ein ESC zum vorigen Menüpunkt einbauen. Damit ist eine traversierende Navigation im Menübaum möglich.

kenn ich leider den befehl nicht für, also für die esc abfrage. daher hab ich das ja mit Ziffer 9 versucht zu umgehen.... wenn mir den einer sagen kann, mach ichs


Punkt 2: Ich hab das auf einem in einer VirtualBox isntallierten XP gemacht. Grafik ist da immer eigenartig, also kann ich da nix sagen.

mh, vllt liegts auch am compiler ? ich benutz freepascal...

Xpyder
30.08.2008, 05:51
kenn ich leider den befehl nicht für, also für die esc abfrage. daher hab ich das ja mit Ziffer 9 versucht zu umgehen.... wenn mir den einer sagen kann, mach ichs

mh, vllt liegts auch am compiler ? ich benutz freepascal...

Es liegt nicht am Compiler. Es liegt am Zeichensatz.
DOS benutzt standardmäßig den Zeichensatz Codepage 437. Der enthält auch diese Kästchen- und Rähmchen-Zeichen.
Andere Systeme (Windows) benutzen den Zeichensatz Codepage 850 (entspricht den ersten 256 Zeichen von Unicode). Der hat an der Stelle auch Buchstaben, und zwar diese "erweiterten", also äöüÄÖÜáéíóúàèìòùâêîôû und so weiter... Meiner Meinung nach müßten also z.B. an der Stelle, wo bei Dir die waagerechten Rähmchen sind, in 850er Zeichensatz lauter ÄÄÄÄ stehen.
Windows hat mal den 852er Zeichensatz benutzt, in dem nur einige Rähmchen ersetzt wurden (die, wo doppelte und einfache kombiniert waren) und wo alle Umlaute 2x vorkamen, einmal in 437er und einmal in 850er Position. Dieser 852er war meiner Meinung nach so eine Art "Hybrid" zwischen 437 und 850.
Abhilfe kann man schaffen, indem man unter Windows in Vollbild schaltet. Wenn das allein nicht helfen sollte, kann man in Vollbild schalten und einen eigenen (manipulierten) Textmode-Zeichensatz laden. (Ja, das geht.) Oder man machts gleich in Grafik. Die besteht aus Pixeln. Und im Gegensatz zu Zeichensatz-Zeichen sehen Pixel überall gleich aus...

Diogenes
30.08.2008, 11:08
kenn ich leider den befehl nicht für, also für die esc abfrage. daher hab ich das ja mit Ziffer 9 versucht zu umgehen.... wenn mir den einer sagen kann, mach ichs
..

Das gibt's keinen eigenen Befehl im Pascal selbst. Ich hab damit nur einen zusätzlichen, von dir zu definierenden Befehl gemeint, der die Wirkung hat, zum übergeordenten Menüpunkt zurückzukehren. Beliebt sind eben die ESC-Taste (#027) und 0 (#048).

Xpyder
31.08.2008, 16:42
@yxcvbnm:
(Deinen Nick kann man schön schnell eintippen. Das war wohl auch die Intention dabei...)
Achja, zum Thema der Unit CRT nochmal:
Du sagst ja, Du benutzt Freepascal - ich hoffe, daß die CRT von Freepascal nicht diesen beschissenen "Schönheitsfehler" hat, den die CRT von Borland's Turbo Pascal hat... ("Runtime Error 200" auf "zu schnellen" Rechner, wegen der Rechnergeschwindigkeitsermittlungsschleife, die CRT immer am Programmanfang ausführt, auch wenn man den DELAY Befehl gar nicht benutzt...)

Wenn Du wissen willst, wie readkey funktioniert und wie man "Nicht-Buchstaben/Zahlen-Tasten" abfragt (ESC, Cursortasten, TAB, BILD usw), kannste ja mal anfragen. Oder falls Interesse an einigen meiner Units oder anderen Dingen zu Pascal, wäre ich wohl derjenige, den Du hier fragen kannst. (Gibt ja nicht mehr so viele Pascal-Programmierer.)

Btw: Habe auch mal Dein Tic-Tac-Toe runtergeladen und angezockt. Ja, ist schon nett gemacht - funktioniert auch ganz prima.

Diogenes
31.08.2008, 19:36
Hat sie nicht, ist komplett frisch gecodet, schon allein wegen der Links- -- äh -- Rechtslage.

yxcvbnm3
01.09.2008, 16:46
@yxcvbnm:
(Deinen Nick kann man schön schnell eintippen. Das war wohl auch die Intention dabei...)

jo, das war sie ;)


Wenn Du wissen willst, wie readkey funktioniert und wie man "Nicht-Buchstaben/Zahlen-Tasten" abfragt (ESC, Cursortasten, TAB, BILD usw), kannste ja mal anfragen.
das wäre meine nächste frage hier gewesen, ich hatte dir übrigens sonst noch ne mail geschickt, aber nix mehr zurück bekommen ?!


Btw: Habe auch mal Dein Tic-Tac-Toe runtergeladen und angezockt. Ja, ist schon nett gemacht - funktioniert auch ganz prima.

habe mittlerweile schon wieder etwas dran modifiziert, aber eigentlich bin ich jetzt so weit, dass ich sage, dass das programm fertig ist ( werde noch die esc abfrage implentieren, sofern mir das einer erklärt, dann wars das aber. )



PS: ich hab früher Borland gehabt, aber der hat bei mir immer rumgezickt, seit ich freepascal hab funktioniert eigentlich alles super.

Diogenes
01.09.2008, 18:22
Nioch einmal: Dabei handelt es sich nur um eine Eingabe, die zum übergeordneten Menüpunkt zurückführt.

yxcvbnm3
04.09.2008, 18:29
Nioch einmal: Dabei handelt es sich nur um eine Eingabe, die zum übergeordneten Menüpunkt zurückführt.


ESC hab ich jetzt komplett umgangen, 9 ist während des kompletten Spiels die "Abbruchtaste".
Hier nochmal die vermutlich letzte version...

Diogenes
04.09.2008, 19:10
Nioch einmal: Dabei handelt es sich nur um eine Eingabe, die zum übergeordneten Menüpunkt zurückführt.
So in etwa hab ich das auch gemeint.