Create Graph Paper or Checkerboard in Perl
In the quest to find activities to do with our kids, we decided to make some games. Instead of drawing the boards by hand (and because the CNC router wanted SVG files), we made a program to make the boards. Here is the Graph Paper or Checker Board of any size maker program:
List of Games that Use 8x8 Boards
Here is a partial list of games that use square boards. I say “square” because with only a slight modification, you can redo the boards of any size you like.
Thief (3x3) Very simple game of fox and geese like quality.
Dao (4x4) Make 4 in a row or occupy corners
Bulo (4x4) Don’t take the poison counter game
Queah (5x5) Liberian Checkers, but with safe spots
Seega (5x5) Custodianship captures after taking turns placing tokens.
3 Musketeers (5x5) Similar to fox and geese, but harder.
Knights (5x5) Swap spots, but using knights
Hepta (7x7) Tetris, but with tokens. Decent strategy.
Kuba (7x7) Fight for the center tokens using push and capture. Decent strategy.
Fox and Geese (8x8) Geese try to surround fox, fox(es) try to eat geese. Play twice to determine winner. Simple strategy.
Lines of Action (8x8) Occupy the other side while your enemy tries to stop you
Crossings (8x8) Form Rows and attack opponent, get to the other side. Decent strategy.
(8x8) Mak Yek (8x8) Russian Checkers, simple strategy
Reversi (8x8) Take turns flipping colors hopefully ending up with the most of your color
Oshi (9x9) Sumo like game of capture and push
Hasami Shogi (9x9) Capture peices, decent strategy
Campaign (10x10) Form X in a Row using Knights
So, as you can see, there are many many games using squares. There are games all the way up to 19x19 for games like “Go”.
#!/usr/bin/perl
# Makes checkered or squares to fit on 1 page A4
use strict;
use warnings;
use SVG; # https://metacpan.org/pod/SVG
use Getopt::Std; # for CLI options
# A4 Paper, .5 margins, Scale of 67 seems to fit
use constant SCALE => '67'; # dots per inch scale, adjust to fit on your board
use constant LINEWIDTH => '0'; #
use constant FILL => 'black'; # can be 'rgb(0,0,0)' too
use constant STROKE => 'black'; # can be 'rgb(0,0,0)' too
# create an SVG object, canvas which we use for the rest of the draws
# using 9 width and .5 starting dot, means use 8.5 ending dots
# that way it's centered, printable
my $svg = SVG->new(
width => 9 * SCALE,
height => 10 * SCALE,
);
my ($outfile, $squares, $checked, %options);
#-----------------------------------------------------------
# USAGE: Educates user on how to run program, then lists files
#-----------------------------------------------------------
sub usage {
my $msg = shift;
print "$msg" . "\n\n";
print "Usage: $0" . ' -o <somefile.svg> -c <1|0> -s <int> -h <0|1>' . "\n\n";
print "-o some output file name\n";
print "-c checkered 1 or 0. 1 = checkered, 0 = no checkers\n";
print "-s how many squares do you want?\n";
exit;
}
#----------------------------------------------
# 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;
my $lw = shift;
$svg->rectangle(
x => $x * SCALE,
y => $y * SCALE,
width => $w * SCALE,
height => $h * SCALE,
style => {
'fill' => FILL,
'stroke' => STROKE,
'stroke-width' => $lw,
'stroke-opacity' => 1,
'fill-opacity' => $fop, # must be 0, for lines, or 1 for solid squares
}
);
}
#----------------------------------------------
# Input and Verify
#----------------------------------------------
# Make sure at least one argument provided
if ( !@ARGV ) { usage(); }
# What are the options they entered
getopt("ocs", \%options);
# Do you want checker board or just squares?
if (defined $options{c}) {
$checked = $options{c};
if ($checked < 0) { usage("Use a 1 or a 0 for checkered or not") }
} else { usage("UNKNOWN CHECKERED"); }
# How many squares?
if (defined $options{s}) {
$squares = $options{s};
unless ($squares > 0) { usage("Use a 1 or a 0 for checkered or not") }
} else { usage("UNKNOWN SQUARES"); }
# Basic Out Put File Checks?
if (defined $options{o}) {
$outfile = $options{o};
if (-e $outfile) { usage("Not allowing you to clobber a file, try again") }
} else { usage("FILE EXISTS"); }
#----------------------------------------------
# Logic
#----------------------------------------------
# figure out how to fit their want, into our sizes
my $step = 8/$squares; # how big should each square be?
my $end = 8/$step; # should just be the same as squares
my @coors; # holds the steps of cooridinates for each square
my $start = .5; # we start at .5 as a margin
# loop over to get our xy start list from 1 to number of squares
foreach my $click (1..$squares) {
push (@coors,$start);
$start = $start + $step;
}
# make our checkers
my $counter = 2; # start the counter that tracks checkers
my $odd = $squares % 2; # is this an even or odd number of squares
if ($odd) {
foreach my $x (@coors) {
foreach my $y (@coors) {
if ($counter % 2) {
squares($x,$y,$step,$step,0,3);
} else {
squares($x,$y,$step,$step,$checked,3);
}
$counter++;
}
#$counter++; not needed for odd # of squares
}
} else {
foreach my $x (@coors) {
foreach my $y (@coors) {
if ($counter % 2) {
squares($x,$y,$step,$step,0,3);
} else {
squares($x,$y,$step,$step,$checked,3);
}
$counter++;
}
$counter++;
}
}
# draw box around it all
squares(.5,.5,8,8,0,3);
# Try to center the title
my $title = "Square Game Board $squares x $squares";
my $ltitle = length($title);
my $xtitle = 4.5 * SCALE - ($ltitle/4.5 * SCALE)/2;
$svg->text(
id => 'l1',
x => $xtitle,
y => SCALE * 9.5,
style => {
'font' => 'Serif',
'font-size' => 32,
'fill' => FILL,
},
)->cdata($title);
# all done, do et
# now render the SVG object, implicitly use svg namespace
open my $fh, ">:encoding(utf8)", $outfile or die "$!\n";
print $fh $svg->xmlify;
close $fh;
SVG Files For the Games Listed