The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Game::WordBrain - Solver for the Mobile App "WordBrain"

SYNOPSIS

    # Create a new Game::WordBrain
    my @letters;
    push @letters, Game::WordBrain::Letter->new({ letter => 't', row => 0, col => 0 });
    push @letters, Game::WordBrain::Letter->new({ letter => 'a', row => 0, col => 1 });
    push @letters, Game::WordBrain::Letter->new({ letter => 'l', row => 1, col => 0 });
    push @letters, Game::WordBrain::Letter->new({ letter => 'k', row => 1, col => 1 });

    my $words_to_find = [ Game::WordBrain::WordToFind->... ];
    my $speller       = Game::WordBrain::Speller->...;
    my $prefix        = Game::WordBrain::Prefix->...;

    my $game = Game::WordBrain->new({
        letters       => \@letters,
        words_to_find => $words_to_find,
        speller       => $speller,       # optional
        prefix        => $prefix,        # optional
    });

    # Solve a Game
    $game->solve();
    print "Number of Solutions Found: " . ( scalar @{ $game->{solutions} } ) . "\n";

    # Construct a game without a word
    my $already_used_word = Game::WordBrain::Word->...;
    my $sub_game = $game->construct_game_without_word( $already_used_word  );

    # Get letter at position
    my $letter = $game->get_letter_at_position({
        row => 2,
        col => 3,
    });


    # Find Near letters
    my $near_letters = $game->find_near_letters({
        used       => [ Game::WordBrain::Letter->... ],
        row_number => 1,
        col_number => 1,
    });


    # Find Near Words
    my $near_words = $game->find_near_words({
        letter          => WordBrain::Letter->...,
        used            => [ ],   # Optional
        max_word_length => 5,     # Optional
    });

DESCRIPTION

Game::WordBrain is a solver created to generation potential solutions for Mag Interactive's WordBrain. WordBrain is available for:

iOS
Android

This module is currently functional for simple games ( 4x4 and less ) but it requires SIGNIFICANT time to process larger ones. Feel free to propose improvements at the GitHub for this repo!

If you are new to WordBrain or simply want a jumpstart on how this module works and it's limitations (and evolution) please see:

YAPC::2016 Presentation on YouTube - "Solving WordBrain - A Depth First Search of a Problem Of Great Breadth"
Presentation Slides

ATTRIBUTES

letters

ArrayRef of Game::WordBrain::Letters that comprise the game field

words_to_find

ArrayRef of Game::WordBrain::WordToFinds that indicate the number of words to find as well as the length of each word.

speller

An instance of Game::WordBrain::Speller that is used to spell check potential words.

If this is not provided it will be automagically built. You generally do not need to provide this but if you wish to use something other than the provided wordlist creating your own Game::WordBrain::Speller and providing it in the call to new would be how to accomplish that.

prefix

An instance of Game::WordBrain::Prefix used to speed up game play.

If not provided, the max word_to_find will be detected and used to construct it. You generally do not need to provide this but if you wish to use something other than the provided wordlist creating your own Game::WordBrain::Prefix and providing it in the call to new would be how to accomplish that.

solutions

Generated after a call to ->solve has been made. This is an ArrayRef of Game::WordBrain::Solutions.

METHODS

new

    my $letters       = [ Game::WordBrain::Letter->... ];
    my $words_to_find = [ Game::WordBrain::WordToFind->... ];
    my $speller       = Game::WordBrain::Speller->...;
    my $prefix        = Game::WordBrain::Prefix->...;

    my $game = Game::WordBrain->new({
        letters       => $letters,
        words_to_find => $words_to_find,
        speller       => $speller,       # optional
        prefix        => $prefix,        # optional
    });

Given an ArrayRef of Game::WordBrain::Letters, an ArrayRef of Game::WordBrain::WordToFind, and optionally an instance of Game::WordBrain::Speller and Game::WordBrain::Prefix constructs and returns a new WordBrain game.

NOTE While it is also possible to pass solutions => [ Game::WordBrain::Solution->...], there is really no reason for a consumer to do so.

solve

    my @letters;
    push @letters, WordBrain::Letter->new({ letter => 't', row => 0, col => 0 });
    push @letters, WordBrain::Letter->new({ letter => 'a', row => 0, col => 1 });
    push @letters, WordBrain::Letter->new({ letter => 'l', row => 1, col => 0 });
    push @letters, WordBrain::Letter->new({ letter => 'k', row => 1, col => 1 });

    my @words_to_find;
    push @words_to_find, WordBrain::WordToFind->new({ num_letters => 4 });

    my $game = Game::WordBrain->new({
        letters       => \@letters,
        words_to_find => \@words_to_find,
    });

    $game->solve();

    print "Number of Solutions Found: " . ( scalar @{ $game->{solutions} } ) . "\n";

The solve method is the real meat of Game::WordBrain. When called on a fully formed game this method will enumerate potential solutions and set the $game->{solutions} attribute.

NOTE Depending on the size of the game grid, this method can take a very long time to run.

construct_game_without_word

    my $word = Game::WordBrain::Word->...;
    my $game = Game::WordBrain->...;

    my $sub_game = $game->construct_game_without_word( $word );

In WordBrain, once a word is matched the letters for it are removed from the playing field, causing all other letters to shift down (think of it like gravity pulling the letters straight down). This method exists to simplify the process of generating a new instance of a Game::WordBrain from an existing instance minus the found word.

There really isn't a reason for a consumer to call this method directly, rather it is used by the solve method during solution enumeration.

get_letter_at_position

    my $game = Game::WordBrain->...
    my $letter = $game->get_letter_at_position({
        row => 2,
        col => 3,
    });

Simple convenience method to retrieve the instance of Game::WordBrain::Letter at a given row and col.

find_near_letters

    my $game = Game::WordBrain->...
    my $near_letters = $game->find_near_letters({
        used       => [ Game::WordBrain::Letter->... ],
        row_number => 1,
        col_number => 1,
    });

Given an ArrayRef of already used (for other words) Game::WordBrain::Letters, and the row and col number of a position, returns an ArrayRef of Game::WordBrain::Letters that are "near" the specified position. By "near" we mean a letter that is touching the specified position in one of the 8 cardinal directions and has not already been used.

find_near_words

    my $game = Game::WordBrain->...;
    my $near_words = $game->find_near_words({
        letter          => WordBrain::Letter->...,
        used            => [ ],   # Optional
        max_word_length => 5,     # Optional
    });

Similiar to find_near_letters, but returns an ArrayRef of Game::WordBrain::Words that can be constructed from the given Game::WordBrain::Letter, ArrayRef of used Game::WordBrain::Letters and the max_word_length that should be searched for ( this should be the max Game::WordBrain::WordToFind->{num_letters} ).

AUTHORS

Robert Stone, <drzigman AT cpan DOT org >

CONTRIBUTORS

Special thanks to the following individuals who submitted bug reports, performance ideas, and/or pull requests.

Todd Rinaldo
Mohammad S Anwar mohammad.anwar@yahoo.com

ACKNOWLEDGMENTS

Special thanks to BrainStorm Incubator for funding the development of this module and providing test resources.

Further thanks to Houston Perl Mongers for providing input and ideas for improvement.

COPYRIGHT & LICENSE

Copyright 2016 Robert Stone

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU Lesser General Public License as published by the Free Software Foundation; or any compatible license.

See http://dev.perl.org/licenses/ for more information.