PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfe bei TTT ähnl. Game


MorVis
21.09.2003, 22:34
Hi,
ich bin mir nicht sicher, ob das hier rein gehört, aber mal sehen...

Ich fang' mal vorne an...im Untericht wurde mir und einem Klassenkameraden langweilig, und wir spielten TTT (Tic Tac Toe). Doch das hat dann keinen Spaß mehr gemacht und wir haben uns eine Variante ausgedacht. "T!"

Der Sinn ist es auf einem 7*7 Feld großem Plan ein T zu bauen.
Nun wollte ich das Programmieren, doch ich bekomme es nicht hin, wann wer gewonnen hat...

Es gibt zu viele Möglichkeiten um diese alle abzufragen.
Kennt jemand eine Methode, um dies kürzer zu machen???

Hier ein kleines Schaubild:


Das Spielfeld:

|01|02|03|04|05|06|07|
|08|09|10|11|12|13|14|
|15|16|17|18|19|20|21|
|22|23|24|25|26|27|28|
|29|30|31|32|33|34|35|
|36|37|38|39|40|41|42|
|43|44|45|46|47|48|49|

Ein T Muss herauskommen:

z.B:

|01|XX|XX|XX|05|06|07|
|08|09|XX|11|12|13|14|
|15|16|XX|18|19|20|21|
|22|23|24|25|26|27|28|
|29|30|31|32|33|34|35|
|36|37|38|39|40|41|42|
|43|44|45|46|47|48|49|

Ich komme einfach nicht weiter, bitte helft mir!! :mauer:


P.S. Jedes Feld kann nur einmal gewählt werden, musste nur XX Nehmen, wegen des Platzes ;)


Poison Nuke
22.09.2003, 10:03
Ich würde das Spielfeld als Array[1..49] of byte deklarieren.
Dann machst du folgende Vereinbarung:
Wert 0: Feld ist nicht belegt
Wert 1: Spielstein von Player 1
Wert 2: Spielstein von Player 2

D.h. die einzelnen stellen im Array können nur einen der drei Werte annehmen.

Jetzt machst du so eine Schleife:

FOR i:=1 TO 33 DO
IF array[i]>0 THEN
IF array[i]=array[i+1] THEN
IF array[i]=array[i+2] THEN
IF array[i]=array[i+8] THEN
IF array[i]=array[i+15] THEN
{Player x hat ein T erstellt}


Das ist mir jetzt aber nur so eingefallen...vllt gibt es ja noch eine effektivere Variante.

MorVis
22.09.2003, 15:17
Danke erstmal...
Kannst du mir das bitte ein bischen genauer erklären, ich möchte nämlich ein Java-Applet damit schreiben....

Sorry aber ich bin noch ziemlich neu auf dem Gebiet ;)

Poison Nuke
22.09.2003, 15:47
oh, nagut, ich dachte, das sei kein problem :D


Also, ein Array kennst du hoffentlich?
(Ist mit eine der wichtigsten Datenstrukturen in der Informatik)

Also du erstellst ein eindimensionalen Array, und zwar vom Typ byte am besten (ist zwar hier nicht soo wichtig, aber besser man nimmt immer die kleinstmögliche Datenmenge).

Dann legst du für dich fest:
Wenn ein Feld im Array den Wert 0 enthält, dann ist an dieser Stelle kein Spielstein.
Wenn es den Wert 1 oder 2 enthält, dann ist ein Spielstein von Spieler 1 od. 2 an dieser Stelle...andere Werte darf der Array jetzt nicht annehmen.

Jetzt erstellst du eine Schleife, und zwar geht die das Spielfeld (den Array) vom ersten Feld bis zum Feld 33 durch (33 deswegen, da nur bis hier ein T möglich wäre).
In dieser Schleife werden jetzt die einzelnen Felder der Arrays geprüft:

Zuerst, ob an der Stelle überhaupt ein Spielstein ist (array[i]>0),
wenn das der Fall ist, dann wird überprüft, ob an der Nachfolgenden Position der gleiche Spielstein ist, wenn das auch der Fall ist, dann wird das aktuelle Feld mit allen anderen Feldern verglichen, die nötig sind, für ein T...wenn alle Bedingungen korrekt sind, dann kann bei der letzten IF Bedingung gesagt werden "Player "array[i]" hat als erster ein 'T' erschaffen", oder so ähnlich.

MorVis
22.09.2003, 16:00
ah... aber wie kommst auf 33?
das T könnte ja auch so aussehen :

|01|02|03|04|05|06|07|
|08|09|10|11|12|13|14|
|15|16|17|18|19|20|21|
|22|23|24|25|26|27|28|
|29|30|31|32|33|XX|35|
|36|37|38|39|40|XX|42|
|43|44|45|46|XX|XX|XX|

Poison Nuke
22.09.2003, 16:07
also wenn du sagst 'T', dann gibt es für mich nur ein aufrechtstehendes T....das andere würde für mich eigentlich nicht in frage kommen :eek:

Aber wenn du wirklich noch so eine zweite Form einbauen willst (was ich eigentlich nicht machen würde), dann musst du noch eine zweite Prüfroutine einbauen, die dann auch wieder die Felder überprüft...wobei dann aber vllt ein effektiverer Algo wünschenswert wäre...mir fällt aber nix besseres ein :(

MorVis
22.09.2003, 16:19
könnte man nicht eine zweite Schleife drch laufen lassen?

Z.B

FOR i:=1 TO 34 DO
IF array[i]>0 THEN
IF array[i]=array[i+7] THEN
IF array[i]=array[i+13] THEN
IF array[i]=array[i+14] THEN
IF array[i]=array[i+15] THEN
{Player x hat ein T erstellt}


würde das gehen?

Poison Nuke
22.09.2003, 16:28
würde auch gehen, würde aber auch doppelt so lange dauern vond er Zeit her....pack es in eine Schleife rein ;)

MorVis
22.09.2003, 16:34
kannst mir einmal beschreiben wie ich ein byte Array mit Java erstelle (dann muss ich nicht nach nem Tut suchen;) )?
thx

Jan Krüger
22.09.2003, 18:05
Hilf dir selbst, so hilft dir Gott. :p

MorVis
22.09.2003, 18:14
Hab ich schon... nur wie ich ein byte-array erstelle hab ich nicht gefunden!
Kannst du mir helfen?

Jan Krüger
22.09.2003, 20:12
So, wie man jedes andere Array auch erstellt.
typ[] var;

The_Friendly_C#Guide
26.11.2003, 22:36
//...
for (int i=0;i<feld.Length;i++)
{
if (checkwin(i))
{
MessageBox.Show("gewonnen");
}

}

//...

private bool checkwin(int feldNr)
{
if (feld[feldNr]==0) return false;
int sd=this.sd(feldNr);
if (sd>=0)
{
int wd=this.wd(feldNr);
if (wd>=0)
{
if ((wd==sd) && ((wd==1) || (wd==0))) return false;
return true;
}
}
return false;
}
/// <summary>
/// Waagrechter Dreier?
/// </summary>
/// <param name="feldNr">Die zu Überprüfende FeldNr</param>
/// <returns>0=Außen 1=Mitte 2=Außen&Mitte</returns>
private int wd(int feldNr)
{
int mod=feldNr%feldSize.Width;
int rv=-1;
if ((mod > 0) && (mod < (feldSize.Width-1)))
if (feld[feldNr]==feld[feldNr-1] && feld[feldNr]==feld[feldNr+1]) rv=1;
if ((mod < (feldSize.Width-2)))
if (feld[feldNr]==feld[feldNr+1] && feld[feldNr]==feld[feldNr+2]) rv++;
if ((mod > 2))
if (feld[feldNr]==feld[feldNr-1] && feld[feldNr]==feld[feldNr-2]) rv++;
return rv;
}
/// <summary>
/// Senkrechter Dreier?
/// </summary>
/// <param name="feldNr">Die zu Überprüfende FeldNr</param>
/// <returns>0=Außen 1=Mitte 2=Außen&Mitte</returns>
private int sd(int feldNr)
{
int rv=-1;
if ((feldNr>=feldSize.Width) && (feldNr<=(feld.Length-feldSize.Width)))
if (feld[feldNr]==feld[feldNr-feldSize.Width] && feld[feldNr]==feld[feldNr+feldSize.Width]) rv=1;
if (feldNr<=(feld.Length-feldSize.Width-feldSize.Width))
if (feld[feldNr]==feld[feldNr+feldSize.Width] && feld[feldNr]==feld[feldNr+feldSize.Width+feldSize.Width]) rv++;
if (feldNr>=(feldSize.Width+feldSize.Width))
if (feld[feldNr]==feld[feldNr-feldSize.Width] && feld[feldNr]==feld[feldNr-feldSize.Width-feldSize.Width]) rv++;
return rv;
}

Und mit [code]-Tags sieht's noch viel toller aus... :p -- Jan

The_Friendly_C#Guide
26.11.2003, 22:48
Der Code besteht aus 4 Teilen:

1 Eine For Schleife über alle Felder

2 Teil eine Funktion die überprüft ob das Feld Teil eines Senkrechten und eines Wagrechten Dreiers ist. (Und ob die Dreier richtig zueinander stehen)

3. und 4. Die Unterfunkionen die schauen ob ein Feld Teil eines waagrechten bzw. senkrechten Dreiers ist.
----------------------------------------------------------------------------

Das Spiel macht richtig Spass, hat jemand eine Idee für einen würdigen Computerspieler?

Ich weis meine Erklärung ist maager, also wenn jemand das Spiel mit Code(C# .Net) haben will oder Fragen hat, einfach melden.

Peace :D

Jan Krüger
26.11.2003, 22:54
Am einfachsten machst du es dir, indem du für jeden möglichen Spielzug (Spielzüge unterscheiden sich durch die momentane Situation auf dem Feld und die Stelle, an der das Kreuz/der Kreis gesetzt wird) die Wahrscheinlichkeit ausrechnest, dass daraus ein Sieg entsteht, und dann einfach in jeder Situation den Zug mit der höchsten Siegwahrscheinlichkeit auswählst. Problem damit: die Berechnung aller dieser Züge dauert ewig. :p

Besser: du lässt den Computergegner diese Erfahrungen sammeln (er speichert alle Spielzüge in einem Spiel und bewertet die Qualität davon hinterher daran, wer gewonnen hat; damit kann man eine recht gute Statistik darüber anfertigen, welche Züge schlau sind und welche nicht. Natürlich sollte man noch ein bisschen optimieren, indem man ähnliche (symmetrische, verschobene etc.) Spielzüge zusammen bewertet) und speichern. Dann spielst du ein paar hundert Trainingsrunden und er sollte langsam besser werden. ;)