Re: Inputing vectors into a scrabble-esque game
by GrandFather (Saint) on Oct 31, 2019 at 00:12 UTC
|
For purposes of maintenance and code validation the @letter initialization code may be better written:
my @letters =
('a') x 9, ('b') x 2, ('c') x 2, ('d') x 4, ('e') x 12, ('f') x 2,
('g') x 4, ('h') x 2, ('i') x 9, ('j') x 1, ('k') x 1, ('l') x 4,
+('m') x 2,
('n') x 6, ('o') x 8, ('p') x 2, ('q') x 1, ('r') x 6, ('s') x 4,
+('t') x 6,
('u') x 4, ('v') x 2, ('w') x 2, ('x') x 1, ('y') x 2, ('z') x 1;
and of course you should always use strictures.
Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
| [reply] [d/l] |
|
use 5.026;
use warnings;
my @letters = do {
my @chars = ( q{a} .. q{z} );
my @counts = (
9, 2, 2, 4, 12, 2, 4, 2, 9, 1, 1, 4, 2,
6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1 );
map { ( $chars[ $_ ] ) x $counts[ $_ ] } 0 .. 25;
};
say join q{}, @letters;
Produces:-
aaaaaaaaabbccddddeeeeeeeeeeeeffgggghhiiiiiiiiijkllllmmnnnnnnoooooooopp
+qrrrrrrssssttttttuuuuvvwwxyyz
I hope this is of interest.
| [reply] [d/l] [select] |
|
| [reply] |
Re: Inputing vectors into a scrabble-esque game
by bliako (Monsignor) on Oct 30, 2019 at 23:12 UTC
|
If that's one more act in the battle of the sexes (oh the most iconic of the palindromes!), I will gladly give my 2 bits to achieve balance:
How about you have the phone take a picture of the board, reconstruct the board in memory, find best move for you? And optionally looking ahead and minimising the score of your opponent's next move.
I have looked briefly at your previously-related post, its answers and the link provided to an older thread for scrabble, but I could not see a function which searches for words in dictionary when some of its letters are clamped on specific values. I.e. for those letters already set on the board squares where you plan to place your new word. So, can you start with a filter for the results of tybalt89's my $pattern = join '', map "$_?", sort @tiles; to make sure your candidate words have specific letters at specific positions?
Then have another function which calculates the score of each candidate word taking into consideration what's already on board (i think appending to existing words gives you extra credit?). Would that be easier by having that function taking the board state as input, adds your candidate word in it and re-calculates the total board score? Subtracting this from initial score will be your word's score - more or less, right?
bw, bliako
| [reply] [d/l] |
|
... have the phone take a picture ...
25 years ago, that sentence would not have made any sense at all. It's quite impressive how the prefered instrument for taking a snapshot has moved from a dedicated, perhaps analog camera to the camera embedded in a smartphone.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
| [reply] |
|
How about you have the phone take a picture of the board, reconstruct the board in memory, find best move for you? And optionally looking ahead and minimising the score of your opponent's next move.
I would love to be able to use phone technology in such a manner. These might be my first tepid steps to coding for this device. I'm always glad to entertain asides and "what are we on the cusp of" discussions, provided that we're also addressing the main topic of the thread.
but I could not see a function which searches for words in dictionary when some of its letters are clamped on specific values. I.e. for those letters already set on the board squares where you plan to place your new word.
I have some ideas on how to deal with that clamping. Our algorithm would move bottom to top for possible placing of vertical vectors, and right to left if they are horizontal. I would think that that would create analogous logic for the two cases. You either have to place your tiles vertically, or horizontally, but never both.
So, can you start with a filter for the results of tybalt89's my $pattern = join '', map "$_?", sort @tiles; to make sure your candidate words have specific letters at specific positions?
The resulting string is simply the tiles with a question mark as padding. I didn't find that useful for this version.
Then have another function which calculates the score of each candidate word taking into consideration what's already on board (i think appending to existing words gives you extra credit?). Would that be easier by having that function taking the board state as input, adds your candidate word in it and re-calculates the total board score? Subtracting this from initial score will be your word's score - more or less, right?I've started with a calculation function and "gotten on the proverbial board." Let me trot out some output then source next:
Questions:
Q1) How do I print the board by showing the letter value in the hash stored at each array location?
As I'm looking at what I have, I realize what I want for the board. It's to have the column numbers displayed in the first row and the row letters displayed in the first column. We could put a character in the corner like a black square. Thus, the array of hashes will be 11x11, but the values will no longer be zero indexed in a way that needs to be accounted for.
Q2) How do I best create these arrays?
Q3 How am I getting greater than 7! = 5040 values from the uniq call on 7 tiles?
Q4) How to I take the best word that %found has and insert it into the array of hashes at, say, the sixth row beginning at the third column and going right? We are guaranteed to have enough room for the first word. It is the only one that can be played without touching the previous graph at some point. (no floaters after the first one).
Thanks for your comments
| [reply] [d/l] |
Re: Inputing vectors into a scrabble-esque game
by tybalt89 (Monsignor) on Nov 01, 2019 at 19:28 UTC
|
Here's some (incomplete) code that (sort of) plays upwords. What's missing is any scoring or score keeping.
I use a simple string for the board, and another string for the height of each cell.
Example board and example heights:
.......... 0000000000
.......c.. 0000000200
.lauze.o.. 0211110100
.e.....a.. 0100000100
.g.....r.. 0200000100
baronies.. 1533553100
.t.....e.. 0200000100
.e.....r.. 0100000200
.......... 0000000000
.......... 0000000000
Using a string enables me to "fairly" easily find all the locations where a new word could go using a regex.
Since words can be either left-right or top-down I go through the core of finding words twice, once normally, and the second time
with the those two strings transposed(flipped around the major axis) to get the best (longest) word to play.
Other than scoring, I think I've got most of the rules followed correctly.
The program continues to play until it runs out of tiles, or (if you play smaller versions, like 4x4) the height string is all 5's.
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11108138
use warnings;
use Path::Tiny;
use List::Util qw( shuffle uniq first );
$SIG{__WARN__} = sub { die @_ };
my $n = 10;
my $maxtiles = 7;
my $upwords = 1; # 0 => extending(normal scrabble?) 1 => upwords
my $n1 = $n + 1;
my $board = ('.' x $n . "\n") x $n;
my $heights = $board =~ tr/./0/r;
my @dictwords;
my $filename = "words.11108138.$n"; # for caching
if( -f $filename )
{
@dictwords = split /\n/, path($filename)->slurp;
}
else
{
@dictwords = sort { length $b <=> length $a }
grep /^[a-z]{2,$n}$/,
path('/usr/share/dict/words')->lines({chomp => 1});
path($filename)->spew(map "$_\n", @dictwords);
}
my @drawpile = shuffle + # thanks to GrandFather 11108145
('a') x 9, ('b') x 2, ('c') x 2, ('d') x 4, ('e') x 12, ('f') x 2,
('g') x 4, ('h') x 2, ('i') x 9, ('j') x 1, ('k') x 1, ('l') x 4, ('
+m') x 2,
('n') x 6, ('o') x 8, ('p') x 2, ('q') x 1, ('r') x 6, ('s') x 4, ('
+t') x 6,
('u') x 4, ('v') x 2, ('w') x 2, ('x') x 1, ('y') x 2, ('z') x 1 ;
my @tiles = sort splice @drawpile, 0, $maxtiles;
print "tiles: @tiles\n";
my $pat = join '', map "$_?", @tiles;
my $word = first
{ /^[@tiles]+$/ and (join '', sort split //) =~ /^$pat$/ } @dictword
+s;
substr $board, $n1 * ($n >> 1) + ($n - length($word) >> 1),
length $word, $word;
substr $heights, $n1 * ($n >> 1) + ($n - length($word) >> 1),
length $word, ($upwords ? 1 : 5) x length $word;
my @chosen = $word;
my $changed = 1;
my $moves = 0;
my $b = $board =~ tr/\n/-/r;
$b =~ s/-/ $_/ for $heights =~ /.*\n/g;
print $b;
while( @tiles )
{
$upwords or $board =~ /\./ or last;
$upwords && $heights =~ tr/0-4// == 0 and last;
my @best; # [ flip, pos, pat, word ]
my @all = (@tiles, ' ', sort +uniq $board =~ /\w/g);
$moves++;
print "moves: $moves tiles: @tiles\n";
my @subdict = grep /^[@all]+$/, @dictwords;
for my $flip ( 0, 1 )
{
my $inorder = join '', map "$_?", sort "@all" =~ /\w/g;
my $orderpat = qr/^$inorder$/;
my @pat;
$board =~ /(?<!\w).{2,}(?!\w)(?{
push @pat, [ $flip, $-[0], $& ]
})(*FAIL)/;
$upwords and @pat = map expand($_), @pat;
@pat = grep $_->[2] =~ /\w/, @pat;
$upwords or
@pat = grep { substr( $board, $_->[1], length $_->[2]) =~ /\./ }
+ @pat;
for my $p ( @pat )
{
my ($flip, $pos, $pat) = @$p;
my @under = substr( $board, $pos, length $pat) =~ /\w/g;
my $w = first { /^[@under@tiles]+$/
&& /^$pat$/
&& (join '', sort /\w/g ) =~ /$orderpat/
&& ( /s$/ ? $pat ne s/s$/./r : 1 )
&& ( $upwords ? matchrule( $pos, $_ ) : 1 )
} @subdict;
$w and $best[ length $w ] //= [ $flip, $pos, $pat, $w ];
}
transpose();
}
if( $changed = @best )
{
my ($flip, $pos, $pat, $word) = @{ $best[-1] };
$flip and transpose();
if( $upwords )
{
my $same = $word ^ substr $board, $pos, length $word;
my $tmppos = $pos;
substr( $heights, $tmppos++, 1 ) += $_ ne "\0" for split //, $sa
+me;
}
else
{
substr($heights, $pos, length $word) =~ tr/0/5/;
}
substr $board, $pos, length $word, $word;
print '-' x 20, "chosen: $flip $pos $word\n";
push @chosen, $word;
$flip and transpose();
my $tmpword = $word;
$tmpword =~ s/$_// for $pat =~ /\w/g;
my $tiles = join '', @tiles;
$tiles =~ s/$_// for split //, $tmpword;
@tiles = split //, $tiles;
}
else
{
splice @tiles, rand @tiles, 1; # discard random tile
}
@tiles = sort @tiles, splice @drawpile, 0, $maxtiles - @tiles;
if( $changed )
{
my $b = $board =~ tr/\n/-/r;
$b =~ s/-/ $_/ for $heights =~ /.*\n/g;
print $b;
}
}
print "\nchosen words: @chosen\n";
sub matchrule
{
my ($pos, $word) = @_;
my $tiles = join '', @tiles;
my $bd = substr $board, $pos, length $word;
my $count = substr $heights, $pos, length $word;
$bd eq $word and return 0;
for ( reverse split //, $word )
{
my $bchar = chop $bd;
my $stack = chop $count;
$_ eq $bchar and next;
$stack >= 5 and return 0;
$tiles =~ s/$_// or return 0;
}
return 1;
}
sub transpose
{
local $_ = $board;
$board = '';
$board .= "\n" while s/^./ $board .= $& ; '' /gem;
local $_ = $heights;
$heights = '';
$heights .= "\n" while s/^./ $heights .= $& ; '' /gem;
}
sub expand
{
my @ans;
my ($flip, $pos, $pat) = @{ shift() };
push @ans, [ $flip, $pos, $` =~ tr//./cr . $& . $' =~ tr//./cr ]
while $pat =~ /\w/g;
return @ans;
}
And here's a sample partial output:
moves: 9 tiles: c g j l n q x
--------------------chosen: 1 78 coarsen
.......... 0000000000
.......c.. 0000000200
.gauze.o.. 0111110100
.e.....a.. 0100000100
.l.....r.. 0100000100
baronies.. 1533553100
.d.....e.. 0100000100
.......n.. 0000000100
.......... 0000000000
.......... 0000000000
moves: 10 tiles: g j l q r t x
--------------------chosen: 1 78 coarser
.......... 0000000000
.......c.. 0000000200
.gauze.o.. 0111110100
.e.....a.. 0100000100
.l.....r.. 0100000100
baronies.. 1533553100
.d.....e.. 0100000100
.......r.. 0000000200
.......... 0000000000
.......... 0000000000
moves: 11 tiles: e g j l q t x
--------------------chosen: 1 13 legate
.......... 0000000000
.......c.. 0000000200
.lauze.o.. 0211110100
.e.....a.. 0100000100
.g.....r.. 0200000100
baronies.. 1533553100
.t.....e.. 0200000100
.e.....r.. 0100000200
.......... 0000000000
.......... 0000000000
Lots of little interesting problems in this game. It was fun, thanks.
| [reply] [d/l] [select] |
|
I'm a little dumbfounded that this much progress got made this quickly...wow.... I'll show sample output and then list source.
Lots of little interesting problems in this game. It was fun, thanks.
You bet. I think I'm going to get an extra physical game for myself.
I'm gonna need some time just to catch up to all this....
| [reply] [d/l] [select] |
|
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11108138
use warnings;
use Path::Tiny;
use List::Util qw( shuffle uniq first );
$SIG{__WARN__} = sub { die @_ };
my $n = 10; # configuration board will be $n by $n
my $maxtiles = 7;
my $dictionaryfile = '/usr/share/dict/words';
my $cachefilename = "words.11108138.$n"; # for caching subsets of dict
+ionary
my $n1 = $n + 1;
my $board = ('.' x $n . "\n") x $n;
my $heights = $board =~ tr/./0/r;
my @dictwords;
if( -f $cachefilename )
{
@dictwords = split /\n/, path($cachefilename)->slurp;
}
else
{
print "caching words of max length $n\n";
@dictwords = sort { length $b <=> length $a }
grep /^[a-z]{2,$n}$/,
split /\n/, path($dictionaryfile)->slurp;
path($cachefilename)->spew(join "\n", @dictwords, '');
}
my @drawpile = shuffle + # thanks to GrandFather 11108145
('a') x 9, ('b') x 2, ('c') x 2, ('d') x 4, ('e') x 12, ('f') x 2,
('g') x 4, ('h') x 2, ('i') x 9, ('j') x 1, ('k') x 1, ('l') x 4, ('
+m') x 2,
('n') x 6, ('o') x 8, ('p') x 2, ('q') x 1, ('r') x 6, ('s') x 4, ('
+t') x 6,
('u') x 4, ('v') x 2, ('w') x 2, ('x') x 1, ('y') x 2, ('z') x 1 ;
my @tiles = sort splice @drawpile, 0, $maxtiles;
print "tiles: @tiles\n";
my $pat = join '', map "$_?", @tiles;
my $word = first
{ /^[@tiles]+$/ and (join '', sort split //) =~ /^$pat$/ } @dictword
+s;
$word or die "no starting word can be found\n";
substr $board, $n1 * ($n >> 1) + ($n - length($word) >> 1),
length $word, $word;
substr $heights, $n1 * ($n >> 1) + ($n - length($word) >> 1),
length $word, 1 x length $word;
my $tiles = join '', @tiles;
$tiles =~ s/$_// for split //, $word;
@tiles = split //, $tiles;
push @tiles, splice @drawpile, 0, $maxtiles - @tiles;
my @chosen = $word;
my $changed = 1;
my $moves = 0;
my $totalscore = 2 * length $word;
printboard();
while( @tiles )
{
$heights =~ tr/5// == $n ** 2 and last; # all 5, no more play possib
+le
my @best; # [ flip, pos, pat, old, highs, word ]
my @all = (@tiles, ' ', sort +uniq $board =~ /\w/g);
$moves++;
print "moves: $moves tiles: @tiles\n";
my @subdict = grep /^[@all]+$/, @dictwords;
for my $flip ( 0, 1 )
{
my @pat;
$board =~ /(?<!\w).{2,}(?!\w)(?{ push @pat, [ $-[0], $& ] })(*FAIL
+)/;
@pat = map expand($_), @pat;
@pat = sort { length $b->[1] <=> length $a->[1] } @pat;
for ( @pat )
{
my ($pos, $pat) = @$_;
my $old = substr $board, $pos, length $pat;
my $highs = substr $heights, $pos, length $pat;
my @under = $old =~ /\w/g;
my $underpat = qr/[^@under@tiles]/;
my @w = grep {
length $pat == length $_
&& !/$underpat/
&& /^$pat$/
&& ( ($old ^ $_) !~ /^\0+\]$/ ) # adding just an 's' not allow
+ed
&& matchrule( $old, $highs, $_ )
} @subdict;
$best[ score($old, $highs, $_) ] //=
[ $flip, $pos, $pat, $old, $highs, $_ ] for @w;
}
transpose();
}
if( $changed = @best )
{
my ($flip, $pos, $pat, $old, $highs, $word) = @{ $best[-1] };
my $newmask = ($old ^ $word) =~ tr/\0/\xff/cr;
$flip and transpose();
substr $board, $pos, length $word, $word;
substr $heights, $pos, length $highs,
($highs & $newmask) =~ tr/0-5/1-6/r | ($highs & ~$newmask);
$flip and transpose();
my $tiles = join '', @tiles;
$tiles =~ s/$_// for split //, $word & $newmask;
@tiles = split //, $tiles;
$totalscore += my $score = score( $old, $highs, $word );
print '-' x 20, "chosen: $flip $pos $word score: $score\n";
push @chosen, $word;
}
else
{
my $tiles = join '', @tiles; # discard random tile
$tiles =~ s/$_// and last for 'q', 'z', $tiles[rand @tiles];
@tiles = split //, $tiles;
}
@tiles = sort @tiles, splice @drawpile, 0, $maxtiles - @tiles;
$changed and printboard();
}
print "\nchosen words: @chosen\ntotalscore: $totalscore\n";
sub score
{
my ($old, $highs, $word) = @_;
my $score = ($old ^ $word) =~ tr/\0//c == $maxtiles ? 20 : 0;
$score += chop($highs) + (chop($old) ne $_) for reverse split //, $w
+ord;
$score == length $word and $score *= 2; # no stacked letters
return $score;
}
sub printboard
{
my $bd = $board =~ tr/\n/-/r;
$bd =~ s/-/ $_/ for $heights =~ /.*\n/g;
print $bd;
}
sub matchrule
{
my ($old, $highs, $word) = @_;
$old eq $word and return 0;
my $newmask = ($old ^ $word) =~ tr/\0/\xff/cr;
($newmask & $highs) =~ tr/5// and return 0;
my $tiles = "@tiles";
$tiles =~ s/$_// or return 0 for ($newmask & $word) =~ /\w/g;
return 1;
}
sub transpose # both board and heights arrays
{
local $_ = $board;
$board = '';
$board .= "\n" while s/^./ $board .= $& ; '' /gem;
$_ = $heights;
$heights = '';
$heights .= "\n" while s/^./ $heights .= $& ; '' /gem;
}
sub expand # change patterns with several letters to several single le
+tter pats
{
my @ans;
my ($pos, $pat) = @{ shift() };
push @ans, [ $pos, $` =~ tr//./cr . $& . $' =~ tr//./cr ]
while $pat =~ /\w/g;
return @ans;
}
| [reply] [d/l] |
|
|
|
|
|
I found and fixed a bug in tile handling, and also removed the option to play normal scrabble (it was adding too much noise).
Also cleaned up some parts, including a major streamlining to 'matchrule'.
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11108138
use warnings;
use Path::Tiny;
use List::Util qw( shuffle uniq first );
$SIG{__WARN__} = sub { die @_ };
my $n = 10; # configuration board will be $n by $n
my $maxtiles = 7;
my $n1 = $n + 1;
my $board = ('.' x $n . "\n") x $n;
my $heights = $board =~ tr/./0/r;
my @dictwords;
my $filename = "words.11108138.$n"; # for caching
if( -f $filename )
{
@dictwords = split /\n/, path($filename)->slurp;
}
else
{
print "caching words of length $n\n";
@dictwords = sort { length $b <=> length $a }
grep /^[a-z]{2,$n}$/,
split /\n/, path('/usr/share/dict/words')->slurp;
path($filename)->spew(join "\n", @dictwords, '');
}
my @drawpile = shuffle + # thanks to GrandFather 11108145
('a') x 9, ('b') x 2, ('c') x 2, ('d') x 4, ('e') x 12, ('f') x 2,
('g') x 4, ('h') x 2, ('i') x 9, ('j') x 1, ('k') x 1, ('l') x 4, ('
+m') x 2,
('n') x 6, ('o') x 8, ('p') x 2, ('q') x 1, ('r') x 6, ('s') x 4, ('
+t') x 6,
('u') x 4, ('v') x 2, ('w') x 2, ('x') x 1, ('y') x 2, ('z') x 1 ;
my @tiles = sort splice @drawpile, 0, $maxtiles;
print "tiles: @tiles\n";
my $pat = join '', map "$_?", @tiles;
my $word = first
{ /^[@tiles]+$/ and (join '', sort split //) =~ /^$pat$/ } @dictword
+s;
$word or die "no starting word can be found\n";
substr $board, $n1 * ($n >> 1) + ($n - length($word) >> 1),
length $word, $word;
substr $heights, $n1 * ($n >> 1) + ($n - length($word) >> 1),
length $word, 1 x length $word;
my @chosen = $word;
my $changed = 1;
my $moves = 0;
my $totalscore = 2 * length $word;
printboard();
while( @tiles )
{
$heights =~ tr/5// == $n ** 2 and last; # all 5, no more play possib
+le
my @best; # [ flip, pos, pat, old, highs, word ]
my @all = (@tiles, ' ', sort +uniq $board =~ /\w/g);
$moves++;
print "moves: $moves tiles: @tiles\n";
my @subdict = grep /^[@all]+$/, @dictwords;
for my $flip ( 0, 1 )
{
my $inorder = join '', map "$_?", sort "@all" =~ /\w/g;
my $orderpat = qr/^$inorder$/;
my @pat;
$board =~ /(?<!\w).{2,}(?!\w)(?{ push @pat, [ $-[0], $& ] })(*FAIL
+)/;
@pat = map expand($_), @pat;
@pat = sort { length $b->[1] <=> length $a->[1] } @pat;
for ( @pat )
{
my ($pos, $pat) = @$_;
my $old = substr $board, $pos, length $pat;
my $highs = substr $heights, $pos, length $pat;
my @under = $old =~ /\w/g;
my $underpat = qr/[^@under@tiles]/;
my $w = first {
length $pat == length $_
&& !/$underpat/
&& /^$pat$/
&& ( /s$/ ? $pat ne s/s$/./r : 1 )
&& matchrule( $old, $highs, $_ )
} @subdict;
$w and $best[ length $w ] //=
[ $flip, $pos, $pat, $old, $highs, $w ], last;
}
transpose();
}
if( $changed = @best )
{
my ($flip, $pos, $pat, $old, $highs, $word) = @{ $best[-1] };
$flip and transpose();
my $usedtiles = '';
$usedtiles = $word;
my $same = $word ^ substr $board, $pos, length $word;
my $tmppos = $pos;
for ( split //, $same )
{
if( $_ ne "\0" )
{
substr( $heights, $tmppos, 1 ) =~ tr/0-4/1-5/; # new tile, add
+ 1
}
else
{
$usedtiles =~ s/$_// for substr $board, $tmppos, 1;
}
$tmppos++;
}
substr $board, $pos, length $word, $word;
$totalscore += my $score = score( $old, $highs, $word );
print '-' x 20, "chosen: $flip $pos $word score: $score\n";
push @chosen, $word;
$flip and transpose();
my $tiles = join '', @tiles;
$tiles =~ s/$_// for split //, $usedtiles;
@tiles = split //, $tiles;
}
else
{
splice @tiles, rand @tiles, 1; # discard random tile
}
@tiles = sort @tiles, splice @drawpile, 0, $maxtiles - @tiles;
$changed and printboard();
}
print "\nchosen words: @chosen\ntotalscore: $totalscore\n";
sub score
{
my ($old, $high, $word) = @_;
my $score = ($old ^ $word) =~ tr/\0//c == $maxtiles ? 20 : 0;
$score += chop($high) + (chop($old) ne $_) for reverse split //, $wo
+rd;
$score == length $word and $score *= 2; # no stacked letters
return $score;
}
sub printboard
{
my $bd = $board =~ tr/\n/-/r;
$bd =~ s/-/ $_/ for $heights =~ /.*\n/g;
print $bd;
}
sub matchrule
{
my ($old, $highs, $word) = @_;
$old eq $word and return 0;
my $newmask = ($old ^ $word) =~ tr/\0/\xff/cr;
($newmask & $highs) =~ tr/5// and return 0;
my $tiles = "@tiles";
$tiles =~ s/$_// or return 0 for ($newmask & $word) =~ /\w/g;
return 1;
}
sub transpose # both board and heights arrays
{
local $_ = $board;
$board = '';
$board .= "\n" while s/^./ $board .= $& ; '' /gem;
$_ = $heights;
$heights = '';
$heights .= "\n" while s/^./ $heights .= $& ; '' /gem;
}
sub expand # change patterns with several letters to several single le
+tter pats
{
my @ans;
my ($pos, $pat) = @{ shift() };
push @ans, [ $pos, $` =~ tr//./cr . $& . $' =~ tr//./cr ]
while $pat =~ /\w/g;
return @ans;
}
| [reply] [d/l] |
Re: Inputing vectors into a scrabble-esque game
by tybalt89 (Monsignor) on Nov 02, 2019 at 15:46 UTC
|
For input, how about just entering a string consisting of
a row digit of starting position of word
a column digit ditto
either a 'h' or a 'v' for whether the word is horizontal or vertical
the word
Example program:
#!/usr/bin/perl
use strict;
use warnings;
my $board = ('.' x 10 . "\n") x 10;
print "$board\n";
my $input = '23hacross'; # simulated read from STDIN
place($input);
print "$board\n";
$input = '16vdown'; # simulated read from STDIN
place($input);
print "$board\n";
sub place
{
my $input = shift;
my ($row, $column, $direction, $word) = $input =~ /^(\d)(\d)(v|h)(.*
+)/;
my $position = 11 * $row + $column;
for ( split //, $word )
{
substr $board, $position, 1, $_;
if( $direction eq 'h' )
{
$position++;
}
else
{
$position += 11;
}
}
}
Outputs:
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
...across.
..........
..........
..........
..........
..........
..........
..........
..........
......d...
...across.
......w...
......n...
..........
..........
..........
..........
..........
| [reply] [d/l] [select] |