Skriptbeispiel Spielkarten

    • Offizieller Beitrag

    Hi,
    für all jene, die gern Kartenspiele programmieren: Windows hält ja bereits Karten und Deckblätter bereit.
    Hier mal ein kleines Bsp., wie man das nutzen kann:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    #include <Constants.au3>
    #include <GUIConstantsEx.au3>
    #include <Array.au3>
    Opt ("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _Main ( )
    _Main (True)

    [/autoit] [autoit][/autoit] [autoit]

    Func _Main ($mixed=False)
    Local $a_hBMP[52][3], $a_hBitmap[52], $hGraphic, $hGUI, $hInstance
    Local $ressource = "cards.dll"

    ; Load ressource dll as datafile
    $hInstance = _WinAPI_LoadLibraryEx ($ressource, $LOAD_LIBRARY_AS_DATAFILE)

    ; Load bitmap's from library
    ; Farben sind in der Dll falsch angeordnet, ebenso die Asse
    ; im Array [i][0]=dll-Indx, [i][1]=echte Reihenfolge, [i][2]=BMP-Handle
    Local $j = 15
    For $i = 0 To 38
    If $i = 12 Or $i = 25 Or $i =38 Then
    $a_hBMP[$i][0] = $j -13
    $a_hBMP[$i][1] = $i +1
    $a_hBMP[$i][2] = _WinAPI_LoadBitmap ($hInstance, $a_hBMP[$i][0])
    Else
    $a_hBMP[$i][0] = $j
    $a_hBMP[$i][1] = $i +1
    $a_hBMP[$i][2] = _WinAPI_LoadBitmap ($hInstance, $a_hBMP[$i][0])
    EndIf
    $j += 1
    Next
    $j = 2
    For $i = 39 To 50
    $a_hBMP[$i][0] = $j
    $a_hBMP[$i][1] = $i +1
    $a_hBMP[$i][2] = _WinAPI_LoadBitmap ($hInstance, $a_hBMP[$i][0])
    $j += 1
    Next
    $a_hBMP[51][0] = 1
    $a_hBMP[51][1] = 52
    $a_hBMP[51][2] = _WinAPI_LoadBitmap ($hInstance, $a_hBMP[51][0])

    [/autoit] [autoit][/autoit] [autoit]

    If $mixed Then
    ; Get random order
    Local $aImagesIndex[52], $RandomIndex
    For $i = 0 To 51
    Do
    $RandomIndex = Random(0, 51, 1)
    _ArraySearch($aImagesIndex, String($RandomIndex))
    If @error Then $aImagesIndex[$i] = String($RandomIndex)
    Until $aImagesIndex[$i]
    Next
    ; Set BMP-Handle to random order
    Local $aTmp[52][3]
    For $i = 0 To UBound($aTmp) -1
    $aTmp[$i][0] = $a_hBMP[$aImagesIndex[$i]][0]
    $aTmp[$i][1] = $a_hBMP[$aImagesIndex[$i]][1]
    $aTmp[$i][2] = $a_hBMP[$aImagesIndex[$i]][2]
    Next

    ; Group by partial sort
    _ArraySort($aTmp, 0, 0, 12, 1)
    _ArraySort($aTmp, 0, 13, 25, 1)
    _ArraySort($aTmp, 0, 26, 38, 1)
    _ArraySort($aTmp, 0, 39, 51, 1)
    $a_hBMP = $aTmp
    $aTmp = 0
    EndIf

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Create GUI
    Local $title='Karten reinfarbig'
    If $mixed Then $title = 'Karten gemischt sortiert'
    $hGUI = GUICreate ($title, 710, 350)
    GUISetBkColor(0x008000)
    GUISetState ()

    ; Initialize GDI+ library
    _GDIPlus_Startup ()

    ; Create bitmap object's from bitmap handle's
    For $i = 0 To UBound($a_hBitmap) -1
    $a_hBitmap[$i] = _GDIPlus_BitmapCreateFromHBITMAP ($a_hBMP[$i][2])
    Next

    ; Create a Graphics object from a window handle
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)

    ; Draw all bitmap object's
    Local $x = 20, $y = 20, $count
    For $i = 0 To UBound($a_hBitmap) -1
    $count = $i +1
    _GDIPlus_GraphicsDrawImage ($hGraphic, $a_hBitmap[$i], $x, $y)
    If $i > 1 And Mod($count, 13) = 0 Then
    $x += 100
    Else
    $x += 20
    EndIf
    If $i = 25 Then
    $x = 20
    $y += 140
    EndIf
    Next

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    For $i = 0 To UBound($a_hBitmap) -1
    _GDIPlus_ImageDispose ($a_hBitmap[$i])
    _WinAPI_DeleteObject ($a_hBMP[$i][2])
    Next
    _WinAPI_FreeLibrary ($hInstance)

    ; Shut down GDI+ library
    _GDIPlus_ShutDown ()
    GUIDelete()
    EndFunc ;==>_Main

    [/autoit]

    Edit: Habe (nur im geposteten Skript, nicht im Anhang) mal erweitert, dass die gemischten Karten in den Blöcken sortiert sind. Sieht besser aus ;)

    Edit2: Neue Version: die Karten befinden sich nun farblich und wertemäßig in der (in DE) üblicherweise verwendeten Reihenfolge. Also Karo-Rot-Pik-Kreuz und 2 bis As. Die gemischten Karten sind jetzt innerhalb des jeweiligen Stapels sortiert.

    DL bisher: 17

  • ich krieg nen fehler oO

    Code
    _WinAPI_LoadBitmap: Der angegebene Ressourcenname wurde nicht in der Image-Datei gefunden.

    Padmak

    • Offizieller Beitrag

    Laß dir mal den Wert von

    [autoit]

    $hInstance = _WinAPI_LoadLibraryEx ($ressource, $LOAD_LIBRARY_AS_DATAFILE)

    [/autoit]

    in die Konsole ausgeben. Falls $hInstance = 0 ist, dann hast du die cards.dll nicht auf dem PC. Allerdings ist die ab Win98 definitiv dabei, bei Vista weiß ich nicht.

  • Is echt interesant :thumbup:
    Naja, wenn sie nicht dabei ist, liehfert man sie eben mit!

    Was lizenztechnisch ein Problem darstellt, wenn man das Script dann mit DLL weitergibt. Immer drauf achten : Auch die DLL's von MS sind keine Freeware !

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

    • Offizieller Beitrag

    Habe das Bsp. noch etwas nachgebessert. Die gemischte Ausgabe wird jetzt innerhalb jedes Stapels sortiert.
    Die Reihenfolge der Farben und Karten habe ich auch berichtigt. Hätte eigentlich Sinn gemacht, wenn diese in der Dll nach Farben und Werten aufsteigend enthalten sind. Aber Kreuz als erste Farbe und As als erste Karte... In Redmond ticken die Uhren halt doch anders. :D

  • Laß dir mal den Wert von

    [autoit]

    $hInstance = _WinAPI_LoadLibraryEx ($ressource, $LOAD_LIBRARY_AS_DATAFILE)

    [/autoit]

    in die Konsole ausgeben. Falls $hInstance = 0 ist, dann hast du die cards.dll nicht auf dem PC. Allerdings ist die ab Win98 definitiv dabei, bei Vista weiß ich nicht.

    Gleiches Problem bei mir - aber ich verwende Vista, und habe die cards.dll nicht auf dem Rechner...
    $hInstance ist hier 0x00000000

  • Sonst testet mal diese cards.dll ;) http://home.comcast.net/~ammaxamma/
    Und ich hab mal die cards.dll-funktionen übersetzt:

    Spoiler anzeigen
    [autoit]


    ; calling conventions and constants from http://www.codeproject.com/KB/cs/drawcardscp1.aspx
    Global $CardsDLL = DllOpen("Cards.DLL")

    [/autoit] [autoit][/autoit] [autoit]

    ; public enum eSUIT : int
    ; {
    Global Const $CLUBS = 0
    Global Const $DIAMOND = 1
    Global Const $HEARTS = 2
    Global Const $SPADES = 3

    [/autoit] [autoit][/autoit] [autoit]

    ; public enum eRank : int
    ; {
    Global Const $ACE = 0
    Global Const $TWO = 1
    Global Const $THREE = 2
    Global Const $FOUR = 3
    Global Const $FIVE = 4
    Global Const $SIX = 5
    Global Const $SEVEN = 6
    Global Const $EIGHT = 7
    Global Const $NINE = 8
    Global Const $TEN = 9
    Global Const $JACK = 10
    Global Const $QUEEN = 11
    Global Const $KING = 12
    ; }

    [/autoit] [autoit][/autoit] [autoit]

    ; public enum eBACK : int
    ; {
    Global Const $CROSSHATCH = 53;, /* XP = CROSSHATCH */
    Global Const $WEAVE1 = 54;, /* XP = SKY */
    Global Const $WEAVE2 = 55;, /* XP = MINERAL */
    Global Const $ROBOT = 56;, /* XP = FISH */
    Global Const $FLOWERS = 57;, /* XP = FROG */
    Global Const $VINE1 = 58;, /* XP = MOONFLOWER */
    Global Const $VINE2 = 59;, /* XP = ISLAND */
    Global Const $FISH1 = 60;, /* XP = SQUARES */
    Global Const $FISH2 = 61;, /* XP = MAGENTA */
    Global Const $SHELLS = 62;, /* XP = SANDDUNES */
    Global Const $CASTLE = 63;, /* XP = SPACE */
    Global Const $ISLAND = 64;, /* XP = LINES */
    Global Const $CARDHAND = 65;, /* XP = TOYCARS */
    Global Const $UNUSED = 66;, /* XP = UNUSED */
    Global Const $THE_X = 67;, /* XP = THE_X */
    Global Const $THE_O = 68; /* XP = THE_0 */
    ; }

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $mdFaceUp = 0; /* Draw card face up */
    Global Const $mdFaceDown = 1; /* Draw card face down */
    Global Const $mdHilite = 2; /* Same as FaceUp except drawn inverted */
    Global Const $mdGhost = 3; /* Draw a ghost card -- for ace piles */
    Global Const $mdRemove = 4; /* draw background specified by color */
    Global Const $mdInvisibleGhost = 5; /* ? */
    Global Const $mdDeckX = 6; /* Draw X */
    Global Const $mdDeckO = 7; /* Draw O */

    [/autoit] [autoit][/autoit] [autoit]

    Func _cdtInit($width,$height)
    Local $result = DllCall($CardsDLL,"int","cdtInit","int*",$width,"int*",$height)
    If @error Then Return SetError(1,0,0)
    Return $result[0]
    EndFunc
    Func _cdtTerm()
    Local $result = DllCall($CardsDLL,"none","cdtTerm")
    If @error Then Return SetError(1)
    EndFunc
    Func _cdtDraw($hdc,$x,$y,$card,$mode,$color)
    Local $result = DllCall($CardsDLL,"int","cdtDraw","ptr", $hdc, "int", $x, "int", $y, "int", $card, "int", $mode, "long", $color)
    If @error Then Return SetError(1,0,0)
    Return $result[0]
    EndFunc
    Func _cdtDrawExt($hdc,$x,$y,$dx,$dy,$card,$mode,$color)
    Local $result = DllCall($CardsDLL,"int","cdtDrawExt","ptr", $hdc, "int", $x, "int", $y, "int", $dx, "int", $dy, "int", $card, "int", $mode, "long", $color)
    If @error Then Return SetError(1,0,0)
    Return $result[0]
    EndFunc
    Func _cdtAnimate($hdc, $cardback, $x, $y, $frame)
    Local $result = DllCall($CardsDLL,"int","cdtAnimate","ptr", $hdc, "int", $cardback ,"int",$x,"int",$y, "int", $frame )
    If @error Then Return SetError(1,0,0)
    Return $result[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _cdtGetCard($Suit, $Rank)
    REturn ($Suit+$Rank)*4
    EndFunc

    [/autoit]