BPS #17: Schachbrett - Auswertung

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Xeres

Moderator

Betreff: BPS #17: Schachbrett - Auswertung

BeitragSo, Feb 19, 2012 12:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Ihr könnt mir übrigens danken, in dem ihr mir für das erste Schachfeld 1 Cent, für das zweite 2 Cent, für das dritte 4 Cent usw. schickt. Danke!
Und nun weiter im Programm:

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:

Teil 1
BlitzBasic: [AUSKLAPPEN]
;Teilaufgabe 1
;Zunaechst brauchen wir ein Grafikfenster
Graphics(400, 300, 32, 2)
Const SqSz% = 40 ;Squaresize die Größe eines Quadrates in Pixeln

ClsColor 125,125,125 ;Hierdurch wird der Fensterhintergrund grau

While Not KeyHit(1) ;Eine Schleife, die nur durch Esc oder den Schließenbutton beendet wird
Cls ;Löscht den Bildschirminhalt
DrawBoard(4) ;Funktionsaufruf, Parameter zeigt der Funktion wieviele Felder wir haben möchten
Flip ;Wechselt den Buffer, so dass das fertig gezeichnete Bild auf den Bildschirm übertragen wird.

Wend ;springt zum Schleifenanfang

End

Function DrawBoard(sq%)
Local height% ;die Koordinate für die Y-Achse
Local width%;die Koordinate für die X-Achse
Local counter% ;mit diesem Zähler, der in beiden Schleifen hochzählt, wird dafür gesorgt, dass trotz der geraden Zahlen die Felderfarben abwechseln
For height = 0 To sq - 1
counter = counter + 1
For width = 0 To sq - 1 ;Die verschachtelte For-Schleife eignet sich hervorragend um 2dimensionale Felder anzuzeigen
counter = counter + 1
If counter Mod 2 <> 0 Then ;Mit Mod (Kurzform von "Modulus") kann geprüft werden, ob eine Zahl durch die zweite teilbar ist. Mod gibt dabei den "Rest" aus.
Color 255,255,255
Else
Color 0,0,0
EndIf
Rect(width * SqSz, height * SqSz, SqSz, SqSz) ;Zeichnet die gefüllten Quadrate ein
Next
Next
End Function


Teil 2
BlitzBasic: [AUSKLAPPEN]
;Teilaufgabe 2
;Zunächst wird die Fenstergröße zwischengespeichert, der Wert könnte fürs zentrieren nützlich sein
Const WINDOW_WIDTH% = 800
Const WINDOW_HEIGHT% = 600

;Setzt wieder unser Grafikfenster
Graphics(WINDOW_WIDTH, WINDOW_HEIGHT, 32, 2)

Const SqSz% = 40 ;Squaresize die Größe eines Quadrates in Pixeln
ClsColor 125,125,125
While Not KeyHit(1)
Cls
DrawBoard(8) ;hier müssen nun 8 Felder angegeben werden.
Flip ;Wechselt den Buffer, so dass das fertig gezeichnete Bild auf den Bildschirm übertragen wird.

Wend

End

Function DrawBoard(sq%) ;Funktion zum Zeichnen
Local height%
Local width%
Local counter% ;mit diesem Zähler, der in beiden Schleifen hochzählt, wird dafür gesorgt, dass trotz der geraden Zahlen die Felderfarben abwechseln
For height = 0 To sq - 1
counter = counter + 1
For width = 0 To sq - 1
counter = counter + 1 ;Kurzschreibweise von counter + 1
If counter Mod 2 <> 0 Then ;Mit Mod (Kurzform von "Modulus") kann geprüft werden, ob eine Zahl durch die zweite teilbar ist. Mod gibt dabei den "Rest" aus.
Color 255,255,255
Else
Color 0,0,0
EndIf

Rect(calcCentered(sq, WINDOW_WIDTH, width), calcCentered(sq, WINDOW_HEIGHT, height), SqSz, SqSz)
Next
Next

Color 255,255,255
;*** Zahlen-Beschriftung links
For height = 0 To sq - 1
Text(calcCentered(sq, WINDOW_WIDTH, -1)+SqSz/2, calcCentered(sq, WINDOW_HEIGHT, height)+SqSz/2, sq-height, True, True)
Next

;*** Buchstaben-Beschriftung unten
For width = 0 To sq - 1
Text(calcCentered(sq, WINDOW_WIDTH, width)+SqSz/2, calcCentered(sq, WINDOW_HEIGHT, sq+1)-SqSz/2, Chr(65+width), True, True)
Next

End Function

Function calcCentered%(sq%, Window%, position%) ;Mit dieser Funktion berechne ich die Pixel-Koordinaten, per Parameter werden die benötigten Daten eingegeben
Return (Window - SqSz * sq) / 2 + position * SqSz ;Man benötigt die Fenstergröße, die Feldgröße, die maximale Anzahl der Felder und das aktuelle Feld
End Function
  • Zuletzt bearbeitet von Xeres am Mo, März 12, 2012 18:00, insgesamt 2-mal bearbeitet

PacMani

Betreff: Re: BPS #17: Schachbrett - Auswertung

BeitragSo, Feb 19, 2012 12:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Xeres hat Folgendes geschrieben:
Ihr könnt mir übrigens danken, in dem ihr mir für das erste Schachfeld 1 Cent, für das zweite 2 Cent, für das dritte 4 Cent usw. schickt. Danke!

So viel Geld habe ich nicht, wie am Ende rauskommt Smile

ozzi789

BeitragSo, Feb 19, 2012 13:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich wollte eine Funktion welche mir möglichst variabel ein Schachbrett zeichnen kann, anhand von Konstanten.
Zudem eine weitere Funktion welche die Infos einzeichnet.

Bei fragen, fragen! Wink


Code: [AUSKLAPPEN]
;ozzi789 - 6.2.12 - BPS # 17 Schachbret
;----------------------------------------
;Die folgenden 3 Variabeln sind da um rumzutesten!

;Aufgabenstellung 1:
;field_w=4 & show_info=0 (field_size ist variabel)

;Aufgabenstellung 2:
;field_w=8 & show_info=1 (field_size ist variabel)

Const field_w=8     
Const field_size=20
Const show_info=1

;-----------------------------------------


;Den Offset benötigen wir um einen Puffer nach aussen zu haben (blauer Rand)
Const offset=50
;Wir wollen das Feld quadratisch
Const field_h=field_w
;Benötigen wir für den Timer
Global timer
;Wir rufen die Funktion 'setup' auf welche alles vorbereitet, siehe unten
setup()


;Unser Mainloop
While Not KeyHit(1)
   Cls
   WaitTimer timer
   ;Das Schachbrett malen
   render_field()
   ;Falls oben in den Konstanten show_info auf 1 gesetzt wurde die Infos malen (1.2.3 / a.b.c. usw)
   If show_info Then render_info()
   Flip 0
Wend
End


;Das Schachbrett einzeichnen
Function render_field()
   Local abs_xy
   ;Alle Felder durchgehen, das -1 ist da wir von 0 anfangen
   For x=0 To field_w-1
      For y=0 To field_h-1
         ;Die x und y Koordinate zusammenzählen
         abs_xy=x+y
         ;Falls die zusammengezählten Koordinaten gerade sind
         If number_even(abs_xy)
            ;Graue Farbe setzen
            Color 200,200,200
         Else
            ;Falls ungerade schwarze Farbe setzen
            Color 0,0,0
         EndIf
         ;Per Rect das Quadrat, also das Feld selber zeichnen
         Rect (x*field_size)+offset,(y*field_size)+offset,field_size,field_size,1
      Next
   Next
End Function


;Die Infos einzeichnen
Function render_info()
   Local temp_str$,ypos,xpos,str_h=StringHeight("1"),str_w=StringWidth("a")
   ;Die Anfganspostion für die Zahlen errechnen
   xpos=offset-(str_h*1.3)
   ;Den grauen Hintergrund für die Infos einzeichnen
   Color 100,100,100
   Rect  offset/2,offset,offset/2,(field_h)*field_size+(offset/2)
   Rect  offset,offset+(field_h)*field_size,field_size*field_w,offset/2
      
   ;Die Zahlen einzeichnen
   Color 255,255,255
   For x=1 To field_w
      Text xpos,((x-1)*field_size)+offset+(field_size/2)-(str_h/2),field_w-x+1
   Next
   
   ;Die Buchstaben einzeichnen
   ypos=offset+(field_size*field_h)+(str_h/1.3)
   For y=1 To field_h
      ;Schaut euch http://www.blitzforum.de/help/ASCII ab zum Verständniss was in temp_str$ kommt
      temp_str$=Chr(y+96)
      Text ((y-1)*field_size)+offset+(field_size/2)-(str_w/2),ypos,temp_str$
   Next
End Function


;Gibt eine 1 zurück falls die übergeben Zahl positiv ist
Function number_even(val)
   val=val+1
   val=val Mod 2
   Return val
End Function


Function setup()
   Local font_size
   ;Wir erzeugen ein Graphicsfenster abhängig unserer gewählten Schachbrett grösse
   Graphics (field_w*field_size)+(offset*2),(field_h*field_size)+(offset*2),32,2
   SetBuffer BackBuffer()
   
   AppTitle "BPS-#17-OZZI  |  Size: "+field_w+"x"+field_h+" @ "+field_size+"px"
   ClsColor 60,100,150
   ;Grösse der Font berechnen
   If field_size/12<12
      font_size=12 ;Falls die Font kleiner als 12 berechnet wird auf 12 setzen
   Else
      font_size=field_size/12 ;Sonst die berechnete verwenden
   EndIf
   ;Die Font laden & gleich setzen
   SetFont(LoadFont("Arial",font_size))
   
   timer=CreateTimer(30)
End Function
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5

Eingeproggt

BeitragSo, Feb 19, 2012 14:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab mich auch mal dran versucht um ein bisschen "Prinzipien zu üben" auch wenns in der Praxis kaum von Bedeutung ist denke ich. Weil meine Prinzipien lauten "Kein einziges IF" und "Keine Zahl außer 0 in der Funktion", bittesehr:

BlitzBasic: [AUSKLAPPEN]
;BPS #17: Schachbrett
;Umsetzung von Christoph "Eingeproggt" Mach
;Feb-2012

;Das "Besondere" an dieser Teilnahme:
;Der Code kommt ohne Abfragen (IF) und ohne hardcodet Zahlen in der Funktion "DrawChessBoard" aus
;Er ist dafür etwas verwirrend, aber lieber verwirrend als langweilig :-P

;Anzeige-Optionen
Global gfx_w=800
Global gfx_h=600
Global board_size=600
Global label_border=30

;Es sollen ja keine Zahlen hardcodet verwendet werden später :-P
Const ONE=1

;Farben (Verwendung von Integer-Angabe statt RGB einzeln damit ich nur eine Variable brauch und nicht je 3 Wink )
Const COL_WHITE=255 Shl 16+255 Shl 8+255
Const COL_BLACK=0
Const COL_GREY=128 Shl 16+128 Shl 8+128
;In Array um darauf mit 0/1 zuzugreifen (siehe in der Funktion "color_switch"
Dim col_avail(1)
col_avail(0)=COL_WHITE
col_avail(1)=COL_BLACK


;LOS GEHTS!
Graphics gfx_w,gfx_h,0,2
;normalerweise verwendet man hier DoubleBuffering.
;aber die Aufgabe ist es ein Schachbrett zu zeichnen.
;Und nicht eine vollwertige Graphikanwemdung mit Buffer-Management :-P

SetFont LoadFont("Arial",label_border)

;Aufgabe 1, 4*4-Feld ohne Beschriftung
DrawChessBoard(4,False)

WaitKey()

;Aufgabe 2, 8*8-Feld mit Beschriftung
;Cls ;nichtmal nötig da voriges Feld eh "übermalt" wird
DrawChessBoard(8,True)

WaitKey()
End



Function DrawChessBoard(s,label)
;Alle Größen in lokale Variablen für diese Ausführung
;(Soll nochmal jemand sagen, "SuperStrick" sei ne "heiden Arbeit" *fg*)

Local border=label*label_border ;Durch Multiplikation mit der Boolschen "label" ist die Border entweder 0 oder gleich der globalen Var "label_border"
Local block_s=(board_size-border-border)/s ;eleganter wäre (board_size-border*2)/s aber da würde die Zahl "2" drinstehen *pingelig sei*
Local start_x=border
Local start_y=border
Local col_switch=False
Local x,y

;Grauer Hintergrund
ClsColor 0,0,COL_GREY
Cls

;Eigentliches Schachbrtt
For x=0 To s-ONE
For y=0 To s-ONE
;Die Farbe so zu setzen funktioniert in Blitz - ist aber eher ein "Hack" als empfehlenswerte Praxis Wink
Color 0,0,col_avail(col_switch)
Rect start_x+x*block_s,start_y+y*block_s,block_s,block_s,True
;Farbe "umschalten"
col_switch=Not col_switch
Next
col_switch=Not col_switch
Next

;Beschriftung außenrum

;Anmerkung: Um "if" zu vermeiden wird auch hier, wie bei "border", mit der Bool multipliziert
;Das führt zu folgendem: Entweder die Schleife geht bis "s-1" oder bis "0-1". Letzteres würde nicht ausgführt werden -> JUHU Wink

;Senkrecht
For y=0 To s*label-ONE
Text 0,start_y+y*block_s,(s-y)
Text board_size-label_border,start_y+y*block_s,(s-y)

Next
;Waagrecht
For x=0 To s*label-ONE
Text start_x+x*block_s,0,Chr(Asc("A")+x)
Text start_x+x*block_s,board_size-label_border,Chr(Asc("A")+x)
Next
End Function


Über den Sinn der einen oder anderen Zeile kann man streiten da die "Lesbarkeit" des Codes doch ein wenig in meinen "Prinzipien" untergegangen ist Sad Aber egal, wer sich in den Kopf setzt keine IFs zu verwenden der muss zu so einem Käse kommen am Ende Razz

mfG, Christoph.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

PacMani

BeitragSo, Feb 19, 2012 15:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Eingeproggt hat Folgendes geschrieben:
Weil meine Prinzipien lauten "Kein einziges IF" und "Keine Zahl außer 0 in der Funktion"

War das nur interessehalber, oder wo hast du so etwas aufgeschnappt? Wink

Eingeproggt

BeitragSo, Feb 19, 2012 16:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Anregung hab ich aus den Tipps der Aufgabenstellung:

Zitat:
- [...] Vermeide zu viele Abfragen und zu viele Schleifen.
- Du wirst aber auch nicht ohne auskommen.
- [...] Ideal wäre, wenn im eigentlichen Code keine Zahlen mehr vorkommen (außer der 0 für For-Schleifen).


Und dann kam noch eine gehörige Portion Sturheit dazu Razz

mfG, Christoph.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

Mr.Hyde

Newsposter

BeitragSo, Feb 19, 2012 16:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Hehe sehr schön, allerdings war das oberste Motto "effizientes Programmieren", wobei das nun natürlich getestet werden müsste. Ich bin mal gespannt was noch für schöne Lösungen auftauchen.
BBP News RSS | Chaos Interactive | Watanien 2 Screens, Infos und Download | Watanien 2 Worklog | PuzzleMasters
http://abgeordnetenwatch.de - http://www.regierungs-beratung.de - Der Regierung auf die Finger schauen

darth

BeitragSo, Feb 19, 2012 18:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

XOR ftw!

BlitzBasic: [AUSKLAPPEN]
Global TILESIZE_X = 32
Global TILESIZE_Y = 32

Function drawChessboard(sizeX, sizeY, offX = 0, offY = 0)
For x = 0 To sizeX -1
For y = 0 To sizeY -1
If (x Mod 2) Xor (y Mod 2)
Color 0, 0, 0
Else
Color 255, 255, 255
EndIf

Rect x * TILESIZE_X +offX, y * TILESIZE_Y +offY, TILESIZE_X, TILESIZE_Y
Next
Next
End Function

Graphics 800, 600, 0, 2
SetBuffer BackBuffer()
Local timer = CreateTimer(60)

While Not KeyHit(1)
Color 125, 125, 125
Rect 0, 0, 280, 280

Color 255, 255, 255
For i = 0 To 7
Text 4, 238 - i * TILESIZE_Y, (i + 1)
Text 32 + i * TILESIZE_X, 264, Chr(65 + i)
Next

drawChessboard(8, 8, 20, 4)

Flip 0
WaitTimer(timer)
Cls
Wend
End


Irgendwie gibts diesmal nicht viel zu erklären. Entweder ist x ungerade oder y, dann wirds schwarz, falls beide das gleiche sind, wirds weiss. Die Rects in der richtigen Grösse (const) und an der richtigen Position ("Tilemap") zu zeichnen ist auch nicht weiter schwer.

MfG,
Darth
Diese Signatur ist leer.

ozzi789

BeitragSo, Feb 19, 2012 18:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Meine Lösung...
Code: [AUSKLAPPEN]
Function number_even(val)
   val=val+1
   val=val Mod 2
   Return val
End Function


Xor ist da natürlich schöner
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5

Xeres

Moderator

BeitragSo, Feb 19, 2012 19:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit dem Wert herum zu rechnen um ihn wieder zurück zu geben ist unnötig. Bei negativen Zahlen bekommt man so -1 zurück. Mit Not wäre es nicht nur kleiner, sondern liefert auch klar True oder False:
BlitzBasic: [AUSKLAPPEN]
Function number_even(val)
If Not(val Mod 2) Then Return True
End Function

@darth: Bitte ergänze Kommentare.
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)

ZEVS

BeitragSo, Feb 19, 2012 19:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Da hier so viel diskutiert wird:
Das beste ist wohl bitweises Und (And):
BlitzBasic: [AUSKLAPPEN]
Function number_even(val)
Return Not (val And 1)
End Function

Mit negativen Zahlen:
BlitzBasic: [AUSKLAPPEN]
Function number_even(val)
Return Not (Abs(val) And 1)
End Function


ZEVS
edit: (un)gerade korrigiert. Mein Englisch war noch nie...
  • Zuletzt bearbeitet von ZEVS am So, Feb 19, 2012 19:37, insgesamt einmal bearbeitet
 

BBPro2

BeitragSo, Feb 19, 2012 19:28
Antworten mit Zitat
Benutzer-Profile anzeigen
hier ne absichtlich komplizierte lösung bei der ich versucht habe alle eventualitäten abzufangen
und gleichzeitig die laufzeit hoch zu halten

(beispiel 1: was kommt nach z ? bei mir a' und nicht ein seltsames zeichen)
(beispiel 2: schwarze felder werden nicht gezeichnet - sie entstehen automatisch durch freilassen)

zum thema xor:
hatte es auch erst mit xor gemacht, aber dann fiel mir auf, dass ich nur ein einfaches "=" brauche
wenn ich die weißen felder zeichne

(die schwarzen sind immer bei x xor y - demnach sind die weißen bei not (x xor y) - und das entspricht einem einfachen "=" )



Code: [AUSKLAPPEN]

; -- Parameter (32, 4, 4, false für Teil 1; 32, 8, 8, true für Teil 2)

Const fieldsize = 16, fieldsx = 32, fieldsy = 32, key = True

; weitere Parameter
Const keysize = fieldsize * 1.1 * key ; * key um keysize auf 0 zu setzen wenn kein Rahmen existiert
Const keyback_r = 64, keyback_g = 64, keyback_b = 64
Const keyfont_r = 192, keyfont_g = 192, keyfont_b = 192

; errechnete Parameter

; Const width = 1024, height = 768 ; auskommentiert für automatische Größenanpassung
Const width = fieldsize * fieldsx + keysize * key ; +keysize wenn Legende angeschaltet ist
Const height = fieldsize * fieldsy + keysize * key ;

Graphics width, height

; -- entsprechenden Font laden

myfont = LoadFont ("MS Sans Serif", fieldsize * 2 / 3, 1) ; Schriftgröße = 2/3 eines Feldes, fettgedruckt
   SetFont myfont

; Legende anzeigen ?
If (key) Then
 ; Rahmen anzeigen
 Color keyback_r, keyback_g, keyback_b
   Rect (0, 0, keysize, height, 1)
   Rect (0, height - keysize, width, keysize, 1)
 ; Rahmen beschriften
 Color keyfont_r, keyfont_g, keyfont_b
 For y = 1 To fieldsy
   Text (keysize / 2, (y - 1) * fieldsize + (fieldsize / 2), fieldsy - y + 1, 1, 1) ; 1, 2, 3, ... vertikal zentriert und rückwärtslaufend
 Next
 For x = 1 To fieldsx
   ; Erzeuge anhängenden ' falls nötig (z.B. a')
   If oldapp <> ((x - 1) / 26) Then
      oldapp = ((x - 1) / 26)
      For j = 1 To ((x - 1) / 26)
       append$ = append$ + "'"
      Next
   End If
   Text (keysize + (fieldsize / 2) + fieldsize * (x - 1), height - keysize / 2, Chr$ (Asc ("a") + (x - 1) Mod 26) + append$, 1, 1) ; a, b, c, ..., y, z, a', b', ...
 Next
End If

; Weiße Felder zeichnen (schwarze ergeben sich von selbst)

Color 200, 200, 200
For i = 0 To fieldsx * fieldsy - 1
   ; wo liegt das nächste Feld ?   
   
   ; Feld auf die Form (rx, yy) [z.B. von (0, 0) bis (7, 7)] bringen
   rx = i / fieldsx
   ry = i Mod fieldsx
   ; rausfinden ob rx/ry gerade sind
   rxe = rx Mod 2
   rye = ry Mod 2
   ; das Feld nur zeichnen, wenn rxe <-> rye
   If rxe = rye Then Rect rx * fieldsize + keysize, ry * fieldsize, fieldsize, fieldsize
Next

WaitKey
End

Xeres

Moderator

BeitragSo, Feb 19, 2012 19:35
Antworten mit Zitat
Benutzer-Profile anzeigen
@ZEVS: Auch da bräuchtest du noch ein Not, sonst wären es ungerade Zahlen.

@BBPro2: Ein paar mehr Kommentare wären nett, insbesondere bei den langen, einzeiligen Text-Funktionen. Wie es funktioniert sollte möglichst gut beschrieben werden.
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)

SpionAtom

Betreff: Meine Variante

BeitragSo, Feb 19, 2012 19:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Kein IF, kein MOD, kein XOR, kein Rechnen mit Boolschen Werten, keine verschachtelten Schleifen.
Stattdessen nutze ich die CopyRect, um das Schachbrett aufzufüllen.

BlitzBasic: [AUSKLAPPEN]
	Const SCHACHBRETT_BREITE = 400
Const SCHACHBRETT_HOEHE = 400
Const SCHACHBRETT_FELDER_HORIZONTAL = 7 ;im Normalfall 8
Const SCHACHBRETT_FELDER_VERTIKAL = 10 ;im Normalfall 8
Const SCHACHBRETT_LEISTE = 32


Const xr = 640, yr = 480
Graphics xr, yr, 0, 2
ClsColor 222, 222, 222

pic_schachbrett = createSchachbrett(SCHACHBRETT_BREITE, SCHACHBRETT_HOEHE, SCHACHBRETT_FELDER_HORIZONTAL, SCHACHBRETT_FELDER_VERTIKAL, SCHACHBRETT_LEISTE)
SetBuffer BackBuffer()
Repeat
Cls
DrawBlock pic_schachbrett, (xr - SCHACHBRETT_BREITE) / 2 - SCHACHBRETT_LEISTE, (yr - SCHACHBRETT_HOEHE) / 2
Flip()
Until KeyDown(1)
End







;Erzeugt ein Image mit Schachbrett und Feldbezeichnungs-Leiste
Function createSchachbrett(breite, hoehe, felder_horizontal, felder_vertikal, leiste)

feld_breite# = breite / felder_horizontal
feld_hoehe# = hoehe / felder_vertikal

pic = CreateImage(breite + leiste, hoehe + leiste)
SetBuffer ImageBuffer(pic)

;------- Schachbrett erzeugen -------
;Zur Erzeugung des Schachbretts reicht es, nur die weißen Felder einzuzeichnen,
;die schwarzen Felder entstehen dann automatisch.

;-- die ersten beiden Zeilen füllen --
;In der folgenden Schleife werden die ersten beiden Zeilen mit weißen Feldern gefüllt.
;Das erste Rect ist für die erste Zeile zuständig, das zweite Rect für die zweite Zeile.
;Da nur jedes zweite Feld ein weißes Feld ist, wird die horizontale Position mit
;i * 2 * feld_breite berechnet. In der zweiten Zeile passiert fast dasselbe mit dem
;Unterschied, dass die weißen Felder um ein Feld versetzt sind: (i * 2 + 1) * feld_breite
Color 255, 255, 255
For i = 0 To (felder_horizontal / 2)
Rect leiste + i * 2 * feld_breite, 0, feld_breite, feld_hoehe
Rect leiste + (i * 2 + 1) * feld_breite, feld_hoehe, feld_breite, feld_hoehe
Next
;-- die restliche Zeilen durch kopieren auffüllen --
;Hat man die ersten beiden Zeilen aufgefüllt, so kann man die übrigen Zeilen, durch
;Kopieren der ersten beiden Zeilen auffüllen, denn das Muster wiederholt ja.
;Bei CopyRect gibt man zunächst die Position und die Größe des zu kopierenden Abschnitts
;an, was in diesem Fall immer der Abschnit über die ersten beiden Zeilen ist.
;Und dann gibt man die Zielposition an, die ist alle zwei Zeilen darunter.
For i = 1 To felder_vertikal / 2
CopyRect leiste, 0, breite, 2 * feld_hoehe, leiste, 2 * i * feld_hoehe
Next


;------- Ziffern und Buchstaben -------
;Die Position der Ziffern und Buchstaben errechnet sich anhand der Zeilen und Spalten,
;in der die einzelnen Zeichen stehen. Wenn man diese zentriert haben will, muss man
;die Größe der Leiste und die Breite bzw Höhe der einzelnen Zeichen mit einberechnen.
Color 33, 33, 33
Rect 0, 0, leiste, hoehe
Rect 0, hoehe - 1, breite + leiste, leiste
Color 255, 255, 255
;Horizontale Buchstabenleiste
For i = 0 To felder_horizontal - 1
b$ = Chr(65 + i)
Text leiste + (i + 0.5) * feld_breite - StringWidth(b$) / 2, hoehe + ((leiste - StringHeight(b$)) / 2), b$
Next
;Vertikale Ziffernleiste
For i = 0 To felder_vertikal - 1
b$ = Str(felder_vertikal - i)
Text (leiste - StringWidth(b$)) / 2, (i + 0.5) * feld_hoehe - StringHeight(b$) / 2, b$
Next

;Rahmen drum
Color 0, 0, 0
Rect 0, 0, breite + leiste, hoehe + leiste, 0

Return pic

End Function


os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080

Eingeproggt

BeitragSo, Feb 19, 2012 20:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Mist, da hat mich jemand noch um ne Nasenlänge geschlagen Razz
Sehr kreativ, Spyon
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

SpionAtom

BeitragMo, Feb 20, 2012 14:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Ach Quatsch! Deine Feld-Farb-Switsch-Methode ist auch ziemlich kreativ!

Nur das mit dem 1 in ONE auslagern halte ich für etwas übertrieben.
Und wenn schon, dann müsstest du aus 0 auch ZERO machen.
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080

PacMani

BeitragMo, Feb 20, 2012 14:24
Antworten mit Zitat
Benutzer-Profile anzeigen
SpionAtom hat Folgendes geschrieben:
Ach Quatsch! Deine Feld-Farb-Switsch-Methode ist auch ziemlich kreativ!

Nur das mit dem 1 in ONE auslagern halte ich für etwas übertrieben.
Und wenn schon, dann müsstest du aus 0 auch ZERO machen.

Dem kann ich nur zustimmen. Konstanten sind zum Erläutern eines Sinnes hinter der Zahl nützlich, nicht um die Zahl an sich nochmal wiederzugeben.
Sonst müsstest du ja logischerweise auch
ONE_BILLION_HUNDREDFOURTYFIVE_MILLION_FIVEHUNDREDTHOUSANDTWENTYFOUR_THREEHUNDREDELEVEN = 1145524311 anlegen Smile

In Sinne des Schachbrettes wäre wennschon eher etwas wie BLACK = 1, WHITE = 0 nützlich.

Dice of Darkness

BeitragMo, Feb 20, 2012 15:38
Antworten mit Zitat
Benutzer-Profile anzeigen
So, dann poste ich einfach mal noch meine Version.

Code: [AUSKLAPPEN]
; BPS#17 - Schachbrett
;
; (c) Dice of Darkness

AppTitle "BPS#17: Schachbrett"

;KONSTANTEN
Const screenResolution = 600
Const screenMode = 2
Const chessDimension = 8   ;gibt an, wie viele Felder das Brett hat (Standard: 8x8)
Const padding = 20         ;Abstand des Feldes zum Bildschirmrand in Pixeln


Graphics screenResolution, screenResolution, 16, screenMode
SetBuffer BackBuffer()
Global frameTimer = CreateTimer(50)


;BLAUER HINTERGRUND
ClsColor 0,0,255
Cls

;Das Schachbrett soll zentriert gezeichnet werden. Wir lassen links und rechts am Bildschirm
;jeweils einen Abstand (der Pixelwert ist in padding gespeichert) und haben dann so viele
;Felder, wie die chessDimension ist PLUS EINS, weil noch die Beschriftung der Felder eingefügt werden muss.
Global fieldSize# = (screenResolution-padding*2)/(chessDimension+2)

Global fieldColor = 0   ;Farbe des aktuellen Feldes (wechselt nach jedem Zeichenvorgang)

;BRETT ZEICHNEN
For x=1 To chessDimension
   For y=1 To chessDimension
      
      SwitchColor()
      Rect (x*fieldSize#) + fieldSize#, y*fieldSize#, fieldSize#, fieldSize#
      
   Next
   If (chessDimension Mod 2 = 0) Then SwitchColor()   ;hier wird ein zusätzlicher Switch benötigt, weil wir wieder oben anfangen weiter zu zeichnen
Next

;BESCHRIFTUNG DER FELDER
Color 200,200,200

;HORIZONTAL
Global ascii = 65   ;Das erste Feld wird mit "A" beschriftet, dann immer mit nachfolgenden Buchstaben

For x=1 To chessDimension
   
   Text (x*fieldSize#) + fieldSize#*1.5, (chessDimension+1)*fieldSize# + fieldSize#/4, Chr(ascii)
   ascii=ascii+1
   
Next

;VERTIKAL
Global fieldLine = chessDimension   ;Die erste Zeile bekommt den Wert von chessDimension (wir gehen von oben nach unten!)

For y=1 To chessDimension
   
   Text padding + fieldSize#, y*fieldSize#+fieldSize#/2, fieldLine
   fieldLine=fieldLine-1
   
Next


WaitKey()   ;so lange das Schachbrett anzeigen, bis eine Taste gedrückt wird

EndGraphics
End


Function SwitchColor()
   
   fieldColor = 1-fieldColor
   If(fieldColor) Then
      Color 255,255,255      ;weiß
   Else
      Color 0,0,0            ;schwarz
   EndIf
   
End Function


Kurze Erklärung dazu: Es ist so ziemlich alles "konstant", was man vielleicht mal variieren möchte (Bildschirmauflösung, Anzahl der Schachfelder etc.). Bei meiner Version ist die Auflösung in x- und y-Richtung immer gleich, das hängt damit zusammen, wie sich mein Schachbrett dann grafisch berechnet.
Die Funktion SwitchColor() hätte mit Sicherheit schöner machen bzw. ganz darauf verzichten können, aber da war ich einfach mal faul Razz.
Um die Buchstaben an die Schachfelder zu schreiben, habe ich übrigens die Funktion Chr() benutzt und den Wert ASCII nach jedem Durchlauf immer inkrementiert - wenn man also nicht mehr als 26 mal 26 Felder auf seinem Schachbrett haben will, geht das auf diese Art ganz gut.

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group