Pretwa Game Board Using Perl to Create SVG
Pretwa is similar to checkers in that you jump and capture pieces. That is where the similarity ends. This article shows how I created a Pretwa board in SVG using Perl, and explains the rules of the game.
What is Pretwa?
Pretwa is a game from the state of Bihar, India for two players using 9 white and 9 black tokens.
Pretwa Game Board
You may download and use this board for your own personal use or to teach someone pretwa.
Pretwa Game Piece Setup
- 9 pieces are setup for the white on the 9, 11 and 1 o’clock positions lines.
- 9 pieces are setup for the black on the 3, 5 and 7 o’clock position lines.
- The center position is left open.
Objective of Pretwa
The objective of Pretwa is to capture all of your opponents pieces (except 3). Once they get down to 3 pieces, you are winner.
Pretwa Game Play
- Players take turns either sliding 1 segment or jumping opponents
- Jumps are compulsory. If you can jump, you must. You must land in an empty spot.
- Multiple jumps and directions are permitted.
- If you do not notice a jump, your opponent can take your piece as penalty.
- You may also win by blocking all of your opponents moves.
Pretwa SVG Game Board Code
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 |
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg height="670" width="603" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <circle cx="306.285714285714" cy="306.285714285714" r="76.5714285714286" style="fill: black; fill-opacity: 0; stroke: black; stroke-opacity: 1; stroke-width: 3" /> <circle cx="306.285714285714" cy="306.285714285714" r="153.142857142857" style="fill: black; fill-opacity: 0; stroke: black; stroke-opacity: 1; stroke-width: 3" /> <circle cx="306.285714285714" cy="306.285714285714" r="229.714285714286" style="fill: black; fill-opacity: 0; stroke: black; stroke-opacity: 1; stroke-width: 3" /> <polygon points="191.428571428571,107.347307244946 421.142857142857,505.224121326482 " style="fill: black; fill-opacity: 1; stroke: black; stroke-opacity: 1; stroke-width: 3" /> <polygon points="191.428571428571,505.224121326482 421.142857142857,107.347307244946 " style="fill: black; fill-opacity: 1; stroke: black; stroke-opacity: 1; stroke-width: 3" /> <polygon points="76.5714285714286,306.285714285714 536,306.285714285714 " style="fill: black; fill-opacity: 1; stroke: black; stroke-opacity: 1; stroke-width: 3" /> <circle cx="306.285714285714" cy="306.285714285714" r="7" /> <circle cx="268" cy="239.972911938792" r="7" /> <circle cx="421.142857142857" cy="505.224121326482" r="7" /> <circle cx="191.428571428571" cy="505.224121326482" r="7" /> <circle cx="421.142857142857" cy="107.347307244946" r="7" /> <circle cx="76.5714285714286" cy="306.285714285714" r="7" /> <circle cx="153.142857142857" cy="306.285714285714" r="7" /> <circle cx="229.714285714286" cy="306.285714285714" r="7" /> <circle cx="306.285714285714" cy="306.285714285714" r="7" /> <circle cx="382.857142857143" cy="306.285714285714" r="7" /> <circle cx="459.428571428571" cy="306.285714285714" r="7" /> <circle cx="536" cy="306.285714285714" r="7" /> <circle cx="344.571428571429" cy="372.598516632637" r="7" /> <circle cx="268" cy="372.598516632637" r="7" /> <circle cx="344.571428571429" cy="239.972911938792" r="7" /> <circle cx="229.714285714286" cy="173.660109591869" r="7" /> <circle cx="382.857142857143" cy="438.91131897956" r="7" /> <circle cx="229.714285714286" cy="438.91131897956" r="7" /> <circle cx="382.857142857143" cy="173.660109591869" r="7" /> <circle cx="191.428571428571" cy="107.347307244946" r="7" /> <text id="l1" style="fill: black; font: Serif; font-size: 32" x="256.833333333333" y="636.5">Pretwa</text> <!-- Generated using the Perl SVG Module V2.84 by Ronan Oger Info: http://www.roitsystems.com/ --> </svg> |
Perl Script to Generate Pretwa Board in SVG
The hardest part was figuring out the positions of the dots and the lines. It took me a bit to brush up on my trig. Enjoy.
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 |
#!/usr/bin/perl # Pretwa 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 => '67'; # 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 = "Pretwa"; # create an SVG object, canvas which we use for the rest of the draws my $svg = SVG->new( width => 9 * SCALE, height => 10 * 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/7); # 1.1428571429 my $leg2 = (8/7) * 2; # 2.2857142857 my $leg3 = (8/7) * 3; # 3.4285714286 my $leg4 = (8/7) * 4; # 4.5714285714 my $leg5 = (8/7) * 5; # my $leg6 = (8/7) * 6; # my $leg7 = (8/7) * 7; # my $ctr = (8/7) * 4; # 4.5714285714, for code readability # Circles my %cs = ( # x, y, size, fill ca => [$ctr,$ctr,$leg1,0], cb => [$ctr,$ctr,$leg2,0], cc => [$ctr,$ctr,$leg3,0], ); # Line Coorids calculated based off of knowing that the # hex was made up of equilateral isoceles triangles # known formulas for calculating all coorids based on # legs only. I only had to draw an X in the right spot # the horizontal line didn't need much math. # NW to SE my $nwx = $ctr - .5 * $leg3; my $nwy = $ctr - (sqrt(3)/2)*$leg3; my $sex = $ctr + .5 * $leg3; my $sey = $ctr + (sqrt(3)/2)*$leg3; # SW to NE my $swx = $ctr - .5 * $leg3; my $swy = $ctr + (sqrt(3)/2)*$leg3; my $nex = $ctr + .5 * $leg3; my $ney = $ctr - (sqrt(3)/2)*$leg3; # Lines are xy start and xy stop coordinates, in inches my %l = ( # x y x y lb => [$nwx,$nwy,$sex,$sey], # NW to SE lc => [$swx,$swy,$nex,$ney], # SW to NE ld => [$leg1,$leg4,$leg7,$leg4],# E to W ); # Dots started with hash of arrays containing the central xy my %dots = ( 0 => [$ctr,$ctr], ); # make the coorindate dots not on the cetner line # 4 permutations, 3 different variables per permutation # chose to loop over instead of manually write up all dots my $counter = 1; foreach my $leg ($leg1,$leg2,$leg3) { my $dx1 = $ctr - .5 * $leg; my $dy1 = $ctr - (sqrt(3)/2)*$leg; $dots{$counter}[0] = $dx1; $dots{$counter}[1] = $dy1; $counter++; $dx1 = $ctr + .5 * $leg; $dy1 = $ctr + (sqrt(3)/2)*$leg; $dots{$counter}[0] = $dx1; $dots{$counter}[1] = $dy1; $counter++; $dx1 = $ctr - .5 * $leg; $dy1 = $ctr + (sqrt(3)/2)*$leg; $dots{$counter}[0] = $dx1; $dots{$counter}[1] = $dy1; $counter++; $dx1 = $ctr + .5 * $leg; $dy1 = $ctr - (sqrt(3)/2)*$leg; $dots{$counter}[0] = $dx1; $dots{$counter}[1] = $dy1; $counter++; } # all of the dots on the center line foreach my $leg ($leg1,$leg2,$leg3,$leg4,$leg5,$leg6,$leg7) { $dots{$counter}[0] = $leg; $dots{$counter}[1] = $ctr; $counter++; } #---------------------------------------------- # Logic, no reason for sort but to help me see data #---------------------------------------------- # make our circles foreach my $cs (sort keys %cs) { circles($cs{$cs}[0],$cs{$cs}[1],$cs{$cs}[2],$cs{$cs}[3]); } # add some lines foreach my $cor (sort keys %l) { lines($l{$cor}[0],$l{$cor}[1],$l{$cor}[2],$l{$cor}[3]); } # add the dots foreach my $cor (sort keys %dots) { dots($dots{$cor}[0],$dots{$cor}[1]); } # Text, at SCALE of 142, 6.5 letters per inch, Serif Font # Text, at SCALE of 96, 5 letters per inche, Serif Font # 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 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); #---------------------------------------------- # dots sub - basically small circles on xy coorids #---------------------------------------------- sub dots { # takes 2 arguments, makes a dot my $x = shift; my $y = shift; $svg->circle( cx => $x * SCALE, cy => $y * SCALE, r => DOTSIZE, ); } #---------------------------------------------- # 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; #print "$xstart,$ystart,$xstop,$ystop\n"; 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, }, ); } # now render the SVG object, implicitly use svg namespace print $svg->xmlify; |