Basic player moves
This commit is contained in:
137
public/img/free.svg
Normal file
137
public/img/free.svg
Normal file
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 512 512"
|
||||
style="enable-background:new 0 0 512 512;"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="free.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
||||
id="metadata67"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs65" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="640"
|
||||
inkscape:window-height="480"
|
||||
id="namedview63"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.4609375"
|
||||
inkscape:cx="256"
|
||||
inkscape:cy="256"
|
||||
inkscape:window-x="70"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<g
|
||||
id="g6">
|
||||
<g
|
||||
id="g4">
|
||||
<polygon
|
||||
points="389.565,205.913 389.565,172.522 300.522,172.522 300.522,339.478 389.565,339.478 389.565,306.087 333.913,306.087 333.913,272.696 389.565,272.696 389.565,239.304 333.913,239.304 333.913,205.913 "
|
||||
id="polygon2" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g12">
|
||||
<g
|
||||
id="g10">
|
||||
<polygon
|
||||
points="100.174,205.913 100.174,172.522 0,172.522 0,339.478 33.391,339.478 33.391,272.696 100.174,272.696 100.174,239.304 33.391,239.304 33.391,205.913 "
|
||||
id="polygon8" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g18">
|
||||
<g
|
||||
id="g16">
|
||||
<polygon
|
||||
points="512,205.913 512,172.522 422.957,172.522 422.957,339.478 512,339.478 512,306.087 456.348,306.087 456.348,272.696 512,272.696 512,239.304 456.348,239.304 456.348,205.913 "
|
||||
id="polygon14" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g24">
|
||||
<g
|
||||
id="g22">
|
||||
<path
|
||||
d="M133.565,172.522v166.957h33.391v-66.783h33.391v33.391h33.391v-33.391H256V172.522H133.565z M222.609,239.304h-55.652 v-33.391h55.652V239.304z"
|
||||
id="path20" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g30">
|
||||
<g
|
||||
id="g28">
|
||||
<rect
|
||||
x="233.739"
|
||||
y="306.087"
|
||||
width="33.391"
|
||||
height="33.391"
|
||||
id="rect26" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g32">
|
||||
</g>
|
||||
<g
|
||||
id="g34">
|
||||
</g>
|
||||
<g
|
||||
id="g36">
|
||||
</g>
|
||||
<g
|
||||
id="g38">
|
||||
</g>
|
||||
<g
|
||||
id="g40">
|
||||
</g>
|
||||
<g
|
||||
id="g42">
|
||||
</g>
|
||||
<g
|
||||
id="g44">
|
||||
</g>
|
||||
<g
|
||||
id="g46">
|
||||
</g>
|
||||
<g
|
||||
id="g48">
|
||||
</g>
|
||||
<g
|
||||
id="g50">
|
||||
</g>
|
||||
<g
|
||||
id="g52">
|
||||
</g>
|
||||
<g
|
||||
id="g54">
|
||||
</g>
|
||||
<g
|
||||
id="g56">
|
||||
</g>
|
||||
<g
|
||||
id="g58">
|
||||
</g>
|
||||
<g
|
||||
id="g60">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
61
public/img/o.svg
Normal file
61
public/img/o.svg
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 210 297"
|
||||
version="1.1"
|
||||
id="svg110"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="o.svg">
|
||||
<defs
|
||||
id="defs104" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="400"
|
||||
inkscape:cy="560"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2490"
|
||||
inkscape:window-height="1381"
|
||||
inkscape:window-x="70"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata107">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 181.17845,116.44189 C 165.55786,85.058517 111.70531,53.839667 81.885448,85.746937 c -36.77086,10.16663 -53.106557,55.158383 -43.88166,90.303623 12.38733,47.19045 62.788892,62.72661 104.711722,45.38287 41.5275,-17.18846 58.46281,-64.80093 38.46294,-104.99154 z m -49.8419,66.01325 c -20.96813,12.59162 -47.465922,7.18634 -56.224322,-16.63316 -7.46164,-20.28407 -0.2837,-34.68327 10.90809,-48.28745 1.56283,0.42134 3.24233,0.69328 5.12545,0.65803 21.798722,-0.40791 36.926292,-10.31754 51.241052,12.38263 11.54783,18.33884 7.63035,40.66148 -11.05027,51.88062 z"
|
||||
id="path8"
|
||||
style="stroke-width:4.44145107" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
106
public/img/thinking.svg
Normal file
106
public/img/thinking.svg
Normal file
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512.002 512.002" style="enable-background:new 0 0 512.002 512.002;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M424.933,63.7C376.142,20.757,313.397-1.815,248.248,0.114c-65.44,1.948-126.989,28.529-173.306,74.847
|
||||
c-39.775,39.775-64.859,90.171-72.539,145.741C-5.026,274.456,5.03,330.214,30.72,377.704c1.357,2.509,3.938,3.933,6.604,3.933
|
||||
c1.205,0,2.427-0.291,3.562-0.905c3.644-1.971,4.999-6.522,3.028-10.165c-24.182-44.703-33.648-97.197-26.652-147.812
|
||||
c7.229-52.304,30.842-99.743,68.287-137.188c43.603-43.603,101.543-68.626,163.146-70.459
|
||||
c61.338-1.83,120.401,19.43,166.328,59.852c3.109,2.737,7.848,2.436,10.585-0.675C428.345,71.176,428.043,66.437,424.933,63.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M448.282,87.05c-2.736-3.109-7.476-3.411-10.585-0.675c-3.109,2.737-3.412,7.476-0.675,10.585
|
||||
c40.421,45.926,61.677,104.995,59.852,166.328c-1.833,61.603-26.856,119.543-70.459,163.146
|
||||
c-29.439,29.438-66.077,50.824-105.953,61.844c-36.855,10.185-75.934,11.444-113.393,3.713c0.173-1.15,0.265-2.326,0.265-3.524
|
||||
c0-4.369-1.196-8.463-3.279-11.973c6.77-4.137,11.296-11.598,11.296-20.095c0-4.369-1.196-8.463-3.279-11.973
|
||||
c6.769-4.138,11.295-11.598,11.295-20.095c0-3.009-0.567-5.887-1.601-8.534h66.255c12.977,0,23.534-10.558,23.534-23.534
|
||||
c0-12.976-10.558-23.534-23.534-23.534H143.714c-9.126,0-16.551-7.425-16.551-16.551v-48.102
|
||||
c0-12.977-10.558-23.534-23.534-23.534c-12.976,0-23.534,10.558-23.534,23.534v39.246c0,9.184-3.16,18.192-8.897,25.364
|
||||
l-7.473,9.341c-10.123,12.653-15.698,28.546-15.698,44.751v33.621c0,30.659,24.943,55.603,55.602,55.603H183.8
|
||||
c6.152,0,11.757-2.375,15.955-6.253c18.493,4.15,37.384,6.238,56.276,6.238c23.071,0,46.135-3.089,68.427-9.25
|
||||
c42.371-11.709,81.295-34.426,112.564-65.695c46.318-46.317,72.899-107.866,74.847-173.306
|
||||
C513.806,198.587,491.225,135.84,448.282,87.05z M191.816,464.931h-8.017c-4.142,0-7.5,3.358-7.5,7.5c0,4.142,3.358,7.5,7.5,7.5
|
||||
c4.706,0,8.534,3.829,8.534,8.534c0,4.705-3.828,8.535-8.534,8.535h-80.171c-22.388,0-40.602-18.214-40.602-40.603v-33.621
|
||||
c0-12.812,4.408-25.377,12.411-35.381l7.473-9.341c7.857-9.822,12.185-22.157,12.185-34.734v-39.246
|
||||
c0-4.706,3.829-8.534,8.534-8.534c4.705,0,8.534,3.829,8.534,8.534v48.102c0,17.397,14.154,31.551,31.551,31.551h144.307
|
||||
c4.706,0,8.534,3.829,8.534,8.534c0,4.705-3.829,8.534-8.534,8.534h-88.188c-4.142,0-7.5,3.358-7.5,7.5c0,4.142,3.358,7.5,7.5,7.5
|
||||
c4.706,0,8.534,3.829,8.534,8.534c0,4.705-3.828,8.534-8.534,8.534h-8.017c-4.142,0-7.5,3.358-7.5,7.5c0,4.142,3.358,7.5,7.5,7.5
|
||||
c4.706,0,8.534,3.828,8.534,8.534S196.521,464.931,191.816,464.931z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M179.136,172.62c-4.12-0.397-7.793,2.606-8.199,6.729l-1.179,11.968c-0.329,3.334-1.936,6.34-4.525,8.466
|
||||
c-2.59,2.125-5.854,3.116-9.187,2.786c-6.882-0.678-11.93-6.83-11.252-13.712l1.572-15.957
|
||||
c0.678-6.883,6.839-11.935,13.712-11.252c4.136,0.408,7.793-2.606,8.199-6.729c0.406-4.123-2.606-7.793-6.729-8.199
|
||||
c-15.115-1.479-28.621,9.596-30.11,24.709l-1.572,15.957c-1.489,15.113,9.596,28.621,24.709,30.11
|
||||
c0.92,0.091,1.838,0.136,2.751,0.136c6.348,0,12.45-2.174,17.422-6.254c5.687-4.667,9.216-11.27,9.938-18.591l1.179-11.968
|
||||
C186.271,176.697,183.259,173.026,179.136,172.62z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M346.683,189.127c-4.125-0.403-7.793,2.606-8.199,6.729l-1.179,11.968c-0.678,6.882-6.827,11.927-13.712,11.252
|
||||
c-6.882-0.678-11.93-6.829-11.252-13.712l1.572-15.957c0.329-3.334,1.936-6.341,4.526-8.466c2.589-2.125,5.851-3.12,9.186-2.786
|
||||
c4.122,0.403,7.793-2.606,8.199-6.729c0.406-4.122-2.606-7.793-6.729-8.199c-7.323-0.722-14.485,1.452-20.172,6.119
|
||||
c-5.687,4.667-9.217,11.269-9.938,18.591l-1.572,15.957c-0.721,7.321,1.452,14.485,6.119,20.172s11.269,9.216,18.591,9.937
|
||||
c0.92,0.091,1.838,0.136,2.751,0.136c6.348,0,12.449-2.174,17.421-6.254c5.687-4.667,9.217-11.269,9.938-18.591l1.179-11.968
|
||||
C353.818,193.203,350.806,189.533,346.683,189.127z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M299.418,321.429c-2.375-1.199-58.913-29.378-123.773-30.862c-4.126-0.08-7.575,3.185-7.669,7.327
|
||||
c-0.096,4.142,3.184,7.576,7.326,7.67c61.373,1.404,116.807,28.979,117.356,29.256c1.084,0.547,2.237,0.806,3.374,0.806
|
||||
c2.741,0,5.382-1.508,6.701-4.122C304.6,327.807,303.115,323.296,299.418,321.429z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M196.501,121.842c-1.79-1.432-44.428-34.768-96.227-8.869c-3.705,1.852-5.207,6.357-3.354,10.062
|
||||
c1.853,3.705,6.356,5.207,10.062,3.354c43.006-21.5,78.592,5.937,80.16,7.175c1.381,1.1,3.03,1.635,4.669,1.635
|
||||
c2.2,0,4.38-0.964,5.861-2.815C200.26,129.15,199.735,124.43,196.501,121.842z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M391.58,126.228c-0.812-4.062-4.765-6.693-8.825-5.884l-80.17,16.034c-4.062,0.812-6.696,4.764-5.884,8.825
|
||||
c0.713,3.565,3.845,6.031,7.347,6.031c0.487,0,0.982-0.048,1.479-0.147l80.17-16.034
|
||||
C389.758,134.241,392.392,130.29,391.58,126.228z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
61
public/img/x.svg
Normal file
61
public/img/x.svg
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 210 297"
|
||||
version="1.1"
|
||||
id="svg68"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="x.svg">
|
||||
<defs
|
||||
id="defs62" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="400"
|
||||
inkscape:cy="560"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2490"
|
||||
inkscape:window-height="1381"
|
||||
inkscape:window-x="70"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata65">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 171.56306,97.130972 c 2.1252,-0.55519 4.19212,-1.32468 5.81517,-2.62965 6.55497,-5.29352 11.62139,-8.49014 14.28014,-16.10493 4.56876,-13.07185 -10.24941,-23.692981 -24.74926,-21.00638 -16.57571,3.07106 -23.18448,15.47697 -32.52374,26.52815 -8.25873,9.7688 -16.09151,19.784828 -24.05431,29.724778 C 88.339193,100.23237 65.49096,87.289832 40.741703,78.521952 24.219791,72.665332 15.086764,94.649752 29.012708,102.1351 c 21.108616,11.34042 41.244276,23.84529 61.075065,36.70787 -20.099802,25.67956 -43.889574,55.51091 -48.843899,85.98921 -2.187984,13.4448 21.122054,25.51588 28.735132,10.28241 12.531563,-25.08582 28.179177,-48.12437 45.795094,-70.89267 1.33159,-1.71632 2.8381,-3.33743 4.19213,-5.03851 15.93009,12.45539 33.1918,27.64313 53.26022,29.13493 7.58172,0.56382 16.43226,-6.40461 15.39208,-13.06048 -3.01296,-19.18736 -27.00001,-31.52093 -46.69181,-42.49991 3.34473,-3.91203 6.47425,-7.95337 9.8459,-11.84641 3.78861,-4.40307 13.40584,-16.18865 19.79044,-23.780568 z"
|
||||
id="path6"
|
||||
style="stroke-width:4.13064194" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -18,7 +18,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="debug" style="display: flex; justify-content: space-around;">
|
||||
<div id="debug" class="debug-bar">
|
||||
<span id="fps"></span>
|
||||
<span id="fps-interval"></span>
|
||||
<span id="then"></span>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
.mttt-cell:hover{
|
||||
background: lightblue;
|
||||
.debug-bar{
|
||||
position: relative;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
z-index: 100;
|
||||
}
|
||||
136
src/game.nim
136
src/game.nim
@@ -1,4 +1,4 @@
|
||||
import dom, strformat, times, jsconsole
|
||||
import dom, strformat, times, jsconsole, options, pure.strutils
|
||||
import gamelight/[graphics, vec]
|
||||
import libmttt
|
||||
|
||||
@@ -17,6 +17,12 @@ type
|
||||
Scene {.pure.} = enum
|
||||
MainMenu, Game
|
||||
|
||||
BoardSize = object ## Infos on size/position of a game board
|
||||
x: int ## X position of the top left corner
|
||||
y: int ## Y position of the top left corner
|
||||
size: int ## Pixel size of the game board. (The board is assumed to be quadratic)
|
||||
cellSize: int ## Pixel size of each cell in the board
|
||||
|
||||
const
|
||||
gameBgColor = "#eaeaea"
|
||||
metaBoardColor = "#484d4d"
|
||||
@@ -29,45 +35,58 @@ var
|
||||
# TODO this should be dynamic
|
||||
sidebarWidth = 150 ## Size of the left sidebar
|
||||
|
||||
proc cellClick(event: Event): void =
|
||||
## TODO Process cell clicks from here
|
||||
let
|
||||
cX = event.target.getAttribute("x")
|
||||
cY = event.target.getAttribute("y")
|
||||
mX = event.target.getAttribute("metaX")
|
||||
mY = event.target.getAttribute("metaY")
|
||||
console.debug(fmt"Click: cell ({cX}, {cY}) in mini board ({mX}, {mY})")
|
||||
proc getGameArea(game: Game): BoardSize =
|
||||
## Get size and position of the game board on the canvas
|
||||
let height = game.renderer.getHeight - 2 * padding
|
||||
let width = game.renderer.getWidth - sidebarWidth - 3 * padding
|
||||
result.x = 2 * padding + sidebarWidth
|
||||
result.y = padding
|
||||
result.size = min(height, width)
|
||||
result.cellSize = (result.size / 3).toInt
|
||||
|
||||
proc createMiniCells(renderer: Renderer2D, board: Coordinate, start: Point, size: float): seq[Element] =
|
||||
proc getCellInfo(e: Node): tuple[cell: Coordinate, board: Coordinate] =
|
||||
## Parse the game imformation from the HTML attributes of an element
|
||||
var val: string
|
||||
val = $e.getAttribute("x")
|
||||
result.cell.x = val.parseInt
|
||||
val = $e.getAttribute("y")
|
||||
result.cell.y = val.parseInt
|
||||
val = $e.getAttribute("metaX")
|
||||
result.board.x = val.parseInt
|
||||
val = $e.getAttribute("metaY")
|
||||
result.board.y = val.parseInt
|
||||
|
||||
proc cellClick(game: Game, event: Event): void =
|
||||
## TODO Process cell clicks from here
|
||||
let (cell, board) = event.target.getCellInfo()
|
||||
console.debug(fmt"Click: cell ({cell.x}, {cell.y}) in mini board ({board.x}, {board.y})")
|
||||
if game.state.currentBoard.isNone:
|
||||
discard game.state.makeMove(cell,board)
|
||||
elif board == game.state.currentBoard.get:
|
||||
discard game.state.makeMove(cell)
|
||||
|
||||
proc createMiniCells(game: Game, board: Coordinate, start: Point, size: float): seq[Element] =
|
||||
## Create the interactive cells in a miniboard
|
||||
for x in 0 .. 2:
|
||||
for y in 0 .. 2:
|
||||
let pos = (start.x + x * size, start.y + y * size).toPoint
|
||||
let cell: Element = renderer.createDivElement(pos, size, size)
|
||||
let pos = ((start.x + x * size).toInt, (start.y + y * size).toInt).toPoint
|
||||
let cell: Element = game.renderer.createDivElement(pos, size, size)
|
||||
cell.setAttribute("info", fmt"({x}, {y}) at {start}")
|
||||
cell.setAttribute("X", $x)
|
||||
cell.setAttribute("Y", $y)
|
||||
cell.setAttribute("metaX", $board.x)
|
||||
cell.setAttribute("metaY", $board.y)
|
||||
cell.onclick = cellClick
|
||||
cell.classList.add("mttt-cell")
|
||||
result.add cell
|
||||
cell.addEventListener("click", proc(ev: Event) = cellClick(game, ev))
|
||||
result.add cell
|
||||
|
||||
proc createCellElements(renderer: Renderer2D): seq[Element] =
|
||||
proc createCellElements(game: Game): seq[Element] =
|
||||
## Create the cell elements for the whole game board
|
||||
# TODO: put those somewhere shared
|
||||
let
|
||||
gAreaX = 2 * padding + sidebarWidth
|
||||
gAreaY = padding
|
||||
gAreaH = renderer.getHeight - 2 * padding
|
||||
gAreaW = renderer.getWidth - sidebarWidth - 3 * padding
|
||||
gSize = min(gAreaH, gAreaW)
|
||||
bSize = (gSize / 3)
|
||||
|
||||
let area = game.getGameArea()
|
||||
for x in 0 .. 2:
|
||||
for y in 0 .. 2:
|
||||
let pos = (gAreaX + x * bSize, gAreaY + y * bSize)
|
||||
result.add renderer.createMiniCells((x, y), pos, bSize / 3)
|
||||
let pos = (area.x + x * area.cellSize, area.y + y * area.cellSize)
|
||||
result.add game.createMiniCells((x, y), pos, area.cellSize / 3)
|
||||
|
||||
proc switchScene(game: Game, scene: Scene) =
|
||||
case scene:
|
||||
@@ -80,8 +99,7 @@ proc switchScene(game: Game, scene: Scene) =
|
||||
let timePos = (padding.toFloat, padding.toFloat + 35.0).toPoint
|
||||
game.timeElement = game.renderer.createTextElement("0", timePos, "#000000", 20, font)
|
||||
|
||||
# TODO Save these somewhere???
|
||||
let elements = game.renderer.createCellElements()
|
||||
discard game.createCellElements()
|
||||
|
||||
proc newGame*(canvasId: string, debug: bool = false): Game =
|
||||
debugMode = debug
|
||||
@@ -115,14 +133,8 @@ proc drawPos(renderer: Renderer2D, x, y: float): void =
|
||||
proc drawPos(renderer: Renderer2D, point: Point): void =
|
||||
renderer.drawPos(point.x.toFloat, point.y.toFloat)
|
||||
|
||||
proc drawBoard(game: Game, zero: Point, size: int, color = "#000000", pad = 10): void =
|
||||
## Draw a Tic Tac Toe board with the given sizes
|
||||
if (debugMode):
|
||||
game.renderer.drawPos(zero) # Top left corner
|
||||
game.renderer.drawPos((zero.x + size, zero.y).toPoint) # Top right corner
|
||||
game.renderer.drawPos((zero.x, zero.y + size).toPoint) # Bottom left corner
|
||||
game.renderer.drawPos((zero.x + size, zero.y + size).toPoint) # Bottom right corner
|
||||
|
||||
proc drawBoardLines(game: Game, zero: Point, size: int, color = "#000000", pad = 10): void =
|
||||
## Draws the lines for a tic tac toe board on the canvas
|
||||
for i in 1 .. 2:
|
||||
let offX = ((size / 3) * i.toFloat) + zero.x.toFloat
|
||||
let offY = ((size / 3) * i.toFloat) + zero.y.toFloat
|
||||
@@ -143,28 +155,60 @@ proc drawBoard(game: Game, zero: Point, size: int, color = "#000000", pad = 10):
|
||||
game.renderer.closePath()
|
||||
game.renderer.strokePath(color, 3)
|
||||
|
||||
proc drawMark(renderer: Renderer2D, pos: Point, size: int, mark: Mark) =
|
||||
## Draw a single mark on the canvas
|
||||
case mark:
|
||||
of Mark.Free:
|
||||
if (debugMode):
|
||||
renderer.drawImage("img/free.svg", pos, size, size, ImageAlignment.TopLeft)
|
||||
of Mark.Player1:
|
||||
renderer.drawImage("img/x.svg", pos, size, size, ImageAlignment.TopLeft)
|
||||
of Mark.Player2:
|
||||
renderer.drawImage("img/o.svg", pos, size, size, ImageAlignment.TopLeft)
|
||||
else:
|
||||
console.error(fmt"Invalid mark '{mark}'");
|
||||
|
||||
proc drawPlayerMarks(game: Game, zero: Point, size: int, coord: Coordinate): void =
|
||||
## Draw the player marks for all cells in a board
|
||||
let cellSize = (size / 3).toInt
|
||||
for x in 0 .. 2:
|
||||
for y in 0 .. 2:
|
||||
let pos = ((zero.x + x * cellSize), (zero.y + y * cellSize)).toPoint ## Top left point for each cell in the board
|
||||
let mark = game.state.board[coord.x][coord.y][x][y]
|
||||
game.renderer.drawMark(pos, cellSize, mark)
|
||||
|
||||
proc drawBoard(game: Game, zero: Point, size: int, coord: Coordinate, color = "#000000", pad = 10): void =
|
||||
## Draw a Tic Tac Toe board with the given sizes, if the game is still open.
|
||||
## If not, draw a big mark for the winner or something to show it is drawn
|
||||
if (debugMode):
|
||||
game.renderer.drawPos(zero) # Top left corner
|
||||
game.renderer.drawPos((zero.x + size, zero.y).toPoint) # Top right corner
|
||||
game.renderer.drawPos((zero.x, zero.y + size).toPoint) # Bottom left corner
|
||||
game.renderer.drawPos((zero.x + size, zero.y + size).toPoint) # Bottom right corner
|
||||
|
||||
let status = game.state.board[coord.x][coord.y].checkBoard
|
||||
if status == Mark.Free:
|
||||
game.drawBoardLines(zero, size, color, pad)
|
||||
game.drawPlayerMarks(zero, size, coord)
|
||||
else:
|
||||
game.renderer.drawMark(zero, size, status)
|
||||
|
||||
proc drawGame(game: Game) =
|
||||
## Redraw the UI elements
|
||||
game.timeElement.innerHTML = fmt"{game.totalTime.inMinutes}m {game.totalTime.inSeconds mod 60}s"
|
||||
|
||||
let
|
||||
gAreaX = 2 * padding + sidebarWidth
|
||||
gAreay = padding
|
||||
gAreaH = game.renderer.getHeight - 2 * padding
|
||||
gAreaW = game.renderer.getWidth - sidebarWidth - 3 * padding
|
||||
gSize = min(gAreaH, gAreaW)
|
||||
bSize = (gSize / 3).toInt
|
||||
let area = game.getGameArea()
|
||||
|
||||
# Draw a box araound the game board
|
||||
game.renderer.strokeRect(gAreaX, gAreaY, gSize, gSize, "#0000004d")
|
||||
game.renderer.strokeRect(area.x, area.y, area.size, area.size, "#0000004d")
|
||||
|
||||
# Draw the meta board
|
||||
game.drawBoard((gAreaX, gAreaY).toPoint, gSize, metaBoardColor, 5)
|
||||
game.drawBoardLines((area.x, area.y).toPoint, area.size, metaBoardColor, 5)
|
||||
|
||||
# Draw the small boards
|
||||
for x in 0 .. 2:
|
||||
for y in 0 .. 2:
|
||||
game.drawBoard((gAreaX + x*bSize, gAreaY + y*bSize).toPoint, bSize, miniBoardColor, 15)
|
||||
game.drawBoard((area.x + x*area.cellSize, area.y + y*area.cellSize).toPoint, area.cellSize, (x, y), miniBoardColor, 15)
|
||||
|
||||
proc draw(game: Game) =
|
||||
## Draw the current screen on the canvas
|
||||
|
||||
Reference in New Issue
Block a user