Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

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?

    #!/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;

Annuvin Gameboard

Annuvin Game Board

Last updated on 13 Jul 2019
Published on 13 Jul 2019