Last active
January 13, 2019 20:55
-
-
Save DouglasMeyer/0691ecc71244c414a4ea50d90aa30b19 to your computer and use it in GitHub Desktop.
TableGames Solitare
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
xmlns:xlink="http://www.w3.org/1999/xlink" | |
version="1.1" | |
width="936" | |
height="440" | |
> | |
<title>Contemporary design deck of playing card</title> | |
<desc>Contemporary design deck of playing card with typographic face cards - Published by Betzaar.com under the CreativeCommons Attribution+ShareAlike licence</desc> | |
<defs> | |
<rect id="stack" width="72" height="110" rx="6" fill="transparent" stroke="black" stroke-width=".5"/> | |
<!-- Card outlines --> | |
<rect id="out" width="72" height="110" rx="6" fill="white" stroke="black" stroke-width=".5"/> | |
<g id="out_club"> | |
<use xlink:href="#out"/> | |
<use x="5" y="35" transform="scale(.5)" xlink:href="#club"/> | |
<use x="5" y="35" transform="rotate(180,36,55) scale(.5)" xlink:href="#club" /> | |
</g> | |
<g id="out_diamond"> | |
<use xlink:href="#out"/> | |
<use x="6" y="35" transform="scale(0.5, 0.5)" xlink:href="#diamond"/> | |
<use x="6" y="35" transform="rotate(180,36,55) scale(.5)" xlink:href="#diamond"/> | |
</g> | |
<g id="out_heart"> | |
<use xlink:href="#out"/> | |
<use x="5" y="35" transform="scale(0.5, 0.5)" xlink:href="#heart"/> | |
<use x="5" y="35" transform="rotate(180,36,55) scale(.5)" xlink:href="#heart"/> | |
</g> | |
<g id="out_spade"> | |
<use xlink:href="#out"/> | |
<use x="5" y="35" transform="scale(0.5, 0.5)" xlink:href="#spade"/> | |
<use x="5" y="35" transform="rotate(180,36,55) scale(.5)" xlink:href="#spade"/> | |
</g> | |
<!-- Rank text --> | |
<g id="r1"><text x="2" y="15">A</text><text x="2" y="15" transform="rotate(180,36,55)">A</text></g> | |
<g id="r2"><text x="2" y="15">2</text><text x="2" y="15" transform="rotate(180,36,55)">2</text></g> | |
<g id="r3"><text x="2" y="15">3</text><text x="2" y="15" transform="rotate(180,36,55)">3</text></g> | |
<g id="r4"><text x="2" y="15">4</text><text x="2" y="15" transform="rotate(180,36,55)">4</text></g> | |
<g id="r5"><text x="2" y="15">5</text><text x="2" y="15" transform="rotate(180,36,55)">5</text></g> | |
<g id="r6"><text x="2" y="15">6</text><text x="2" y="15" transform="rotate(180,36,55)">6</text></g> | |
<g id="r7"><text x="2" y="15">7</text><text x="2" y="15" transform="rotate(180,36,55)">7</text></g> | |
<g id="r8"><text x="2" y="15">8</text><text x="2" y="15" transform="rotate(180,36,55)">8</text></g> | |
<g id="r9"><text x="2" y="15">9</text><text x="2" y="15" transform="rotate(180,36,55)">9</text></g> | |
<g id="r10"><text x="2" y="15">10</text><text x="2" y="15" transform="rotate(180,36,55)">10</text></g> | |
<g id="r11"><text x="2" y="15">J</text><text x="2" y="15" transform="rotate(180,36,55)">J</text></g> | |
<g id="r12"><text x="2" y="15">Q</text><text x="2" y="15" transform="rotate(180,36,55)">Q</text></g> | |
<g id="r13"><text x="2" y="15">K</text><text x="2" y="15" transform="rotate(180,36,55)">K</text></g> | |
<!-- Club --> | |
<path id="club" d="M 5.2157714,5.882057 C 4.7718857,5.271543 4.328,4.494857 4.328,3.458743 4.328,1.461029 5.9186286,0 7.8610286,0 c 1.9792,0 3.5330284,1.498286 3.5330284,3.458743 0,1.035886 -0.443886,1.812571 -0.888,2.423314 l 0.09257,0.09257 c 0.536457,-0.388343 1.3504,-0.647543 1.831314,-0.647543 1.9424,0 3.2928,1.701714 3.2928,3.5515432 0,2.0347418 -1.572343,3.6070848 -3.551772,3.6070848 -1.072685,0 -2.5897134,-0.610514 -3.6438854,-2.182857 h -0.074055 c 0.258971,3.162974 0.666286,4.383774 1.6649144,5.586288 V 16 H 5.6045714 V 15.889143 C 6.6034286,14.686629 7.0105143,13.465829 7.2694857,10.302857 H 7.1954286 C 6.1408,11.874971 4.6242286,12.485714 3.5515429,12.485714 1.5721143,12.485714 0,10.913371 0,8.8786292 0,7.0288 1.3501714,5.327086 3.2925714,5.327086 c 0.4809143,0 1.2946286,0.2592 1.8310857,0.647543 l 0.092114,-0.09257 z"/> | |
<!-- Diamond --> | |
<path id="diamond" d="M 11.6592,8 5.8212571,16 0,8 5.8212571,0 11.6592,8 z"/> | |
<!-- Heart --> | |
<path id="heart" d="M 6.6448,2.994057 C 7.192,0.978743 8.5837716,0 10.058971,0 c 1.773486,0 3.197943,1.650286 3.197943,3.857371 0,2.571429 -1.209143,4.452572 -2.452343,6.198629 -1.1924564,1.669714 -3.5460567,4.548343 -4.1595424,5.258286 H 6.6118857 C 5.9986286,14.604343 3.6459429,11.725714 2.4523429,10.056 1.2093714,8.309943 0,6.4288 0,3.857371 0,1.650286 1.4256,0 3.1984,0 4.6729143,0 6.0649143,0.978743 6.6121143,2.994057 h 0.032686 z"/> | |
<!-- Spade --> | |
<path id="spade" d="M 8.7382856,16 h -4.290057 v -0.105371 c 0.9494857,-1.142858 1.3010285,-2.303543 1.5824,-4.765029 H 5.9252571 C 5.3801143,12.307657 4.3426286,12.800229 3.2528,12.800229 1.1430857,12.800229 0,11.3056 0,9.2484572 0,7.472457 1.7933714,5.397714 2.8662857,4.167086 4.0969143,2.760457 5.7142857,0.931886 6.5757714,0 h 0.0352 c 0.8614857,0.931886 2.4790862,2.760457 3.7099426,4.167086 1.072229,1.230628 2.865829,3.305371 2.865829,5.0813712 0,2.0571428 -1.142629,3.5517718 -3.2525714,3.5517718 -1.090057,0 -2.127543,-0.492343 -2.6722287,-1.670629 h -0.1056 c 0.2811428,2.461714 0.6331428,3.622171 1.5821717,4.765029 V 16 z"/> | |
<!-- J --> | |
<path id="jack" d="m 0.461668,32.107515 c 0,0 2.686087,0.671517 5.372157,0.671517 0.58758,0 1.17514,-0.04196 1.72076,-0.126486 0.71349,-0.545609 1.8047,-2.266372 2.30833,-5.372142 0.71351,-4.364865 3.60943,-24.594334 3.60943,-24.594334 L 9.233385,1.804703 C 9.233385,1.301064 9.485195,0.377729 9.778975,0 h 11.66761 l -0.46165,2.181849 -3.69334,0.420282 c 0,0 -2.68607,18.634614 -3.81925,24.258575 -1.21715,6.421388 -3.73532,8.897609 -7.97429,8.897609 -2.77001,0 -4.40684,-0.881367 -5.498055,-2.098492 l 0.461668,-1.552302 z"/> | |
<!-- Q --> | |
<path id="queen" d="m 29.617505,30.215686 c -0.84568,1.514307 -2.1839,2.817314 -5.88163,2.817314 -4.57764,0 -11.83222,-4.155537 -16.023475,-8.311074 C 2.18294,24.721926 0,20.953769 0,15.389575 0,7.606746 4.71901,0 12.290045,0 c 5.52948,0 7.74859,3.73294 7.74859,9.332351 0,6.726336 -3.55734,13.347023 -9.40327,15.002194 6.79678,4.120321 11.65664,5.635116 14.89606,5.635116 1.69088,0 2.88775,-0.316948 3.87381,-0.599169 l 0.21227,0.845194 z M 10.740525,2.746881 c -5.528485,0 -7.782825,6.726335 -7.782825,11.234037 0,4.402052 1.69087,7.994127 6.30422,7.994127 5.529475,0 7.782845,-6.69112 7.782845,-11.234037 0,-4.402053 -1.68991,-7.994127 -6.30424,-7.994127 z"/> | |
<!-- K --> | |
<path id="king" d="M 0.44567,28.254932 4.54576,27.408794 8.06647,2.852233 4.01096,1.916344 C 4.01096,1.381551 4.27834,0.401094 4.59032,0 h 11.943725 l -0.49023,2.316821 -3.92183,0.446281 -3.832685,24.734206 4.367485,0.311964 c 0,0.668493 -0.31196,1.916962 -0.75764,2.495704 H 0 l 0.44567,-2.050044 z m 26.338565,1.916964 c -0.57936,0.445662 -1.20328,0.935889 -3.20873,0.935889 -1.82723,0 -3.38705,-1.069588 -5.25883,-3.476159 -1.38155,-1.871159 -4.72399,-7.263661 -6.64035,-10.383292 -0.84675,-1.38155 -1.15872,-2.719153 -1.15872,-2.719153 l 13.0579,-11.676329 -3.8327,-0.935889 c 0,-0.534793 0.26738,-1.515249 0.57934,-1.916344 h 11.05244 l -0.49025,2.316821 -2.85224,0.490845 -13.36984,11.408934 c 1.69351,3.119627 6.19468,9.403455 7.84364,11.275233 1.51525,1.738698 3.1642,3.342459 4.27834,4.189836 v 0.489608 z"/> | |
</defs> | |
<g id="Back"> | |
<!-- <use xlink:href="#out" fill="blue"/> --> | |
<rect id="out" width="72" height="110" rx="6" fill="#CCF" stroke="black" stroke-width=".5"/> | |
</g> | |
<!-- And now the actual cards --> | |
<!-- Club suit --> | |
<g font-size="12" font-family="Arial"> | |
<g id="1_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r1"/> | |
<use x="28" y="47" xlink:href="#club"/> | |
</g> | |
<g id="2_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r2"/> | |
<use x="28" y="16" xlink:href="#club"/> | |
<use x="28" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="3_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r3"/> | |
<use x="28" y="47" xlink:href="#club"/> | |
<use x="28" y="16" xlink:href="#club"/> | |
<use x="28" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="4_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r4"/> | |
<use x="13" y="16" xlink:href="#club"/> | |
<use x="43" y="16" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="5_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r5"/> | |
<use x="28" y="47" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club"/> | |
<use x="43" y="16" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="6_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r6"/> | |
<use x="13" y="47" xlink:href="#club"/> | |
<use x="43" y="47" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club"/> | |
<use x="43" y="16" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="7_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r7"/> | |
<use x="28" y="32" xlink:href="#club"/> | |
<use x="13" y="47" xlink:href="#club"/> | |
<use x="43" y="47" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club"/> | |
<use x="43" y="16" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="8_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r8"/> | |
<use x="13" y="16" xlink:href="#club"/> | |
<use x="43" y="16" xlink:href="#club"/> | |
<use x="13" y="36" xlink:href="#club"/> | |
<use x="43" y="36" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="13" y="36" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="36" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="9_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r9"/> | |
<use x="28" y="47" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club"/> | |
<use x="43" y="16" xlink:href="#club"/> | |
<use x="13" y="36" xlink:href="#club"/> | |
<use x="43" y="36" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="13" y="36" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="36" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="10_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r10"/> | |
<use x="13" y="16" xlink:href="#club"/> | |
<use x="43" y="16" xlink:href="#club"/> | |
<use x="13" y="36" xlink:href="#club"/> | |
<use x="43" y="36" xlink:href="#club"/> | |
<use x="13" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="16" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="13" y="36" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="43" y="36" xlink:href="#club" transform="rotate(180,36,55)"/> | |
<use x="28" y="27" xlink:href="#club"/> | |
<use x="28" y="27" xlink:href="#club" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="11_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r11"/> | |
<use x="16" y="18" xlink:href="#jack"/> | |
<use x="16" y="18" xlink:href="#jack" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="12_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r12"/> | |
<use x="20" y="18" xlink:href="#queen"/> | |
<use x="20" y="18" xlink:href="#queen" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="13_Club"> | |
<use xlink:href="#out_club"/> | |
<use xlink:href="#r13"/> | |
<use x="20" y="18" xlink:href="#king"/> | |
<use x="20" y="18" xlink:href="#king" transform="rotate(180,36,55)"/> | |
</g></g> | |
<!-- Diamonds suit --> | |
<g font-size="12" font-family="Arial" fill="red"> | |
<g id="1_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r1"/> | |
<use x="30" y="47" xlink:href="#diamond"/> | |
</g> | |
<g id="2_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r2"/> | |
<use x="30" y="16" xlink:href="#diamond"/> | |
<use x="30" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="3_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r3"/> | |
<use x="30" y="47" xlink:href="#diamond"/> | |
<use x="30" y="16" xlink:href="#diamond"/> | |
<use x="30" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="4_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r4"/> | |
<use x="15" y="16" xlink:href="#diamond"/> | |
<use x="45" y="16" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="5_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r5"/> | |
<use x="30" y="47" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond"/> | |
<use x="45" y="16" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="6_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r6"/> | |
<use x="15" y="47" xlink:href="#diamond"/> | |
<use x="45" y="47" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond"/> | |
<use x="45" y="16" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="7_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r7"/> | |
<use x="30" y="32" xlink:href="#diamond"/> | |
<use x="15" y="47" xlink:href="#diamond"/> | |
<use x="45" y="47" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond"/> | |
<use x="45" y="16" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="8_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r8"/> | |
<use x="15" y="16" xlink:href="#diamond"/> | |
<use x="45" y="16" xlink:href="#diamond"/> | |
<use x="15" y="36" xlink:href="#diamond"/> | |
<use x="45" y="36" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="15" y="36" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="36" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="9_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r9"/> | |
<use x="30" y="47" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond"/> | |
<use x="45" y="16" xlink:href="#diamond"/> | |
<use x="15" y="36" xlink:href="#diamond"/> | |
<use x="45" y="36" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="15" y="36" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="36" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="10_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r10"/> | |
<use x="15" y="16" xlink:href="#diamond"/> | |
<use x="45" y="16" xlink:href="#diamond"/> | |
<use x="15" y="36" xlink:href="#diamond"/> | |
<use x="45" y="36" xlink:href="#diamond"/> | |
<use x="15" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="15" y="36" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="45" y="36" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
<use x="30" y="27" xlink:href="#diamond"/> | |
<use x="30" y="27" xlink:href="#diamond" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="11_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r11"/> | |
<use x="16" y="18" xlink:href="#jack"/> | |
<use x="16" y="18" xlink:href="#jack" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="12_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r12"/> | |
<use x="20" y="18" xlink:href="#queen"/> | |
<use x="20" y="18" xlink:href="#queen" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="13_Diamond" fill="red"> | |
<use xlink:href="#out_diamond"/> | |
<use xlink:href="#r13"/> | |
<use x="20" y="18" xlink:href="#king"/> | |
<use x="20" y="18" xlink:href="#king" transform="rotate(180,36,55)"/> | |
</g></g> | |
<!-- Hearts suit --> | |
<g font-size="12" font-family="Arial" fill="red"> | |
<g id="1_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r1"/> | |
<use x="30" y="47" xlink:href="#heart"/> | |
</g> | |
<g id="2_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r2"/> | |
<use x="29" y="16" xlink:href="#heart"/> | |
<use x="29" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="3_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r3"/> | |
<use x="29" y="47" xlink:href="#heart"/> | |
<use x="29" y="16" xlink:href="#heart"/> | |
<use x="29" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="4_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r4"/> | |
<use x="15" y="16" xlink:href="#heart"/> | |
<use x="44" y="16" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="5_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r5"/> | |
<use x="29" y="47" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart"/> | |
<use x="44" y="16" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="6_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r6"/> | |
<use x="15" y="47" xlink:href="#heart"/> | |
<use x="44" y="47" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart"/> | |
<use x="44" y="16" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="7_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r7"/> | |
<use x="29" y="32" xlink:href="#heart"/> | |
<use x="15" y="47" xlink:href="#heart"/> | |
<use x="44" y="47" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart"/> | |
<use x="44" y="16" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="8_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r8"/> | |
<use x="15" y="16" xlink:href="#heart"/> | |
<use x="44" y="16" xlink:href="#heart"/> | |
<use x="15" y="36" xlink:href="#heart"/> | |
<use x="44" y="36" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="15" y="36" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="36" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="9_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r9"/> | |
<use x="30" y="47" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart"/> | |
<use x="44" y="16" xlink:href="#heart"/> | |
<use x="15" y="36" xlink:href="#heart"/> | |
<use x="44" y="36" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="15" y="36" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="36" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="10_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r10"/> | |
<use x="15" y="16" xlink:href="#heart"/> | |
<use x="44" y="16" xlink:href="#heart"/> | |
<use x="15" y="36" xlink:href="#heart"/> | |
<use x="44" y="36" xlink:href="#heart"/> | |
<use x="15" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="16" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="15" y="36" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="44" y="36" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
<use x="29" y="27" xlink:href="#heart"/> | |
<use x="29" y="27" xlink:href="#heart" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="11_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r11"/> | |
<use x="16" y="18" xlink:href="#jack"/> | |
<use x="16" y="18" xlink:href="#jack" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="12_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r12"/> | |
<use x="20" y="18" xlink:href="#queen"/> | |
<use x="20" y="18" xlink:href="#queen" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="13_Heart" fill="red"> | |
<use xlink:href="#out_heart"/> | |
<use xlink:href="#r13"/> | |
<use x="20" y="18" xlink:href="#king"/> | |
<use x="20" y="18" xlink:href="#king" transform="rotate(180,36,55)"/> | |
</g></g> | |
<!-- Spades suit --> | |
<g font-size="12" font-family="Arial"> | |
<g id="1_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r1"/> | |
<use x="12" y="20" xlink:href="#spade" transform="scale(2)"/> | |
</g> | |
<g id="2_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r2"/> | |
<use x="30" y="16" xlink:href="#spade"/> | |
<use x="30" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="3_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r3"/> | |
<use x="30" y="47" xlink:href="#spade"/> | |
<use x="30" y="16" xlink:href="#spade"/> | |
<use x="30" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="4_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r4"/> | |
<use x="14" y="16" xlink:href="#spade"/> | |
<use x="45" y="16" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="5_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r5"/> | |
<use x="29" y="47" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade"/> | |
<use x="45" y="16" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="6_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r6"/> | |
<use x="14" y="47" xlink:href="#spade"/> | |
<use x="45" y="47" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade"/> | |
<use x="45" y="16" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="7_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r7"/> | |
<use x="29" y="32" xlink:href="#spade"/> | |
<use x="14" y="47" xlink:href="#spade"/> | |
<use x="45" y="47" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade"/> | |
<use x="45" y="16" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="8_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r8"/> | |
<use x="14" y="16" xlink:href="#spade"/> | |
<use x="45" y="16" xlink:href="#spade"/> | |
<use x="14" y="36" xlink:href="#spade"/> | |
<use x="45" y="36" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="14" y="36" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="36" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="9_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r9"/> | |
<use x="29" y="47" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade"/> | |
<use x="45" y="16" xlink:href="#spade"/> | |
<use x="14" y="36" xlink:href="#spade"/> | |
<use x="45" y="36" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="14" y="36" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="36" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="10_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r10"/> | |
<use x="14" y="16" xlink:href="#spade"/> | |
<use x="45" y="16" xlink:href="#spade"/> | |
<use x="14" y="36" xlink:href="#spade"/> | |
<use x="45" y="36" xlink:href="#spade"/> | |
<use x="14" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="16" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="14" y="36" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="45" y="36" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
<use x="29" y="27" xlink:href="#spade"/> | |
<use x="29" y="27" xlink:href="#spade" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="11_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r11"/> | |
<use x="16" y="18" xlink:href="#jack"/> | |
<use x="16" y="18" xlink:href="#jack" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="12_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r12"/> | |
<use x="20" y="18" xlink:href="#queen"/> | |
<use x="20" y="18" xlink:href="#queen" transform="rotate(180,36,55)"/> | |
</g> | |
<g id="13_Spade"> | |
<use xlink:href="#out_spade"/> | |
<use xlink:href="#r13"/> | |
<use x="20" y="18" xlink:href="#king"/> | |
<use x="20" y="18" xlink:href="#king" transform="rotate(180,36,55)"/> | |
</g></g> | |
</svg> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const name = 'Solitare'; | |
const suits = 'Heart Diamond Spade Club'.split(' '); | |
const cards = new Array(52).fill().map((_, index) => ({ | |
id: index, | |
suit: suits[Math.floor(index / 13)], | |
value: index % 13 + 1 | |
})); | |
/* API | |
items: [] | |
x, y, width, height, image | |
canPick, pick(keys) => [] | |
canPlace, place(keys, cardsToPlace) | |
*/ | |
class Card { | |
static get url() { return `https://gist.githubusercontent.com/DouglasMeyer/0691ecc71244c414a4ea50d90aa30b19/raw/Contemporary_playing_cards.svg/Contemporary_playing_cards.svg`; } | |
static get width() { return 72; } | |
get width(){ return Card.width; } | |
static get height() { return 110; } | |
get height(){ return Card.height; } | |
static get padding() { return 10; } | |
static get peek() { return 25; } | |
static pos(x, y) { | |
return [ | |
Card.padding + x * (Card.width + Card.padding), | |
Card.padding + y * (Card.height + Card.padding) | |
]; | |
} | |
constructor(game, id, suit, value) { | |
Object.assign(this, { | |
game, id, suit, value, revealed: false | |
}); | |
} | |
trigger() { this.game.trigger(this.id, this); } | |
get image() { | |
if (this.revealed) return `${Card.url}#${this.value}_${this.suit}`; | |
return `${Card.url}#Back`; | |
} | |
get stack() { return this.game.items.find(stack => stack.items.includes(this)); } | |
get x() { return this.stack.cardPos(this).x; } | |
get y() { return this.stack.cardPos(this).y; } | |
pick({ altKey, ctrlKey, metaKey, shiftKey }){ | |
if (shiftKey && this.revealed) { | |
const items = this.stack.items; | |
const goalStack = this.game.goalStacks.find(stack => stack.canPlace(this)); | |
const cardLastOnStack = this === items.slice(-1)[0]; | |
if (goalStack && cardLastOnStack) { | |
goalStack.items.push(items.splice(-1)[0]); | |
const newEndOfStack = items.slice(-1)[0] | |
if (newEndOfStack) { | |
newEndOfStack.revealed = true; | |
newEndOfStack.trigger(); | |
} | |
this.trigger(); | |
this.game.checkWin(); | |
return; | |
} | |
} | |
return this.stack.pick(this); | |
} | |
place(_keys, cards){ this.stack.place(this, cards); } | |
} | |
class Stack { | |
get width(){ return Card.width; } | |
get height(){ return Card.height; } | |
constructor(game, x, y) { | |
Object.assign(this, { | |
game, x, y, items: [] | |
}); | |
} | |
get image() { return `${Card.url}#stack`; } | |
cardPos(card) { | |
const index = this.items.indexOf(card); | |
return { x: this.x, y: this.y + Math.min(index, 3) }; | |
} | |
trigger() { this.game.trigger(this.id, this); } | |
} | |
class DrawStack extends Stack { | |
constructor(game, x, y) { | |
super(game, x, y); | |
cards.slice().sort(() => Math.random() - 0.5).forEach(({ id, suit, value }) => { | |
this.items.push(new Card(game, id, suit, value)) | |
}) | |
} | |
pick(_card){ | |
const { discardStack } = this.game; | |
if (this.items.length) { | |
const card = this.items.pop(); | |
card.revealed = true; | |
discardStack.items.push(card); | |
card.trigger(); | |
} else { | |
while (discardStack.items.length) { | |
const card = discardStack.items.pop(); | |
card.revealed = false; | |
this.items.push(card); | |
card.trigger(); | |
} | |
} | |
} | |
place(_card, _cards){} | |
} | |
class DiscardStack extends Stack { | |
pick(_card){ | |
const cards = this.items.slice(-1); | |
if (!cards[0]) return; | |
cards[0].trigger(); | |
return cards; | |
} | |
place(_card, _cards){} | |
} | |
class GoalStack extends Stack { | |
pick(_card){ | |
const cards = this.items.slice(-1); | |
cards[0].trigger(); | |
return cards; | |
} | |
canPlace(card){ | |
const lastOnStack = this.items.slice(-1)[0]; | |
return lastOnStack | |
? card.suit === lastOnStack.suit && | |
card.value === lastOnStack.value + 1 | |
: card.value === 1; | |
} | |
place(_card, cards){ | |
const card = cards[0]; | |
if (!this.canPlace(card)) return; | |
const items = card.stack.items; | |
items.splice(items.indexOf(card), 1); | |
this.items.push(card); | |
card.trigger(); | |
const newEndOfStack = items.slice(-1)[0] | |
if (newEndOfStack) { | |
newEndOfStack.revealed = true; | |
newEndOfStack.trigger(); | |
} | |
this.game.checkWin(); | |
} | |
} | |
class CascadingStack extends Stack { | |
pick(card) { | |
const index = this.items.indexOf(card); | |
if (index === -1) return; | |
if (card.revealed) { | |
const cards = this.items.slice(index) | |
cards.forEach(card => card.trigger()); | |
return cards; | |
} | |
} | |
place(_card, cards) { | |
const lastOnStack = this.items.slice(-1)[0]; | |
const firstHealdCard = cards[0]; | |
if (!firstHealdCard) return; | |
const canPlace = cards.length && | |
lastOnStack | |
? lastOnStack.value - 1 === firstHealdCard.value && | |
Math.floor(suits.indexOf(lastOnStack.suit)/2) !== Math.floor(suits.indexOf(firstHealdCard.suit)/2) | |
: firstHealdCard.value === 13; | |
if (!canPlace) return; | |
const sourceItems = cards[0].stack.items; | |
const newEndOfStack = sourceItems[sourceItems.indexOf(cards[0]) - 1]; | |
if (newEndOfStack) { | |
newEndOfStack.revealed = true; | |
newEndOfStack.trigger(); | |
} | |
cards.forEach(card => { | |
const items = card.stack.items; | |
items.splice(items.indexOf(card), 1); | |
this.items.push(card); | |
card.trigger(); | |
}); | |
} | |
cardPos(card) { | |
const index = this.items.indexOf(card); | |
const offset = this.items.slice(0, index).reduce((acc, { revealed }) => acc + (revealed ? Card.peek : Card.padding), 0); | |
return { x: this.x, y: this.y + offset }; | |
} | |
} | |
const sleep = seconds => new Promise(resolve => setTimeout(resolve, 1000*seconds)); | |
class Solitare { | |
constructor() { | |
this.subscriptions = []; | |
[ this.width, this.height ] = Card.pos(7, 4); | |
this.drawStack = new DrawStack(this, ...Card.pos(0, 0)); | |
this.discardStack = new DiscardStack(this, ...Card.pos(1, 0)); | |
this.goalStacks = new Array(4).fill().map((_, i) => new GoalStack(this, ...Card.pos(3+i, 0))); | |
this.cascadingStacks = new Array(7).fill().map((_, i) => new CascadingStack(this, ...Card.pos(i, 1))); | |
this.items = [ | |
...this.cascadingStacks, | |
this.drawStack, | |
this.discardStack, | |
...this.goalStacks | |
]; | |
this.items.forEach((stack, index) => { stack.id = `stack_${index}`; }); | |
this.deal(); | |
} | |
async deal() { | |
for (let i=0; i<7; i++) { | |
let card; | |
for (let j=i; j<7; j++) { | |
await sleep(0.05); | |
card = this.drawStack.items.pop(); | |
this.cascadingStacks[j].items.push(card); | |
card.trigger(); | |
} | |
await sleep(0.05); | |
card = this.cascadingStacks[i].items.slice(-1)[0]; | |
card.revealed = true; | |
card.trigger(); | |
} | |
} | |
async checkWin() { | |
if (!this.goalStacks.every(stack => stack.items.length === 13)) return; | |
for (let index=0,stack; stack=this.goalStacks[index]; index++){ | |
let x = (this.width - Card.width) * Math.random(); | |
let y = (this.height - Card.height) * Math.random(); | |
stack.items.forEach(({ id, image, width, height }) => { | |
this.trigger(id, { id, image, width, height, x, y }); | |
}); | |
await sleep(0.3); | |
stack.items.forEach(({ id, image, width, height }, index, items) => { | |
this.trigger(id, { | |
id, image, width, height, | |
x: x + Card.height * 4 * Math.cos(index / items.length * Math.PI*2), | |
y: y + Card.height * 4 * Math.sin(index / items.length * Math.PI*2) | |
}); | |
}); | |
await sleep(0.5); | |
} | |
} | |
subscribe(fn) { | |
this.subscriptions.push(fn); | |
fn(null, { | |
width: this.width, height: this.height, | |
actions: { | |
Deal: async function(){ | |
this.items.forEach(stack => | |
this.drawStack.items.push(...stack.items.splice(0)) | |
); | |
this.drawStack.items.sort(() => Math.random() - 0.5); | |
this.drawStack.items.forEach(card => { | |
card.revealed = false; | |
card.trigger(); | |
}); | |
await sleep(0.3); | |
this.deal(); | |
}.bind(this) | |
} | |
}); | |
this.items.forEach(stack => { | |
stack.trigger(); | |
}); | |
this.items.forEach(stack => { | |
stack.items.forEach(item => { | |
item.trigger(); | |
}); | |
}); | |
return function unsubscribe(){ | |
const index = this.subscriptions.indexOf(fn); | |
if (index === -1) return false; | |
this.subscriptions.splice(index, 1); | |
return true; | |
}.bind(this); | |
} | |
trigger(itemId, item) { | |
this.subscriptions.forEach(fn => fn(itemId, item)); | |
} | |
} | |
export default function solitare(fn){ | |
const solitare = new Solitare(); | |
return solitare.subscribe(fn); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment