Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: using perl to find words for scrabble -- further suggestions

by Discipulus (Canon)
on Sep 05, 2019 at 08:39 UTC ( [id://11105648]=note: print w/replies, xml ) Need Help??


in reply to using perl to find words for scrabble

hello Aldebaran,

I'd go on my own because will be fun and a nice chance to improve your perl skills ;)

My suggestions are:

0) use strict; use warnings; (also dump from Data::Dump does not need a reference as Data::Dumper do)

1) Sort the results by their score. This its easy and a hash with characters scores will be enough:

use strict; use warnings; use Data::Dump; my %values; map{ $values{$_} = 1} qw(e a i o n r t l s u); map{ $values{$_} = 2} qw(d g); map{ $values{$_} = 3} qw(b c m p); map{ $values{$_} = 4} qw(f h v w y); map{ $values{$_} = 5} qw(k); map{ $values{$_} = 8} qw(j x); map{ $values{$_} = 10} qw(q z); # result words from tybalt89 example my @result_words = qw(along gall gallon goal hall halo halon hang hoga +n llano loan loll long); my %scores = words_values(@result_words); foreach my $word ( sort{ $scores{$b} <=> $scores{$a} } keys %scores ){ print "$word\tscore:\t$scores{$word}\n"; } sub words_values{ my @words = @_; my %scores = map { my $word = $_; my @chars = split '', $word; my $score; $score += $values{$_} for @chars; $word => $score; } @words; return %scores; } __DATA__ hogan score: 9 hang score: 8 halon score: 8 halo score: 7 gallon score: 7 hall score: 7 along score: 6 llano score: 5 goal score: 5 gall score: 5 long score: 5 loll score: 4 loan score: 4

2) Scrabble is a board made of squares, so rows and columns, so it is an ArrayOfArrays. You can represent the empty board like:

my @board = map{ [('.') x 15] } 0..14 ; print "Empty board:\n"; foreach my $row(@board){ foreach my $col( @$row ){ print $col; } print "\n"; } __DATA__ Empty board: ............... ............... ............... ............... ............... ............... ............... ............... ............... ............... ............... ............... ............... ............... ...............

3) but the board has value modifiers for letters and for words too. You can build distinct AoA to hold these modifiers (initializing default to 1) like in my @board_letter_mod = map{ [('1') x 15]  } 0..14 ; adding by hand modifiers like in $board_letter_mod[0][3] = 3;

Board letter modifiers( just one.. ): 111311111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111 111111111111111

You can do the very same for @board_word_mod adding $board_word_mod[0][0] = 3; but..

4) You are storing many informations for each tile in distinct structures! why do not stores them in just one structure? You can build an ArrayOfHashes intializing default values

my @board; foreach my $row(0..14){ foreach my $col( 0..14 ){ $board[$row][$col] = { letter => '.', lett_mod => 1, word_mod +=> 1}; } } __DATA__ # will result in (first row) ( [ { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, { lett_mod => 1, letter => ".", word_mod => 1 }, ], ...

5) now the fun starts.. ;) You can simply modify the score based on the position on the board, computing both letter and word modifiers. But also words have to be put on the board using already present tiles. This will be difficult (but fun!): you have to consider many factors to achieve this correctly. I'd leave apart the possibility to form more than one word (valid in scrabble) because will be too complex (tybalt89 are you there? ;).

One possible approach can be to scan the board's letters horizontally and vertically to count how many free spaces there are before and after that letter. You can now select all valid words using your own tiles and the letter already present, selecting only valid words and words that fit in empty tiles. Letters can be in reverse order too.. good luck!

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11105648]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (10)
As of 2024-03-28 12:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found