Z10: Blackjack


  • wizball6502
  • 590 Views 20 replies

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Z10: Blackjack

    Hallo Freunde der BASIC Zehnzeiler-Herausforderungen!

    Ich führe mal BIF's Z10-Serie weiter und möchte gerne sehen, wie gut ein Blackjack (auch bekannt als 17+4) als PUR-80 Zehnzeiler aussehen könnte.

    Kurz zum Spiel (es gibt verschiedene Ausprägungen der Regeln, aber hier die einfachste):
    • 52 französische Karten, also je 13 Karten à Herz, Karo, Kreuz, Pik)
    • Karten 2-10 zählen ihren Eigenwert
    • Bube, Dame, König zählen je 10 Punkte
    • Ass zählt 11 Punkte
    Ziel ist es, so nah an ein Kartenwerttotal von 21 zu kommen ohne diesen Wert zu überschreiten (=Bust).

    Der Dealer (Computer) gibt sich eine Karte (sichtbar), dann dem Spieler (sichtbar), dann sich (verdeckt) und noch eine dem Spieler (sichtbar). Die Kartenwerte werden zusammengezählt. Der Spieler entscheidet nun, ob er noch eine Karte möchte (Hit) oder bei dem aktuellen Kartenwerttotal bleibt (Stand). Bei "Hit" erhält er eine weitere Karte dazu. Sobald der Spieler "Stand" wählt, zieht der Dealer so lange, bis er entweder mindestens 17 Punkte erreicht hat oder "Bust" geht. Je nachdem gewinnt der Dealer oder der Spieler.

    Viel Spass beim Tüfteln!

    The post was edited 1 time, last by wizball6502 ().

  • Noch ein Tipp. Das Zahlenmischen in BASIC wurde im Thread "Zufallszahlen" diskutiert:
    forum64.de/index.php?thread/4715-zufallszahlen/

    Das hat mich dann auch dazu bewogen, das mit einem Kartenspiel zu kombinieren. Blackjack bzw. 17+4 schien mir dazu geeignet. Die besondere Herausforderung ist dann noch, das Ganze grafisch ansprechend darzustellen. Bin gespannt...
  • BIF wrote:

    Hallo, hab mein ersten Black-Jack Zehnzeiler funktionsmäßig fertiggestellt.
    Und hier ist der Screenshot der zeigt, wie´s aussieht.
    Sieht supercool aus. Vor allem gefällt mir bei deiner Version, dass du den Hintergrund weiss gewählt hast, damit die Karten - das zentrale Objekt im Spiel - authentisch dargestellt werden können.

    Hier ein Screenshot meiner vorläufigen Version:


    Ein klein bisschen Platz hatte ich noch, um anzuzeigen, wenn der Spieler gleich zu Beginn 21 Punkte (also einen "Blackjack") erhält.

    Gruss aus der Schweiz

    Edit: Wo ich regeltechnisch aufgrund der Zeichenlimite noch einen Kompromiss - zum Nachteil des Casinos - eingehen musste: Ein Unentschieden fällt immer zu Gunsten des Spielers aus. :D

    The post was edited 1 time, last by wizball6502 ().

  • @'wizball6502:

    Danke für dein Lob und die Würdigung.

    Stimmt genau, den Hintergrund habe ich weiß gewählt, da das meiner Meinung nach am besten aussierht.

    Dein Programm sieht find ich auch schon gut strukturiert aus.
    Zugegebenermaßen kenne ich mich mit Black-Jack nicht ganz perfekt aus.

    Aber die Programmierung war schon durchaus interessant.

    Schönen Gruß an die Schweiz.
  • BIF wrote:

    Dein Programm sieht find ich auch schon gut strukturiert aus.
    Danke dir :)

    BIF wrote:

    Zugegebenermaßen kenne ich mich mit Black-Jack nicht ganz perfekt aus.
    Das jeweilige Thema zu durchleuchten, finde ich fast genauso spannend und interessant wie das Zehnzeiler-Tüfteln. Die Regeln von Blackjack musste ich auch erst wieder im Internet recherchieren, und habe dann noch einige YouTube Videos angeschaut, wie das Herausgeben der Karten so abläuft. Habe dabei gelernt, dass es bei den Casino-Regeln noch "Split" und "Double" sowie eine "Versicherung" gegen einen Dealer Blackjack gibt, aber das hätte den Rahmen eines PUR-80 Zehnzeilers dann definitiv gesprengt (wenn die Darstellung nicht darunter leiden soll). Was ich bisher auch nicht kannte, ist die Regel "Dealer must stand on 17 and must draw to 16", also das der Dealer, sobald er 17 Punkte zusammen hat, nicht mehr ziehen darf.

    Jedenfalls wäre ich dank diesem Zehnzeiler nun grundsätzlich fit für einen Casino-Besuch (bin aber eher nicht der Zocker-Typ).
  • BIF wrote:

    Hier kommt mein KARTEN 17+4.PRG
    als Download.
    Vielen Dank für dein PRG. Werde deine Version gleich mal ausprobieren.

    Hier meine Variante:
    blackjack.prg

    Steuerung:
    H = Hit (eine weitere Karte erhalten)
    S = Stand (keine weitere Karte mehr)
    <space> um neu zu starten.

    Display Spoiler

    Source Code: blackjack.prg

    1. 0poke53280,5:poke53281,5:print"{clear}":d=13:k=51:v$="B":t$=" jqka":dima(k):fori=.tok:a(i)=i:next
    2. 1forc=kto1step-1:n=rnd(.)*(c+1):b=a(c):a(c)=a(n):a(n)=b:next:r$="{down}{left}{left}{left}{left}{left}":q$="B{space*3}B"
    3. 2o$="UCCCI":u$="JCCCK{light green}":gosub5:print"{home}{down}{red}"tab(5)o$r$m$u$:gosub6:gosub6:print"{down}{down}{down}{white}hit or stand?"
    4. 3ifx>hory>hor(s=1andx>16)thenprintl$(abs(eory>21))tab(7)j$"{reverse on} wins {reverse on}":wait197,32:poke198,0:run
    5. 4geta$:on-(a$="h")gosub6:j$="":on-(a$<>"s"ands=0)goto3:s=1:gosub5:e=y<>21andx<22andx>y:goto3
    6. 5a=a(z):l$(1)="{home}{white}dealer{red}":b$="B{cm +}{cm +}{cm +}B":h=20:printl$(1):t=f:gosub7:x=x+r:printx:f=f+5:return
    7. 6a=a(z):l$(0)="{home}{down*10}{white}player{red}":j$="bj ":printl$(0):t=g:gosub7:y=y+r:printy:g=g+5:return
    8. 7n=int(a/d):r=a-n*d:p=(r-8)andr>8:r=r+2:f$=str$(r):ifp>0thenf$=mid$(t$,p,2):r=10-(p=4)
    9. 8d$=mid$("SZXA",n+1,1):f$=mid$(f$,2,len(f$)-1):p$=left$(" ",2-len(f$)):z=z+1:n$=b$+r$
    10. 9printtab(t)left$("{black}",n/2)o$r$v$d$p$f$v$r$q$r$q$r$v$f$p$d$v$r$u$:m$=n$+n$+n$+n$:return
    11. 2019 rem basic tenliner / (c) roman werner @romwer roman.werner@gmail.com
    Display All


    Beim Design habe ich mir noch überlegt, ob ich die aktuelle Summe der Kartenpunkte anzeigen oder weglassen soll. Weglassen macht vermutlich mehr Spass, weil man dann ein bisschen Kopfrechnen und sich etwas konzentrieren muss. Ich habe mich aber für das Anzeigen entschieden, damit Personen, die noch nie Blackjack gespielt haben oder solche die andere Regeln gewohnt sind, intuitiv nachvollziehen können, wie in meiner Version gezählt wird (also Bube, Dame, König immer 10, Ass immer 11).
  • Hallo BIF

    Interessant. Du hast ein völlig anderes Spiel daraus gemacht, das mir aber gut gefällt. Wäre noch spannender, wenn man nur max. ein Kartendeck lang (also 52 Karten) ziehen dürfte und dann am Schluss das erreichte Punktetotal angezeigt wird. Und es wäre abgesehen davon auch ein gutes Training für solche, die Karten zählen üben möchten. :D
  • @wizball6502:

    JA, ein bischen Zauberei muß auch dabei sein.
    Also, mit :poke19,1: kann man die Ausgabe von rechts-Steuerzeichen auf Leerzeichen umschalten.
    Ansonsten setze ich die Felder auf Null bevor ich :dim: Feldlöschen ausführe.

    Hier kommt noch mal das überarbeitete Programm.
    Der Kartenstapel wird nun vollständig verteilt.
    Neumischen wird mit einem Punkt über der Karte angezeigt.

    Schönen Gruß.
    Files
    • KARTEN 17+4.PRG

      (784 Byte, downloaded 5 times, last: )
  • BIF wrote:

    Also, mit :poke19,1: kann man die Ausgabe von rechts-Steuerzeichen auf Leerzeichen umschalten.
    Stimmt so nicht ganz. Das unterschiedliche Verhalten zeigt sich ja nur im Zusammenhang mit SPC(). Auf PRINTs mit rechts-Steuerzeichen hat der POKE keinen Einfluss.

    Ich habe mir die Verwendung der Zeropage-Adresse 19 ($13) im BASIC Kernal mal genauer angeschaut ( pagetable.com/c64disasm/ ). Da geht es um den I/O-Kanal, welche sich auf die Zahl bei "OPEN 1,..." bezieht, über den eine Ein- oder Ausgabe erfolgen soll. Initial ist der Wert 0 (Ein-/Ausgabe über Tastatur/Monitor). Regulär gesetzt wird die Speicherstelle 19 ($13) vom BASIC-Befehl CMD und fixiert den Kanal für den nächsten In- oder Output (z.B. via INPUT oder PRINT). Die Kanal-Adresse wird ebenfalls von den Befehlen GET#, PRINT# oder INPUT# vorübergehend gesetzt, weil dort die Kanal-Nummer direkt mitgegeben wird und als Teil des #-Befehls ein CMD-Aufruf ausgeführt wird. Im Hintergrund wird dann einfach ein GET, PRINT oder INPUT über das jeweilige Ein-/Ausgabegerät ausgeführt. Interessant: GET#, PRINT#, INPUT# sowie GET setzen denn Kanal bzw. Speicherstelle 19 ($13) nach Verwendung wieder auf 0. "CMD" macht somit in Verbindung mit den #-Befehlen IMHO keinen grossen Sinn. Kurios: Trotzdem muss im Anschluss einer Peripherie-Ausgabe ein #-Befehl ausgeführt werden, ansonsten wird der I/O-Channel nicht wieder auf 0 zurückgesetzt. Wenn Speicherstelle 19 ($13) nämlich gesetzt bleibt (ungleich 0), dann gibt es ein seltsames Verhalten, wenn man im Bildschirm <return> drückt: Nach dem Return gibt es keine Zeilenschaltung mehr. Lustig: Man kann auf diese Weise sogar ein Listing eingeben. Aus diesem Verhalten kommt man raus, wenn man POKE19,0 eintippt und <return> drückt. Aber auch irgendeine Fehlermeldung setzt Adresse 19 ($13) wieder auf 0.

    Wenn Adresse 19 ($13) also nicht gleich 0 ist, dann geht der C64 Kernal von Peripherie-Output aus und druckt bei SPC() dann eben statt einem Steuerzeichen "nach rechts" (was grundsätzlich schneller ist, aber nur auf dem Bildschirm Sinn macht) ein echtes Leerzeichen. Somit kann man POKE19,1 oder POKE19,255 oder irgendeine Zahl zwischen 1 und 255 verwenden, um das gewünschte Verhalten zu erreichen.

    Alternativ könnte man statt diesem POKE also auch die Standard-BASIC-Befehle einsetzen, um eine Ausgabe über den Bildschirm via Peripherie-Modus auszugeben (und damit zum Leerzeichen zu gelangen), also statt...

    POKE19,1:PRINTCHR$(18)SPC(20):POKE19,0

    ...könnte man auch folgende Befehlszeile verwenden (3=Bildschirm Device):

    OPEN1,3:PRINT#1,CHR$(18)SPC(20):CLOSE1

    Ist beides in etwa gleich schnell in der Ausführung und auch gleich lang als source code. Wobei mir persönlich der Weg über "OPEN1,3" lieber ist, da nachvollziehbarer. Der POKE ist dafür geheimnisvoller. :D

    Was ich mich aber nun wundere... in den gängigen POKE-Sammlungen steht, dass man mit POKE19,65 das Fragezeichen bei einem INPUT ausschalten kann:

    ------------------------------------------------------------------
    Miscellaneous
    ------------------------------------------------------------------
    POKE 775,200 disable LIST
    POKE 775,167 enable LIST
    POKE 56341,S set cursor speed (S=0-255)
    POKE 204,0 turn cursor on during a GET
    POKE 204,255 turn cursor back off
    POKE 19,65 turn off question mark during INPUT
    POKE 19,0 turn question mark back on
    POKE 54296,15:POKE 54296,0 make a click sound

    Meines Erachtens spielt es keine Rolle, welcher Wert in Adresse 19 steht. Hauptsache, es steht eine Zahl > 0 drin. Ich habe das Gefühl, da hat sich jemand einen Scherz erlaubt und einfach sein Geburtsjahr 1965 verewigen wollen.


    Edit: Gerade darüber gestolpert. Finde die Speicherstelle 19 ($13) hier sehr klar und treffend beschrieben: archive.org/details/Compute_s_…g_the_64_and_64C/page/n23 . Das Buch gefällt mir.

    The post was edited 3 times, last by wizball6502 ().

  • Ich glaube mal die Umschaltung auf Leerzeichen ist für die Druckerausgabe gedacht.
    Im ROM-Listing kann man da auf jeden Fall viel lesen.

    In dem Programm verwende ich POKE19,1:printspc(s):geta$:
    geta$ ist dabei äquivalent zu poke19,0


    Schönen Gruß.

    The post was edited 2 times, last by BIF ().

  • @BIF Was hältst du von der 65 in POKE19,65? Gehst du mit mir einig, dass es egal ist, welche Zahl zwischen 1-255 dort steht? Wäre noch eine Serie Wert: „Das Geheimnis hinter den Wunderpokes - DAS steckt wirklich dahinter“ :f5:

    Die Anwendung von POKE242,0 ist auch sehr interessant. Aber auch diese Adresse sollte man nach dem erfolgten Zaubertrick (Screenrollen verhindern) wieder auf den ursprünglichen Wert zurücksetzen, um seltsames Verhalten zu vermeiden. Berufsethik sozusagen. :saint:

    Zu guter Letzt noch ein Benchmarkvergleich, den ich kürzlich gemacht habe, zum Platzieren des Cursors auf dem Bildschirm aufgrund von Zeile und Spalte.

    Source Code

    1. Die folgende Variante ist bisher am Schnellsten:
    2. 10 fori=1to24:a$=a$+"{down}":next
    3. 20 z=12:s=20
    4. 30 print"{home}"left$(a$,z)tab(s)"test";
    5. also z.B. schneller als...
    6. 20 z=12:s=20
    7. 30 poke211,s:poke214,z:sys58640:print"test";
    8. ...wenn man von der Initialisierung von a$ mal absehen möchte.
    Display All

    Ein SPC() und TAB() benötigt übrigens kein ";" am Schluss um zu verhindern, dass der PRINT-Command eine Zeilenschaltung macht.Das folgende Beispiel schreibt das Wort "test" auch ohne Semikolon im Anschluss der 20 Leerstellen.

    Source Code

    1. 10 printspc(20)
    2. 20 print"test"

    The post was edited 3 times, last by wizball6502 ().

  • New

    @BIF: Gerade erst entdeckt: gamebase64.com/game.php?id=25084

    Eine Jugendsünde? :thumbsup: Ich sehe schon, du hast schon einige BASIC-Zeilen auf dem Buckel. Hut ab. Dein BASIC-Spiel aus dem Jahre 2006 scheint mir spieltechnisch sehr umfangreich zu sein. Wie lange hast du denn damals daran gesessen, bis es Release-würdig war? Ich persönlich kenne Skat leider überhaupt nicht, aber ich kann mir schon vorstellen, dass das Spiel für einen Liebhaber etwas hergibt. Sieht jedenfalls cool aus.
  • New

    Habe mein Blackjack noch ein wenig aufpoliert (grosse Karten mit runden Ecken, Muster auf Kartenrückseite) und - was mich besonders freut - endlich einen sinnvollen Einsatz für den ECM-Modus gefunden. Der ECM-Modus erlaubt bis zu 4 verschiedene Hintergrund-Farben auf ein einzelnes Zeichen anzuwenden. Das wird hier bei den Karten (Hintergrund weiss, Schriftfarbe rot, schwarz oder hellblau) und bei der Gewinn-Meldung (Hintergrund rot, Schriftfarbe weiss) angewendet. Dafür hat man nur 64 Zeichen, aber für ein Kartenspiel braucht es nicht viel mehr. Und mir gefällt grundsätzlich die Reduktion aufs Wesentliche. 8)



    Edit: Der Fokus auf Look & Feel zollt ihren Tribut: Ein PUR-80 Zehnzeiler ist das nicht mehr. Müsste aber schauen, ob ich das stattdessen in einem PUR-256 Zehnzeiler unterbringen kann. Vermutlich mache ich aber eher ein übersichtliches, dokumentiertes BASIC-Programm daraus - als Anschauungsvorlage und funktionelle Basis - falls jemand selbst mal ein eigenes Kartenspiel entwickeln möchte.

    The post was edited 4 times, last by wizball6502 ().

  • New

    Jo, der ECM-Modus ist für Kartenspiele auch sehr gut geeignet.
    Man muß wohl nur die Zeichen für die Karten-Farben umkopieren.

    Wie lang hab ich am Skat-Karten-Programm gearbeitet ?
    Keine Ahnung, das Spiel ist natürlich in mehreren Etappen entstanden.
    Rein theoretisch könnte ich da natürlich wieder neu einsteigen und weiterprogrammieren.
    Aber irgendwann hab ich mich dann wieder anderen Aufgaben und Programmen zugewendet.

    Man kann ja in Basic so viel machen.


    Schönen Gruß.
  • New

    Sehr cooles Projekt. Weiter so!

    Allerdings gäbe es da noch ne klitzekleine Korrektur:

    Das Ass besitzt nämlich ZWEI Wertigkeiten, nämlich 11 UND 1.

    Folglich könnte man das noch so anpassen:

    Source Code

    1. 5000 if nc$="ASS" then gosub 6000
    2. 6000 if hd+11 > 21 then 6020
    3. 6010 hd=hd+11: goto 6030
    4. 6020 hd=hd+1
    5. 6030 return
    Drücken Sie jetzt bitte die Any-Taste !