Annuvin Game Board from Perl SVG
Annuvin is a game that solves the issue of unbalanced play. As you progress through the game, the losing player actually gets stronger.
Objective of Annuvin
Eliminate all opposing pieces by replacement.
Annuvin Setup
Each player has 7 tokens, placed opposite each other, as per the diagram. It is played on a 4 sized hex board.
Game Play of Annuvin
Move 7 spaces, minus the remaining number of friendly pieces. As your pieces die, remaining pieces can go further moves.
Agree on the variations
- Can/Cannot move over friendly counters?
- Full move compulsory or partial move allowed?
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 264 265 266 267 268 269 270 271 272 273 |
#!/usr/bin/perl use strict; use warnings; use SVG; # https://metacpan.org/pod/SVG # using scale of 66 here, and then 66 in estlecam to create # the CNC files to fit on an 11x11 board of wood 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 # title auto centers my $title = "4x4 Hex (Annuvin)"; # create an SVG object, canvas which we use for the rest of the draws my $svg = SVG->new( width => 11 * SCALE, height => 11 * SCALE, ); # only adjust this for changing hexes per page # 4x4= 2.5 # 5x5= 3.0 # 6x6= 3.5 # Larger hexsize = smaller hexes my $hexsize = 2.5; #---------------------------------------------- # Define the dots, lines, squares, circles etc # everything is based off of the segment length # of the circle radius, so "legs" of various length # used throughout rest of the math #---------------------------------------------- # 8 inch game board (11 inches with 1.5 inch boarder) # done so I could scale easier to fit my workpiece my $leg1 = (8/6); # 1.3333333333 (does this matter?) my $leg2 = ($leg1) * 2; # 2.6666666666 my $leg3 = ($leg1) * 3; # 3.9999999999 my $hex = (SCALE/$hexsize); # my $ctr = 5.5; # because our board is 11x11, so 5.5x5.5 is center # Squares are xy start then l,w in inches my %squares = ( sa => [0,0,11,11,0], # border/edge of board ); # color was used for debugging my %c = ( 'b' => 'black', 'r' => 'red', 'l' => 'blue', 'w' => 'white', 'g' => 'green', 'y' => 'yellow', 'o' => 'orange', 'k' => 'pink', 'p' => 'purple', 'e' => 'grey', 'lg' => 'LightGray', # D3D3D3 'bg' => 'Beige' # F5F5DC ); # xysteps are how far to go until next hex my $ystep = 0; my $xstep = 0; # what is the center of our board? my $xs = $ctr * SCALE; my $ys = $ctr * SCALE; my $hc = 100; # just a counter to start the hex ID # find the NW corner to start from my $ystart = hexstart(3,$hex,$xs,$ys,'y'); my $xstart = hexstart(3,$hex,$xs,$ys,'x'); hexes($hc, $hex , $xstart,$ystart, $c{w},'sw'); # ok, do the rest, in a smaller and smaller radius, clockwise for (0..1) {hexes($hc, $hex , $xs,$ys, $c{w},'sw');} for (0..2) {hexes($hc, $hex , $xs,$ys, $c{w},'se');} for (0..2) {hexes($hc, $hex , $xs,$ys, $c{w},'e');} for (0..2) {hexes($hc, $hex , $xs,$ys, $c{w},'ne');} for (0..2) {hexes($hc, $hex , $xs,$ys, $c{w},'nw');} for (0..1) {hexes($hc, $hex , $xs,$ys, $c{w},'w');} hexes($hc, $hex , $xs,$ys, $c{w},'sw'); for (0..1) {hexes($hc, $hex , $xs,$ys, $c{w},'sw');} for (0..1) {hexes($hc, $hex , $xs,$ys, $c{w},'se');} for (0..1) {hexes($hc, $hex , $xs,$ys, $c{w},'e');} for (0..1) {hexes($hc, $hex , $xs,$ys, $c{w},'ne');} for (0..1) {hexes($hc, $hex , $xs,$ys, $c{w},'nw');} for (1..1) {hexes($hc, $hex , $xs,$ys, $c{w},'w');} hexes($hc, $hex , $xs,$ys, $c{w},'sw'); for (1..1) {hexes($hc, $hex , $xs,$ys, $c{w},'sw');} for (1..1) {hexes($hc, $hex , $xs,$ys, $c{w},'se');} for (1..1) {hexes($hc, $hex , $xs,$ys, $c{w},'e');} for (1..1) {hexes($hc, $hex , $xs,$ys, $c{w},'ne');} for (1..1) {hexes($hc, $hex , $xs,$ys, $c{w},'nw');} for (1..1) {hexes($hc, $hex , $xs,$ys, $c{w},'sw');} hexes($hc, $hex , $xs,$ys, $c{w},'sw'); #---------------------------------------------- # Logic, no reason for sort but to help me see data when debugging #---------------------------------------------- # 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); #---------------------------------------------- # customs - accepts custom data paths #---------------------------------------------- sub hexstart { my $hops = shift; my $size = shift; my $strtx = shift; my $strty = shift; my $xy = shift; my ($hx1,$hy1,$hx2,$hy2,$hx3,$hy3,$hx4,$hy4,$hx5,$hy5,$hx6,$hy6,$hx7,$hy7); $hy6 = $strty + ((sqrt(3)/2) * $size) * 2; $hy2 = $strty - ((sqrt(3)/2) * $size); if ($xy eq 'y') {return $strty + ($hy2 - $hy6) * $hops;} if ($xy eq 'x') {return $strtx - (1.5 * $size) * $hops;} } sub hexes { #d='M 3130,5385 4012,5385 4453,6149 4012,6912 3130,6912 2689,6149 3130,5385 Z' # takes 6 points to make a hex. # takes xy start and builds hex with length from there my $id = shift; my $sz = shift; my $sx = shift; my $sy = shift; my $color = shift; my $dir = shift; my ($hx1,$hy1,$hx2,$hy2,$hx3,$hy3,$hx4,$hy4,$hx5,$hy5,$hx6,$hy6,$hx7,$hy7); # xy coorids for a scaled single hex based on sx and sy starts # begins at sw the goes clockwise for others, building custom string $hx1 = $sx - 1.5 * $sz; $hy1 = $sy + ((sqrt(3)/2) * $sz); $hx2 = $sx - 1.5 * $sz; $hy2 = $sy - ((sqrt(3)/2) * $sz); $hx3 = $sx; $hy3 = $sy - ((sqrt(3)/2) * $sz) * 2; $hx4 = $sx + .5 * 3 * $sz; $hy4 = $sy - ((sqrt(3)/2) * $sz); $hx5 = $sx + .5 * 3 * $sz; $hy5 = $sy + ((sqrt(3)/2) * $sz); $hx6 = $sx; $hy6 = $sy + ((sqrt(3)/2) * $sz) * 2; $hx7 = $hx1; $hy7 = $hy1; # step direction is which way to place the next hex # feed this sub a number of hexes and it goes that # direction, that many times. if ($dir eq 'nw') { $xstep = $sx - 1.5 * $sz; $ystep = $sy - ($hy6 - $hy2); $xs = $xstep; $ys = $ystep; } elsif ($dir eq 'ne') { $xstep = $sx + 1.5 * $sz; $ystep = $sy - ($hy6 - $hy2); $xs = $xstep; $ys = $ystep; } elsif ($dir eq 'se') { $xstep = $sx + 1.5 * $sz; $ystep = $sy + $hy6 - $hy2; $xs = $xstep; $ys = $ystep; } elsif ($dir eq 'sw') { $xstep = $sx - 1.5 * $sz; $ystep = $sy + $hy6 - $hy2; $xs = $xstep; $ys = $ystep; } elsif ($dir eq 'e') { $xstep = $sx + (1.5 * $sz) * 2; $xs = $xstep; $ys = $ystep; } elsif ($dir eq 'w') { $xstep = $sx - (1.5 * $sz) * 2; $xs = $xstep; $ys = $ystep; } elsif ($dir == 0) { $xs = $ctr * SCALE; $ys = $ctr * SCALE; } # no real hex method for perl SVG module, so custom string it: my $string = "M $hx1,$hy1 $hx2,$hy2 $hx3,$hy3 $hx4,$hy4 $hx5,$hy5 $hx6,$hy6 $hx7,$hy7 Z"; # add the object. my $tag = $svg->path( d => $string, id => 'hex_'.$id, style => { 'fill' => $color, 'stroke' => STROKE, 'stroke-width' => 3, 'stroke-opacity' => 1, 'fill-opacity' => 1, }, ); # advance hex id counter $hc++; } #---------------------------------------------- # 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); } #---------------------------------------------- # 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; |