Skip to content

Instantly share code, notes, and snippets.

@DouglasMeyer
Last active January 13, 2019 20:55
Show Gist options
  • Save DouglasMeyer/0691ecc71244c414a4ea50d90aa30b19 to your computer and use it in GitHub Desktop.
Save DouglasMeyer/0691ecc71244c414a4ea50d90aa30b19 to your computer and use it in GitHub Desktop.
TableGames Solitare
Display the source blob
Display the rendered blob
Raw
<?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>
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