Watermelon Chess SVG Using Perl
Watermelon chess is a simple strategy game where you surround your opponent to remove them from the game.
We are creating game boards for the CNC router. The first step is to create a SVG file. From the SVG file, we then create the g-code. This article contains rules about watermelon chess, and the Perl used to create the SVG.
Objective
The objective of watermelon chess is to surround your opponent, capturing pieces. Once you get them down to 2 pieces, you win.
Setup
6 pieces on one side and 6 on the other using different colors.
Movement
Move 1 segment at a time on your turn.
Capture
If you surround an opponent’s piece or group of pieces, those pieces are captured.
Watermelon Chess SVG Code in Perl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
#!/usr/bin/perl # Water Melon Chess Board done in SVG use strict; use warnings; use SVG; # https://metacpan.org/pod/SVG # with margins at .25, SCALE of 142*9.5 (last row of dots) fits on an A4 use constant SCALE => '66'; # dots per inch scale, adjust to fit on your board use constant DOTSIZE => '7'; # should be an odd number use constant LINEWIDTH => '3'; # should be an odd number use constant FILL => 'black'; # can be 'rgb(0,0,0)' too use constant STROKE => 'black'; # can be 'rgb(0,0,0)' too my $title = "Watermelon Chess"; # create an SVG object, canvas which we use for the rest of the draws my $svg = SVG->new( width => 11 * SCALE, height => 11 * SCALE, ); #---------------------------------------------- # Define the dots, lines, squares, circles etc # Order isn't important, all is eventually drawn # SVG has max of 2-4k objects before browser gets sluggish # keys are sorted alpha for debug reasons #---------------------------------------------- # everything is based off of the segment length # of the circle radius, so "legs" of various length # used throughout rest of the math my $leg1 = (8/6); # 1.1428571429 my $leg2 = ($leg1) * 2; # 2.2857142857 my $leg3 = ($leg1) * 3; # 3.4285714286 my $leg4 = ($leg1) * 4; # 4.5714285714 my $ctr = 5.5; # Circles / Dots my %circles = ( # x, y, size, fill ca => [$ctr,$ctr,$leg3,0], # the big Juan #cb => [$ctr,$ctr-$leg3,$leg1,0], # N but can't do full circles, do arcs instead #cc => [$ctr+$leg3,$ctr,$leg1,0], # E, do arcs instead #cd => [$ctr,$ctr+$leg3,$leg1,0], # S, do arcs instead #ce => [$ctr-$leg3,$ctr,$leg1,0], # W, do arcs instead cf => [$ctr,$ctr,$leg1,0], # the little Juan cg => [$ctr-$leg3,$ctr,.1,1], # y-axis ch => [$ctr-$leg2+$leg1*.15,$ctr,.1,1], # y-axis ci => [$ctr-$leg1,$ctr,.1,1], # y-axis cj => [$ctr+$leg1,$ctr,.1,1], # y-axis ck => [$ctr+$leg2-$leg1*.15,$ctr,.1,1], # y-axis cl => [$ctr+$leg3,$ctr,.1,1], # y-axis cm => [$ctr,$ctr,.1,1], # center cn => [$ctr,$ctr-$leg3,.1,1], # x-axis co => [$ctr,$ctr-$leg2+$leg1*.15,.1,1], # x-axis cp => [$ctr,$ctr-$leg1,.1,1], # x-axis cq => [$ctr,$ctr+$leg1,.1,1], # x-axis cr => [$ctr,$ctr+$leg2-$leg1*.15,.1,1], # x-axis cs => [$ctr,$ctr+$leg3,.1,1], # x-axis ct => [$ctr-$leg3+$leg1*.167,$ctr+$leg1-$leg1*.017,.1,1], # arc dots, W cu => [$ctr-$leg3+$leg1*.167,$ctr-$leg1+$leg1*.017,.1,1], # arc dots, W cv => [$ctr+$leg3-$leg1*.167,$ctr+$leg1-$leg1*.017,.1,1], # arc dots, E cw => [$ctr+$leg3-$leg1*.167,$ctr-$leg1+$leg1*.017,.1,1], # arc dots, E cx => [$ctr-$leg1+$leg1*.017,$ctr-$leg3+$leg1*.167,.1,1], # arc dots, N cy => [$ctr+$leg1-$leg1*.017,$ctr-$leg3+$leg1*.167,.1,1], # arc dots, N cz => [$ctr-$leg1+$leg1*.017,$ctr+$leg3-$leg1*.167,.1,1], # arc dots, S c0 => [$ctr+$leg1-$leg1*.017,$ctr+$leg3-$leg1*.167,.1,1], # arc dots, S ); # Lines are xy start and xy stop coordinates, in inches my %lines = ( # x y x y lb => [$ctr,$ctr-$leg3,$ctr,$ctr+$leg3], # N to S lc => [$ctr-$leg3,$ctr,$ctr+$leg3,$ctr], # E to W ); # Squares are xy start then l,w in inches my %squares = ( sa => [0,0,11,11,0], # border/edge of board ); # so we need some custom paths, not sure how to do arcs with this module my %arcs = ( # x,y (start), x,y (stop) aa => [$circles{'ct'}[0],$circles{'ct'}[1],$circles{'cu'}[0],$circles{'cu'}[1],0,0], # West Arc ab => [$circles{'cx'}[0],$circles{'cx'}[1],$circles{'cy'}[0],$circles{'cy'}[1],0,0], # North Arc ac => [$circles{'cv'}[0],$circles{'cv'}[1],$circles{'cw'}[0],$circles{'cw'}[1],0,1], # East Arc ad => [$circles{'cz'}[0],$circles{'cz'}[1],$circles{'c0'}[0],$circles{'c0'}[1],0,1], # South Arc ); #---------------------------------------------- # Logic, no reason for sort but to help me see data when debugging #---------------------------------------------- foreach my $arc (sort keys %arcs) { arcs($arc, $arcs{$arc}[0],$arcs{$arc}[1],$arcs{$arc}[2],$arcs{$arc}[3],$arcs{$arc}[4],$arcs{$arc}[5]); } # make our circles/dots foreach my $circle (sort keys %circles) { circles($circles{$circle}[0],$circles{$circle}[1],$circles{$circle}[2],$circles{$circle}[3]); } # add some lines foreach my $cor (sort keys %lines) { lines($lines{$cor}[0],$lines{$cor}[1],$lines{$cor}[2],$lines{$cor}[3]); } # make our squares foreach my $square (sort keys %squares) { squares($squares{$square}[0],$squares{$square}[1],$squares{$square}[2],$squares{$square}[3],$squares{$square}[4]); } # for SVG< keep - but will probably delete for boards title($title); #---------------------------------------------- # Text, at SCALE of 142, 6.5 letters per inch, Serif Font # Text, at SCALE of 96, 5 letters per inche, Serif Font # Text, at SCALE of 67, 4.5 bleh bleh # Take half of estimated lenght of title, subtract it from center # that should start half before center, and then half after center # adjust the /5 down to move left, up to move right #---------------------------------------------- sub title { my $ltitle = length($title); my $xtitle = 5.5 * SCALE - ($ltitle /4.5 * SCALE)/2; $svg->text( id => 'l1', x => $xtitle, y => SCALE * .95, style => { 'font' => 'Serif', 'font-size' => SCALE / 2, 'fill' => FILL, }, )->cdata($title); } #---------------------------------------------- # customs - accepts custom data paths #---------------------------------------------- sub arcs { # M = Absolute move to X,Y # A = Absolute Arc Radius X and Y # Rotation # Large ARC Flag # Sweep Flag # End X,Y of Arc # seems to be ignoring the A rx, ry my ($id,$sx,$sy,$ex,$ey,$a1,$a2) = @_; $sx = $sx * SCALE; $sy = $sy * SCALE; $ex = $ex * SCALE; $ey = $ey * SCALE; my $sz = ($leg1-$leg1 * .167) * SCALE; my $string = "M $sx,$sy A $sz,$sz 90 $a1 $a2 $ex,$ey"; my $tag = $svg->path( d => $string, id => 'arc_'.$id, style => { 'fill' => FILL, 'stroke' => STROKE, 'stroke-width' => 3, 'stroke-opacity' => 1, 'fill-opacity' => 0, }, ); } #---------------------------------------------- # circles - x,y start, radius and fill opacity #---------------------------------------------- sub circles { my $x = shift; my $y = shift; my $r = shift; my $fop = shift; $svg->circle( cx => $x * SCALE, cy => $y * SCALE, r => $r * SCALE, style => { 'fill' => FILL, 'stroke' => STROKE, 'stroke-width' => 3, 'stroke-opacity' => 1, 'fill-opacity' => $fop, }, ); } #---------------------------------------------- # lines sub # really a 2 point polygon, and lines #---------------------------------------------- sub lines { # 4 arguments, xstart, ystart, xstop, ystop my $xstart = SCALE * shift; my $ystart = SCALE * shift; my $xstop = SCALE * shift; my $ystop = SCALE * shift; my $path = $svg->get_path( x => [$xstart,$xstop], y => [$ystart,$ystop], -type => 'polygon'); $svg->polygon( %$path, style => { 'fill' => FILL, 'stroke' => STROKE, 'stroke-width' => LINEWIDTH, 'stroke-opacity' => 1, 'fill-opacity' => 1, }, ); } #---------------------------------------------- # square sub #---------------------------------------------- sub squares { # accepts 6 values: # x y coord, w h specs, fill opacity and line weight my $x = shift; my $y = shift; my $w = shift; my $h = shift; my $fop = shift; $svg->rectangle( x => $x * SCALE, y => $y * SCALE, width => $w * SCALE, height => $h * SCALE, style => { 'fill' => FILL, 'stroke' => STROKE, 'stroke-width' => LINEWIDTH, 'stroke-opacity' => 1, 'fill-opacity' => $fop, # must be 0, for lines, or 1 for solid squares } ); } # now render the SVG object, implicitly use svg namespace print $svg->xmlify; |
Ótimo.