BPS #14 TicTacToe, Teil I - Auswertung

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Xeres

Moderator

Betreff: BPS #14 TicTacToe, Teil I - Auswertung

BeitragSo, Nov 13, 2011 22:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Grundlagen für den nächsten Teil sollten wir zusammen bekommen haben - wer hat's geschafft, wo gibt es Probleme?

Das war die Aufgabe

Postet hier eure Ergebnisse, Codes, Gedanken. Lernt von den anderen, seht euch deren Quelltext an und versucht euren eigenen zu verbessern.

Diskussion
Postet zu euren Codes stets eine kurze Erklärung mit euren Gedanken in denen ihr simpel gesagt die Frage "Wieso habe ich XY auf diese Art gelöst?" beantwortet. Beiträge, die nur den Code enthalten werden wir aus dem Thread entfernen.

Nächste Aufgabe
In einer Woche wird die Musterlösung nach editiert und in 2 die nächste Aufgabe eingestellt.

Viel Spaß & viel Erfolg!

Musterlösung:
BlitzMax: [AUSKLAPPEN]
'====================================================================
' Project: Tic Tac Toe
'====================================================================
SuperStrict
AppTitle = "TicTacToe" ' Dem Fenster einen Namen geben
Graphics 200,200' Grafikmodus initialisieren


Global grid:Byte[,] = New Byte [3,3] ' Speicher für ein 3 x 3 Feld reservieren, Integervariable

Local timer:TTimer ' Die Variable in welche den Handlewert der Framebremse beinhalten wird
Local x:Byte,y:Byte,player:Byte,mx:Int,my:Int, MouseH1:Byte,pos_x:Int,pos_y:Int,win:Byte ' Allgemeine Variablen im Programm

timer=CreateTimer(60) ' Einen Timer erstellen


' Globale Einstellungen
SetClsColor 128,0,0 ' Die Löschfarbe setzen
SeedRnd MilliSecs() ' Damit der Zufall zufällig ist
' Lies dazu auch in der Hilfe nach
player=Rand(1,2) ' Der Zufall entscheidet wer beginnt

Repeat ' Hauptschleife

mx=MouseX() ' Die Mauspositionen zwischenspeichern
my=MouseY() ' Dies wirkt sich positiv auf die Performance aus
MouseH1:Byte =MouseHit(1)
' wenn die Werte mehrmals im Programm benötigt werden

Cls ' Der Backbuffer wird "gereinigt", siehe dazu auch "Globale Einstellungen"
SetColor 0,0,255 ' Blau als Zeichenfarbe festlegen

' Das Spielfeld malen
DrawLine 25,75,175,75
DrawLine 25,125,175,125
DrawLine 75,25,75,175
DrawLine 125,25,125,175

' Mittels 2 verschachtelten Schleifen werden die bereits gesetzten
' Steine ins Spielfeld gemalt
For y=0 To 2
For x=0 To 2
If grid[x,y]>0 Then ' Ist der Wert im Feld größer 0 dann...

Select grid[x,y] ' ...entscheide welche Farbe wir brauchen...
Case 1 SetColor 255,0,0
Case 2 SetColor 0,128,0
End Select ' Select-Konstrukt Ende

DrawOval 30+(x*50),30+(y*50),40,40' ... und male den Stein
EndIf ' Das EndIf zeigt das Ende des Konstrukts
Next ' Beendet die Schleife
Next ' Man sieht auch schön wie wichtig die Einrückung für die
' Lesbarkeit des Codes ist

' Je nach aktuell zugberechtigtem Spieler Farbe setzen
Select player ' Wieder ein Select-Case-Konstrukt für die Entscheidung
Case 1 ' Spieler 1
SetColor 255,0,0 ' Rot
Case 2 ' Spieler 2
SetColor 0,128,0 ' Grün
End Select ' Beendet das Konstrukt

' Hier wird ein Kreis gezeichnet an der Position des Mauszeigers
' Der Kreis ist 40 Pixel breit, 40 Pixel hoch und gefüllt
DrawOval mx-20,my-20,40,40

' Auswerten der Usereingabe
If MouseH1 = True And win=False' Die linke Maustaste wurde gedrückt und
' es gibt noch keinen Gewinner der Partie

' In diesem If-Konstrukt wird nun alles verarbeitet was mit
' diesem Klick zusammenhängt. Wird der Klick an verschiedenen Stellen
' im Programm benötigt muß dieser zwischengespeichert werden.
' Mehr dazu auch im Forum.
If mx>=25 And mx<=175 ' Ist der Mauszeiger vertikal im Spielfeld?
If my>=25 And my<=175 ' Ist der Mauszeiger horizontal im Spielfeld?
pos_x=(mx-25)/50
pos_y=(my-25)/50
' In den oberen 2 Zeilen machen wir uns eine Eigenheit von BB zunutze.
' Rechnen wir zunächst anhand von Beispielwerten den Wert von Hand aus:
' Wir nehmen an mx sei 100
' Das ergibt: pos_x=(100-25)/50
' pos_x=75/50
' pos_x=1.5
' Da pos_x aber ein Integerwert ist rundet BB den Wert auf 2
' Selbiges gilt sinngemäß auch für pos_y

If grid[pos_x,pos_y]=0 ' Das Feld ist noch leer
grid[pos_x,pos_y]=player
' Das Feld an eben berechneter Position wird nun mit dem Wert
' für den aktuellen Spieler gefüttert

' Jetzt muß geprüft werden ob 3 Steine in einer Reihe sind
' Diese Prüfung wird nur ausgeführt wenn ein neuer Stein gesetzt wurde
' Das schont die Performance
win=CheckLine(player)

If player=1 Then player=2 Else player=1 ' Den anderen Spieler wählen
EndIf
EndIf
EndIf
EndIf

If win>0 Then ' Es gab einen Gewinner und wir bieten an ein neues Spiel zu beginnen

SetColor 255,255,255 ' Die Zeichenfarbe einstellen (weiß)
DrawText "Player "+String(win)+" hat gewonnen!", 5,70
DrawText "Leertaste - neues Spiel",5,100

If KeyHit(KEY_SPACE) Then ' Die Leertaste wird abgefragt (Scancodes siehe Hilfe)
NewGame() ' Das Spielfeld vorbereiten
win=False ' Den letzten Gewinner löschen
player=Rand(1,2) ' Den beginnenden Spieler neu auswählen
EndIf
EndIf


Flip ' Die Buffer werden getauscht
WaitTimer(timer) ' Der Rechner "wartet" bis er den nächsten Frame malen darf
' Dies gibt dem Prozessor Zeit noch all die anderen Dinge zu tun die er
' zu erledigen hat
Until KeyHit(KEY_ESCAPE) Or AppTerminate() ' Solange die ESC-Taste nicht gedrückt wurde springen wir zurück
' zum Schleifenanfang

End ' Das Programm beenden



Function CheckLine:Byte(player:Byte)
Local x:Byte
Local y:Byte ' Die Variablen werden lokal in der Funktion angelegt

For y=0 To 2 ' Waagrecht prüfen
If grid[0,y]=player And grid[1,y]=player And grid[2,y]=player Then
Return player ' Ist die Reihe voll mit gleichen Steinen geben wir
' den Spieler zurück und beenden somit die Funktion
EndIf
Next

For x=0 To 2 ' Senkrecht prüfen
If grid[x,0]=player And grid[x,1]=player And grid[x,2]=player Then
Return player ' Dasselbe wie oben
EndIf
Next

' Nun prüfen wir noch die Diagonalen
If grid[0,0]=player And grid[1,1]=player And grid[2,2]=player Then
Return player
EndIf
If grid[2,0]=player And grid[1,1]=player And grid[0,2]=player Then
Return player
EndIf

' Wenn keine der Prüfungen anschlägt gibt es noch keinen Gewinner
' und es wird False zurückgegeben
Return False
End Function

Function NewGame()
Local x:Byte,y:Byte
For y=0 To 2
For x=0 To 2
grid[x,y]=0 ' Das Spielfeld wird leergeräumt
Next
Next
End Function
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
  • Zuletzt bearbeitet von Xeres am So, Nov 27, 2011 22:45, insgesamt 3-mal bearbeitet

BlitzMoritz

Betreff: TicTacToe in 16-Zeilen!

BeitragSo, Nov 13, 2011 23:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Auf meiner Suche nach einem kurzen Code mit möglichst wenigen Befehlszeilen habe ich manche Reduktionen vorgenommen. Beispielsweise habe ich mich auf ein eindimensionales Array beschränkt. Es hat 49 Einträge, um an den zusätzlichen Rändern "tote" Leerfelder quasi als "Puffer" zu bauen, welche die Gewinneranalyse mit geringem Aufwand möglich macht. Das Verständnis sämtlicher Umrechnungen erschließt sich evtl. leichter, wenn man sich die Anordnung der Indizes des 7 x 7 großen Arrays aufschreibt.
Die Variablen bedeuten: p = Player, a = Array, i = Index. Mit Escape leert man das Spielfeld.

BlitzMax: [AUSKLAPPEN]
Graphics 120,120 'Ein kleines Fenster malt sich leicht,
Local p@, a@[49], i@ 'die Platzhalter in Byte - das reicht.
Repeat 'Wenn dann das Ganze kommt ins Rollen,
Cls 'zuerst wir saubermachen wollen.
For i = 16 To 32 'Wer sagt, er bräuchte mehr, der lügt,
DrawText Chr(Max(48,a[i])), i Mod 7*40-67, i/7*40-67 'denn wenn beim Malen man betrügt,
Next 'die eine Dimension genügt!
i = 16+MouseY()/40*7+MouseX()/40 'Wo treibt sich denn die Maus herum?
If MouseHit(1) And Not a[i] Then 'Und schlägt brutal auf Nullen 'rum?
a[i] = 49+p 'Der neue Platzherr schaut - nicht dumm - sich 'rundherum nach Freunden um. Er bräucht' von ihnen zweie bloß, dann wär' der Jubel riesengroß:
If a[i-2]+a[i-1]+a[i+1]+a[i+2] = 2*a[i] Or a[i-14]+a[i-7]+a[i+7]+a[i+14] = 2*a[i] Or a[i-16]+a[i-8]+a[i+8]+a[i+16] = 2*a[i] Or a[i-12]+a[i-6]+a[i+6]+a[i+12] = 2*a[i] Then Print "Spieler " + Chr(a[i]) + " hat gewonnen!"
p = (p+1) Mod 2 'Nun kommt der Gegner auch 'mal d'ran,
End If '(auch er will zeigen, was er kann).
If KeyHit(KEY_ESCAPE) Then a = New Byte[49] 'Wird's dann am Ende schlicht zuviel, dann gibt's die Flucht ins neue Spiel.
Flip 'So wendet sich stets Blatt für Blatt,
Until AppTerminate() 'bis man genug vom Spielen hat.

Holzchopf

Meisterpacker

BeitragMo, Nov 14, 2011 10:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr schön! Eine elegante und gut dokumentierte Lösung, so soll es sein! Mit diesem Beitrag wird sicher der ein oder andere bestimmt noch etwas (oder viel) lernen können Smile
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

Xeres

Moderator

BeitragSo, Nov 20, 2011 14:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Musterlösung steht im Anfangspost.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group