#!/usr/bin/perl use strict; # This program generates acrostics. It first generates a large array, and switches the appropriate cells of the array to 1s to create squares, # filled in sections, letters, and numbers. It writes the results to an image file in XBM format (chosen because of the ease of writing to such files). # It is driven principally by a command line interface using which you enter rows of letters. Given # the value of the final number it fills in all the rest for you (note that if you have enough memory, and can generate all eight rows at once, # it isn't necessary to have this input: it's easy to figure out what the number is algorithmically). This program is a major memory hog (seemingly # inevitably -- anyone have any ideas?) # I am a rookie programmer. There are probably about a billion things wrong with this program, and I would appreciate any (constructive) advice users of the program # could give me. ### INITIALIZE VARIABLES our($hldstring,$str,$numyrows,$numdigs,$numxrows,$col,$row,$boxnums,$orboxnum,$c,$wholecommand,@commandarray,$istart,@strs,$name,@grid,%numbers,%letters,$xcorn,$ycorn); $numyrows = 8; # number of rows in the acrostic $numxrows = 27; # number of columns in the acrostic our $xdim = 72*$numxrows; # number of elements across the array our $ydim = 72*$numyrows; # number of elements down the array our @commands; InitializeGrid(); LoadTables(); $col = $row = 0; ### GET INPUT # first get the final number, then ask for the row data print("The acrostic is a grid of 27 squares by $numyrows squares. Please \nfirst enter the last number value in the $numyrows-line block: "); $boxnums = ; chomp($boxnums); $orboxnum = $boxnums; #store the original number of boxes in an array. This is so the file can create image files with meaningful titles (see #below, in the CONVERT AND WRITE TO FILE SECTION print("\n\n"."Now please enter the letters corresponding to each square from left to right.\nIndicate a black square with a \"_\". After each eight characters have been entered press"."\n"."return to advance to the next line. If you make a mistake you will have an opportunity to correct\nit before the program begins.\n\n> "); while(){ $commands[$row] = $_; chomp($commands[$row]); if(length($commands[$row]) > 27){ print("Too many characters. Please enter the line again.\n> "); } elsif(length($commands[$row]) < 27){ print("Too few characters. Please enter the line again.\n"); } elsif(length($commands[$row]) == 27){ $commands[$row] =~ tr/[a-z]/[A-Z]/; if( $commands[$row] =~ /[^A-Z_]/){ print("Sorry. Only letters and \"_\" are permitted to be entered. Please enter line again.\n> "); next; } print("\n"."You entered: ".$commands[$row]."\n\n> "); $row++; if($row == $ydim / 72){ print("\n"); last; } } } AskAfter(); foreach $c (@commands){ $wholecommand .= $c; } ### PASS DRAWING INSTRUCTIONS @commandarray = split('',$wholecommand); $ycorn = $ydim - 72; $xcorn = 1872; $istart = ($ydim / 72) * 27 - 1; for (my $i = $istart ; $i >= 0 ; $i--){ if($commandarray[$i] =~ /_/){ FillBlack($xcorn,$ycorn); if($xcorn == 0){ $xcorn = 1872; $ycorn -= 72; } else { $xcorn -= 72; } } elsif($commandarray[$i] =~ /[A-Z]/){ MakeSquare($xcorn,$ycorn); print($commandarray[$i].$boxnums," XCORN: $xcorn YCORN: $ycorn","\n"); if($boxnums <10) { $boxnums = "0".$boxnums; } GenerateCoor($xcorn,$ycorn,$commandarray[$i].$boxnums); $boxnums--; if($xcorn == 0){ $xcorn = 1872; $ycorn -= 72; } else { $xcorn -= 72; } } } print("Done.\n\n Writing image to file..."); ### CONVERT AND WRITE TO FILE @strs = FlattenGrid(); PrepareFile(); $name = "$orboxnum"."to"."$boxnums"; open (O,">$name.xbm"); print O "\#define test_width $xdim\n\#define test_height $ydim\nstatic unsigned char test_bits[] = {"; print O $hldstring; print O "};"; close(O); print("\a\nDone.\n"); ### SUBROUTINES sub InitializeGrid { for (my $i = 0 ; $i <= $ydim - 1 ; $i++){ for (my $j = 0 ; $j <= $xdim - 1; $j++) { $grid[$i][$j] = 0; } } } ### Array-handling subroutines : these take data from drawing routines and prepare it for processing sub WriteGrid { ### WriteGrid takes instructions from various drawing subroutines (e.g. those for squares, filled squares, letters & numbers) my $x = shift; ### and passes them to CheckCommands to make sure they're legal before sending them to DoCommands for final processing my $y = shift; my $instruction = shift; $instruction =~ s/(?:\{|\})//g; CheckCommands($x,$y,$instruction); } sub CheckCommands { my $chcksum = 0; my $x = shift; my $y = shift; my $instruction = shift; my $tmpsum1 = 0; my $tmpsum2 = 0; my @grid; @commands = split(',',$instruction); foreach $c (@commands) { $c =~ s/(?:\{|\})//g; ($tmpsum1,$tmpsum2) = $c =~ /(\d+)\w(\d+)/; ### parse the instructions from the letter and number tables $chcksum += ($tmpsum2 - $tmpsum1); ### make sure that the instructions it has received encompass an entire 72-pixel width; otherwise there's problems } if($chcksum != 72) { print("Incomplete Line!: $c\n"); die; } else { my $commandstring = join(',',@commands); DoCommands($x,$y,$commandstring); } } sub DoCommands { our $rowcount; my($num1,$num2); my $char = 0; my $bit = 0; my $num = 0; my $xc = shift; my $yc = shift; my $string = shift; $xc = 0; my @commands = split(',',$string); foreach $c (@commands){ ($num1,$char,$num2) = $c =~ /(\d+)(\w)(\d+)/; # if($char =~ /w/i){ # $bit = 0; # } elsif ($char =~ /b/i) { # Here's where the writing to the array takes place $bit = 1; # } # for (my $i = $num1 ; $i <= $num2 -1 ; $i++){ $grid[$yc][$xc + $i] = $bit; } } $rowcount = $yc; } sub FlattenGrid { ### turn the array into a bunch of strings suitable for passing to the file my $c = 0; $str = ''; for (my $i = 0 ; $i <= $ydim ; $i++){ for (my $j = 0 ; $j <= $xdim ; $j++) { $str .= $grid[$i][$j]; $c++; } } my @strs = split('',$str); return(@strs); } sub PrepareFile { my ($a,$s,$tmp); my $i = 0; our(@strs); $a = "0x"; my $count = 0; #fill in the data while ($i <= length($str)){ if($count == 9){ $hldstring .= "\015\012\040\040\040"; ### make a new line in the XBM data to facilitate reading $count = 0; } my $tmpbit0 = $strs[$i]; my $tmpbit1 = $strs[$i+1]; my $tmpbit2 = $strs[$i+2]; my $tmpbit3 = $strs[$i+3]; my $tmpbit4 = $strs[$i+4]; my $tmpbit5 = $strs[$i+5]; my $tmpbit6 = $strs[$i+6]; my $tmpbit7 = $strs[$i+7]; my $tmpbyte = $tmpbit7.$tmpbit6.$tmpbit5.$tmpbit4.$tmpbit3.$tmpbit2.$tmpbit1.$tmpbit0; $tmp = unpack("H8",pack("C",oct("0b".$tmpbyte))); $tmp =~ tr/[a-z]/[A-Z]/; $tmp = $a."$tmp,\040"; $hldstring .= $tmp; $i += 8; $count++; } $hldstring =~ s/, $//; } ### square and filled square generation subroutines sub MakeSquare { my $xb = shift; # Beginning x and my $yb = shift; # y coordinates my $xnext = $xb + 1; my $xe = $xb + 72; # Ending x and my $ye = $yb + 72; # y coordinates my $xeless = $xe - 1; # x coordinate right before the end WriteGrid($xb,$yb,"{$xb}b{$xe}"); # top line is black for (my $i = $yb + 1 ; $i <= $ye - 2 ; $i++){ WriteGrid($xb,$i,"{$xb}b"."$xnext".","."$xnext"."w{$xeless},{$xeless}b{$xe}"); #middle lines have black on either side } WriteGrid($xb,$ye - 1,"{$xb}b{$xe}"); # bottom line is black } sub FillBlack { my $xb = shift; # Beginning x and my $yb = shift; # y coordinates my $xe = $xb + 72; # Ending x and my $ye = $yb + 72; # y coordinates my $xeless = $xe - 1; # x coordinate right before the end for (my $i = $yb ; $i <= $ye - 1 ; $i++){ WriteGrid($xb,$i,"{$xb}b{$xe}"); } } ### Letter and Number Generation Subroutines sub GenerateCoor{ ### combine number and letter data into a single line our @lastc; my ($letter,$number,$numberdata,$olda,@sects,$s,$n,$lastlet,$numnumlines,$xbmore,@letterdata,@temp,@numberdata,@dgs,$i,$d,$c,@tmpnumdat,$t,$numletlines); my $xb = shift; my $yb = shift; my $keystring = shift; # for example: "A9" my $lastnum; my $clast; ($letter,$number) = $keystring =~ /(\w)(\d+)/; $letter =~ tr/[A-Z]/[a-z]/; my $letterdata = $letters{$letter}; #letterdata if($number =~ /^\d{1}$/){ # if it's just one digit then no problem $numberdata = $numbers{$number}; @letterdata = split(';',$letterdata); # parse the drawing instructrions from the table @numberdata = split(';',$numberdata); $numdigs = 1; } elsif($number =~ /\d{2,3}/){ @letterdata = split(';',$letterdata); @dgs = split('',$number); $numdigs = $#dgs + 1; $i = 0; foreach $d (@dgs){ $c = 0; $tmpnumdat[$i] = $numbers{$d}; @temp = split(';',$tmpnumdat[$i]); foreach $t (@temp) { $numberdata[$c] .= $t.","; $c++; } foreach $n (@numberdata){ $n =~ s/ //g; } ($lastnum) = $tmpnumdat[$i] =~ /^.*?(?:w|b)(..).{0,1}$/; $i++; } } $numletlines = $#letterdata; $numnumlines = $#numberdata; my $lxb = $xb + 5; # beginning x value for letter (for formatting) my $lyb = $yb + 3; # beginning y value for letter my $nxb = $xb + 54; # beginning x value for number my $nxe = $nxb + 18; # beginning y value for number my $lxe = $xb + 10; # ending x value for letter my $xe = $xb + 72; # get the ending x coordinate within the relative space of the 72x72 grid $xbmore = $xb+1; my $lye = $yb + 6; my $xless = $xe - 1; if($numdigs == 1){ for (my $i = 0 ; $i <= $numletlines ; $i++){ $letterdata[$i] =~ s/(\d+)/$1+$lxb/ge; $numberdata[$i] =~ s/(\d+)/$1+$nxb/ge; ($lastlet) = $letterdata[$i] =~ /^.*?(?:w|b)(..).{0,1}$/; ($lastnum) = $numberdata[$i] =~ /^.*?(?:w|b)(..).{0,1}$/; my $commandstring = "$xb"."b"."$xbmore".",1w$lxb,".$letterdata[$i].",$lastlet"."w$nxb".",$numberdata[$i]".",$lastnum"."w"."$xless".",$xless"."b"."$xe"; $commandstring =~ s/ //g; WriteGrid($xb,$lyb,$commandstring); $commandstring = ''; $lyb++; } } elsif($numdigs > 1){ for (my $i = 0 ; $i <= $numnumlines ; $i++){ @sects = split(',',$numberdata[$i]); $numberdata[$i] = ''; $clast = 0; foreach $s (@sects) { # combine the data from different numbers into a single line ($a,$b,$c) = $s =~ /(\d{1,2})(\w)(\d{1,2})/; if($a == $clast){ $numberdata[$i] .= $s.","; $clast = $c; next; } if($a != $clast){ $olda = $a; # make sure that the beginning coordinates of each new number match with the ending coordinates $a += ($clast - $a); # of the previous one $c += ($clast - $olda); $clast = $c; $numberdata[$i] .= $a.$b.$c.","; next; } } $letterdata[$i] =~ s/(\d+)/$1+$lxb/ge; $numberdata[$i] =~ s/(\d+)/$1+$nxb/ge; $letterdata[$i] =~ s/ //g; $numberdata[$i] =~ s/ //g; if($letterdata[$i] =~ /^$/){ $letterdata[$i] = '5w10'; } ($lastnum) = $numberdata[$i] =~ /^.*?(?:w|b)(\d+),$/; my $commandstring = "$xb"."b"."$xbmore,"."$xbmore"."w$lxb,".$letterdata[$i].",$lxe"."w$nxb".",$numberdata[$i]"."$lastnum"."w"."$xless".",$xless"."b"."$xe"; WriteGrid($xb,$lyb,$commandstring); $lastnum = 0; $lyb++; } } undef @numberdata; # clear @numberdata for the next pass around the block } ### I/O Subroutines sub AskAfter { print("Please check your input. If you need to make any corrections type in the number of\nthe line at the prompt \">\". Otherwise type \"OK\" at the prompt and press return.\n\n"); my $i = 1; foreach $c (@commands){ print("ROW $i: $c\n"); $i++; } PrintPrompt(); } sub PrintPrompt { print "\n>"; my $inp = ; if($inp =~ /OK/i){ print("\nProcessing..."); } elsif($inp =~ /(\d+)/){ print("\n".$commands[$1-1]."\n"); ChangeInput($1-1); } } sub ChangeInput { my $rownum = shift; print("Change to: "); my $inp = ; chomp($inp); $inp =~ tr/[a-z]/[A-Z]/; if(CheckLineInput($inp) == 1){ PrintPrompt(); } elsif(CheckLineInput($inp) == 0){ $commands[$rownum] = $inp; print("\nRow ".($rownum+1)." changed to ".$commands[$rownum].".\n\n"); AskAfter(); } } sub CheckLineInput { my $input = shift; chomp($input); if(length($input) > 27){ print("Too many characters. Please enter the line again.\n"); } elsif(length($input) < 27){ print("Too few characters. Please enter the line again.\n"); } elsif(length($input) == 27){ if( $input =~ /[^A-Z_]/){ print("Sorry. Only letters and \"_\" are permitted to be entered. Please enter line number and change again.\n"); return(1); last; } return(0); last; } } #### LOAD TABLES: #### ------------ #### This is where the data for the numbers and letters are kept. In order to make it easier to read and to correct I #### used a format in which all numbers and letters were composed of bits on a 5x9 grid. Drawing on each line of this grid #### is determined by a sequence of instructions delineated by commas ; each line of instructions is separated from the next #### by a semicolon. Each instruction begins and ends with a number, and has a letter in between. If the letter is 'w' the pixel is #### white, and if 'b' then black. The starting number determines where the white/black pixel(s) starts, and the final number determines #### where it ends. All lines of instructions must have 0 as their starting coordinate and 5 as their ending coordinate, otherwise, the #### CheckCommands() subroutine will generate an error. sub LoadTables { %numbers = ('0' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w3,3b5 ; 0b1,1w2,2b3,3w4,4b5 ; 0b2,2w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', '1' => '0w2,2b3,3w5 ; 0w1,1b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w1,1b4,4w5', '2' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0w4,4b5 ; 0w4,4b5 ;0w3,3b4,4w5 ; 0w2,2b3,3w5 ; 0w1,1b2,2w5 ; 0b1,1w5 ; 0b5', '3' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0w4,4b5 ; 0w2,2b4,4w5 ; 0w4,4b5 ; 0w4,4b5 ; 0w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', '4' => '0w3,3b4,4w5 ; 0w2,2b4,4w5 ; 0w1,1b2,2w3,3b4,4w5 ; 0b1,1w3,3b4,4w5 ; 0b5 ; 0w3,3b4,4w5 ; 0w3,3b4,4w5 ; 0w3,3b4,4w5 ; 0w3,3b4,4w5', '5' => '0b5 ; 0b1,1w5 ; 0b1,1w5 ; 0b4,4w5 ; 0w4,4b5 ; 0w4,4b5 ; 0w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', '6' => '0w2,2b4,4w5 ; 0w1,1b2,2w5 ; 0b1,1w5 ; 0b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', '7' => '0b5 ; 0w4,4b5 ; 0w4,4b5 ; 0w3,3b4,4w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5', '8' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', '9' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b5 ; 0w4,4b5 ; 0w3,3b4,4w5 ; 0w1,1b3,3w5' ); %letters = ('a' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5', 'b' => '0b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b4,4w5', 'c' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', 'd' => '0b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b4,4w5 ', 'e' => '0b5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b4,4w5; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b5', 'f' => '0b5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b4,4w5; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5', 'g' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w3,3b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', 'h' => '0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5', 'i' => '0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5', 'j' => '0w4,4b5 ; 0w4,4b5 ; 0w4,4b5 ; 0w4,4b5 ; 0w4,4b5 ; 0w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', 'k' => '0b1,1w4,4b5 ; 0b1,1w3,3b4,4w5 ; 0b1,1w2,2b3,3w5 ; 0b2,2w5 ; 0b1,1w5 ; 0b2,2w5 ; 0b1,1w2,2b3,3w5 ; 0b1,1w3,3b4,4w5 ; 0b1,1w4,4b5', 'l' => '0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b5', 'm' => '0b1,1w4,4b5 ; 0b2,2w3,3b5 ; 0b1,1w2,2b3,3w4,4b5 ; 0b1,1w2,2b3,3w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5', 'n' => '0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b2,2w4,4b5 ; 0b1,1w2,2b3,3w4,4b5 ; 0b1,1w3,3b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5', 'o' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', 'p' => '0b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b4,4w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b1,1w5', 'q' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1, 1b4, 4w5 ; 0w3, 3b5', 'r' => '0b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5', 's' => '0w1,1b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w5 ; 0b1,1w5 ; 0w1,1b4,4w5 ; 0w4,4b5 ; 0w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', 't' => '0b5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5', 'u' => '0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b4,4w5', 'v' => '0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b2,2w3,3b4,4w5 ; 0w1,1b2,2w3,3b4,4w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5', 'w' => '0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w2,2b3,3w4,4b5 ; 0b2,2w3,3b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5', 'x' => '0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b2,2w3,3b4,4w5 ; 0w2,2b3,3w5 ; 0w1,1b2,2w3,3b4,4w5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5', 'y' => '0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0b1,1w4,4b5 ; 0w1,1b2,2w3,3b4,4w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5 ; 0w2,2b3,3w5', 'z' => '0b5 ; 0w4,4b5 ; 0w4,4b5 ; 0w3,3b4,4w5 ; 0w2,2b3,3w5 ; 0w1,1b2,2w5 ; 0b1,1w5 ; 0b1,1w5 ; 0b5' ) } =head1 NAME Acrostic.pl =head1 DESCRIPTION - a small script to generate graphic images (in XBM format) of acrostic grids based upon a sequence of letters (corresponding to letters in the acrostic) and underscores ('_': to indicate black squares) at a command prompt. =pod SCRIPT CATEGORIES CPAN/Graphics Fun/Educational =cut