Kartenspiele

  • @ RKSoft

    Ok, wenn Du im Boot bleibst bleibe ich auch. 2 Spieler dann.
    Ich behaupte aber weiterhin, gescheite KI und akzeptable KI Geschwindigkeit in der von Bugjam gewünschten Form gibt es mit V2 Basic nicht.

    Machen wir Matatu als Programmierübung. Aber etwas Besseres als die Android App wird das Spiel dann nicht. Ich werde den Code wieder veröffentlichen, evtl. macht ja wer anders die KI und ich liefere das Regelgerüst und den 2P-Modus.
  • OK, erstmal 2 Spieler, dass die Regeln stehen. Hast wohl recht, das geht nicht in BASIC - kompilieren bringt ja noch was Speed, aber das genuegt wohl nicht. Andererseits muss er ja nicht gleich spielen wie ein Weltmeister - aber er sollte zumindest so klug sein, wenn er z.B. einen J eund einen K auf der Hand hat, erst den J und darauf dann den K zu legen, anstatt den K, nur weil der mehr Punkte zaehlt. Das ist fuer mich jetzt nicht wirklich "Intelligenz" (im Sinne von Spieltaktik), sondern ganz grundlegende Spiellogik...
  • Hehe, ja, hast eh recht - ich dachte nur, ich erlaeutere mal die "Intelligenz" etwas naeher - das klingt so komplex, ist aber an sich erstmal recht simpel, wenn man nur die groebsten Fehler vermeiden will, die die "KI" von der App macht. Das ist mir neulich so eingefallen, wahrschinlich als ich auf dem Haeusl sass und Matatu auf dem Handy gezockt habe. ;)
  • Ich habe mir schon ein Konzeptpapier gemacht. Ich arbeite zuerst an der reinen Spielmechanik. Visualisiert wird mit Zahlencodes (H5 für Herz5 usw. in primitivster Formatierung.

    Wenn die Spielmechanik sitzt kommen Char-Grafiken dazu (Rahmen mit Symbolen für Karten, etc). Wobei ich hoffe, dass RKSoft diese Char-Grafiken verändern wird. Er macht das einfach so gut. :)

    Es müssen dann auch visuelle Lösungen gefunden werden wenn man viele Karten auf der Hand hat, d.h. eine Möglichkeit zu blättern. Das kommt aber erst wenn die Spiellogik sitzt.

    Ich setze das Spiel nicht auf dem Plus/4, sondern gleich am C128 um. Basic 3.5/7.0 nimmt sich da nicht viel. Ich kann aber den "Play" Befehl für das Abspielen primitiver Soundeffekte nutzen ohne den SID näher zu kennen.

    Das Listing wird es für RKSoft sowieso als Textdatei geben.

    Aktuell in der Pipeline habe ich:

    • Matatu in Basic (evtl. dieses Jahr noch - Spielmechanik-WIP-Versionen kann ich ja hier rein posten falls Bugjam das Verhalten testen möchte und Ratschläge geben
    • C64 Intro in ASM mit SID-Musik und mehreren Bildschirmmodi per IRQ (die nächsten 12 Monate)
    • Bitmap-Effekte in Basic am Schneider CPC - das CPC Basic ist halt so überlegen geil, dass man ohne Hardwarekenntnisse Bitmaps manipulieren kann. Es gibt einen Befehl "test", der mir sagt, an welcher BS-Koordinate welche Pixelfarbe gesetzt ist. "testr" ermöglicht eine Pixelabfrage relativ zum aktuellen Koordinatenursprung. So euphorisch der C128 einen macht - für Amateurcoder legt der CPC immer noch ne Schippe drauf. Für Profis ist es egal. Da wird es in jedem Fall Assembler und das gibt an jedem Computer Knoten im Hirn. Da zählt dann nur noch die Hardware, und da punktet der C64 und der C128 vor allem mit Sprites.
  • Kleines Update :

    Habe jetzt am c128 die Grundlage geschaffen. Karten mischen und ausgeben funktioniert.

    Erstmal alles text basiert mit 2 Spieler Modus. Dann kommt ki dazu bzw was man in basic als ki halt machen kann.

    Läuft erstmal die engine, kann man die Visualisierung umstellen auf char Grafik mit Karten.

    @ bugjam :

    Ich bin kein Profi coder und vieles was du dir vielleicht einfach vorstellst ist es gar nicht. Allein das verdammte mischen von 52 Karten mit 4 blättern zu je 13 Karten musste ich erstmal hinkriege ohne dass der c128 ewig rechnet sondern halbwegs zackig. Ich mach das gern und weil ich zugesagt habe aber bitte kein Wunder erwarten. Lieber freundlich überrascht sein wenn es am Ende spielbar ist.

    Quellcode kommt hier rein sobald text Version im 2 Spieler Modus fertig. Die text version wird nur das nötigste enthalten, der Fokus geht auf die Logik. Wenn die sitzt geht es ans malen.
  • @Bytebreaker: Das stimmt wohl, als Nicht-Coder habe ich oft eher naive Vorstellungen davon, was "einfach" und was "schwierig" zu implementieren ist. :) Keine Sorge, ich finde es super, dass Du Dich ueberhaupt des Projekts angenommen hast, von daher freue ich mich auf jeden Fall auf jedes (Zwischen-) Ergebnis. Ein bisschen Speed kann man sicher auch noch durch Kompilieren rausholen; und wenn es spezifische Fragen gibt, wird Dir hier im Forum ja bestimmt auch geholfen. Das war eh so meine Idee - ein win-win: ein nettes kleines neues Spiel fuer mich und die Community, und eine Lernerfahrung fuer einen Coder.
    Von daher all thumbs up!
  • Bytebreaker schrieb:

    Ich bin kein Profi coder und vieles was du dir vielleicht einfach vorstellst ist es gar nicht. Allein das verdammte mischen von 52 Karten mit 4 blättern zu je 13 Karten musste ich erstmal hinkriege ohne dass der c128 ewig rechnet sondern halbwegs zackig.
    Zum Thema "zufällig mischen" verbrechen Programmieranfänger mitunter die maximal umständlichsten Algorithmen, daher hier die Standardlösung: :P

    Quellcode

    1. rem init:
    2. ma = 51:rem maximum index (0..51)
    3. dim s(ma):rem stack of cards
    4. for i = 0 to ma
    5. s(i) = i
    6. next
    7. rem shuffle:
    8. for i = 0 to ma:rem iterate over all positions
    9. j = int(rnd(0) * ma):rem select a random partner
    10. t = s(j):s(j) = s(i):s(i) = t:rem triangle swap
    11. next
    Alles anzeigen

    Bitte nicht als Kritik missverstehen...

    (ach ja, ich war jetzt zu faul, um nachzusehen, welches Argument für RND() in diesem Fall das "Beste" ist)
    Yes, I'm the guy responsible for the ACME cross assembler
  • Mac Bacon schrieb:

    Zum Thema "zufällig mischen" verbrechen Programmieranfänger mitunter die maximal umständlichsten Algorithmen, daher hier die Standardlösung: :P
    Ähm, nein...

    Quellcode

    1. for i = 0 to ma:rem iterate over all positions
    2. j = int(rnd(0) * ma):rem select a random partner
    Siehe hier: "Similarly, always selecting j from the entire range of valid array indices on every iteration also produces a result which is biased"

    Quellcode

    1. 10 x=rnd(-1963):fori=1to81:y=rnd(1):next
    2. 20 forj=1to5:printchr$(rnd(1)*16+70);:next
    3. 30 printint(rnd(1)*328)-217

    sd2iec Homepage
  • Unseen schrieb:

    Siehe hier: "Similarly, always selecting j from the entire range of valid array indices on every iteration also produces a result which is biased"
    As a concrete example of this bias, observe the distribution of possible outcomes of shuffling a three-element array [1, 2, 3]. There are 6 possible permutations of this array (3! = 6), but the algorithm produces 27 possible shuffles (3³ = 27). In this case, [1, 2, 3], [3, 1, 2], and [3, 2, 1] each result from 4 of the 27 shuffles, while each of the remaining 3 permutations occurs in 5 of the 27 shuffles.
    ...sobald man es weiß, ist es ganz logisch...
    Danke für die Korrektur!
    Yes, I'm the guy responsible for the ACME cross assembler
  • Ok, hier jetzt die hoffentlich korrekte Version:

    Quellcode

    1. rem shuffle:
    2. for i = ma to 1 step -1:rem iterate over positions (stop early because index 0 could only be swapped with itself anyway)
    3. j = int(rnd(0) * (i + 1)):rem select a random partner
    4. t = s(j):s(j) = s(i):s(i) = t:rem triangle swap
    5. next
    Hab gerade noch gesehen, dass mein erstes Programm sogar noch einen weiteren Fehler hatte, denn eigentlich wollte ich das RND-Ergebnis mit (ma + 1) multiplizieren.

    @Endurion: Durch den Test auf belegte/freie Slots landest Du automatisch in der quadratischen Komplexitätsklasse, zumindest habe ich Deine Beschreibung jetzt so verstanden.
    Yes, I'm the guy responsible for the ACME cross assembler
  • Bytebreaker schrieb:

    Kleines Update :

    Habe jetzt am c128 die Grundlage geschaffen. Karten mischen und ausgeben funktioniert.

    Erstmal alles text basiert mit 2 Spieler Modus. Dann kommt ki dazu bzw was man in basic als ki halt machen kann.

    Läuft erstmal die engine, kann man die Visualisierung umstellen auf char Grafik mit Karten.

    @ bugjam :

    Ich bin kein Profi coder und vieles was du dir vielleicht einfach vorstellst ist es gar nicht. Allein das verdammte mischen von 52 Karten mit 4 blättern zu je 13 Karten musste ich erstmal hinkriege ohne dass der c128 ewig rechnet sondern halbwegs zackig. Ich mach das gern und weil ich zugesagt habe aber bitte kein Wunder erwarten. Lieber freundlich überrascht sein wenn es am Ende spielbar ist.

    Quellcode kommt hier rein sobald text Version im 2 Spieler Modus fertig. Die text version wird nur das nötigste enthalten, der Fokus geht auf die Logik. Wenn die sitzt geht es ans malen.
    Bin auf eine erste Beta gespannt! :)
  • Danke für die Shuffle-Tips. Knapp und elegant wie man es von Euch kennt. :)

    Ich habe mir etwas eigenes ausgedacht, das vielleicht etwas eigenwillig ist, aber funktioniert, nicht zu lang dauert und einen begrenzten Satz Karten jedes Mal nach etwas umstellt was wie Zufall aussieht.

    Ich sehe es auch kommen dass natürlich bessere Vorschläge kommen was die Programmarchitektur/Konzeption angeht. Davon will ich gerne lernen. Trotzdem möchte ich zunächst versuchen, mit eigenen Denkansätzen in akzeptabler Spielgeschwindigkeit ans Ziel zu kommen. Wenn das scheitert, dann nehme ich die Alternativen. Und beim nächsten Kartenspiel sowieso das Eleganteste was ich damn kenne.

    Ich habe es zum Beispiel mit Mikes Punktsetzalgorithmus auf Bitmaps so gemaht. Ich hatte einen eigenen, der hat auch funktioniert aber ich kenne keinen der so schnell ist wie Mike's. Also ist das meine Referenz. Trotzdem finde ich es wichtig, selbst zu erfinden und nicht nur zu übernehmen, auch wenn die eigenen Sachen nicht auf Anhieb so effizient sind.

    Anbei mein Shuffle-Code, er ist in VICE C128 einfügbar und ausführbar.

    Quellcode

    1. 1 print "press any key.."
    2. 2 x=rnd(-time)
    3. 10 scnclr
    4. 20 print "initializing.."
    5. 100 rem matatu intit
    6. 110 dim ca$(52,3):rem 1 array für stapel und 2 spieler
    7. 120 data "he15","he20","he03","he04","he05","he06","he07","he08","he09","he10"
    8. 121 data "he11","he12","he13"
    9. 122 data "pi15","pi20","pi03","pi04","pi05","pi06","pi07","pi08","pi09","pi10"
    10. 123 data "pi11","pi12","pi13"
    11. 124 data "ka15","ka20","ka03","ka04","ka05","ka06","ka07","ka08","ka09","ka10"
    12. 125 data "ka11","ka12","ka13"
    13. 126 data "kr15","kr20","kr03","kr04","kr05","kr06","kr07","kr08","kr09","kr10"
    14. 127 data "kr11","kr12","kr13"
    15. 130 fori=1to52:read n$:ca$(i,0)=n$:next i
    16. 131 print "shuffling cards.."
    17. 138 co=1
    18. 139 do while co<53
    19. 140 zz=int(rnd(1)*52)+1
    20. 141 ca$(co,3)=ca$(zz,0):ca$(zz,0)="0000":co=co+1
    21. 142 loop
    22. 145 co=1:dim buf$(52)
    23. 147 for i=1 to 52
    24. 148 if ca$(i,0)<>"0000" then buf$(co)=ca$(i,0):co=co+1
    25. 149 next i
    26. 150 co=1
    27. 152 for i=1 to 52
    28. 153 if ca$(i,3)="0000" then ca$(i,3)=buf$(co):co=co+1
    29. 154 next i
    30. 155 for i=1to52:ca$(i,0)="0000":next i
    31. 160 scnclr
    32. 169 print:print
    33. 170 print "hand out cards to p1 and p2.."
    34. 180 for i=1to7:ca$(i,1)=ca$(i,3):ca$(i,3)="0000":next
    35. 181 for i=8to14:ca$(i-7,2)=ca$(i,3):ca$(i,3)="0000":next
    36. 182 cc=15:rem current stack card
    37. 183 print "p1:"
    38. 184 for i=1to52:printca$(i,1)" ";:next
    39. 185 print "p2:"
    40. 186 for i=1to52:printca$(i,2)" ";:next
    41. 192 print:print:print"top of stack = "ca$(cc,3)
    42. 193 print "stack:"
    43. 194 for i=1to52:printca$(i,3)" ";:next
    Alles anzeigen
    Ich mache jetzt weiter mit dem Regelwerk und der Hauptschleife für den 2-Spieler-Modus. Ihr seht schon ich werde Strings auswerten und Teile davon in Zahlen umwandeln um damit zu rechnen.
    Dateien
    • shuffle.prg

      (1,26 kB, 1 mal heruntergeladen, zuletzt: )
  • Lese interessiert mit, Bytebreaker :) .

    Was mir aufgefallen ist:

    Zeile 130: Der Zwischenschritt über N$ ist überflüssig/kost nur Zeit.


    Ohne jetzt groß im Spiel zu stecken, würde ich den Kartensatz wohl nur einmal als Strings speichern und die Spieler-Karten nur als Werte händeln. Es sei denn, es gibt einen guten Grund dagegen.
    Read'n'Blast my jump'n'stop-text-sprite-scroller Select A Move

    Ex-TLI (The Level 99 Industries) & Ex-TNP (The New Patriots) & Ex-TEA (The East Agents) & ?