From 25f65f212c210638d15d73c0c8dfe1fc08bd96a2 Mon Sep 17 00:00:00 2001 From: Andinus Date: Wed, 12 Jan 2022 12:42:38 +0530 Subject: Add visualize feature using Cairo This takes parts from Fornax: https://github.com/andinus/fornax Each step is visualized and a video solution is generated. --- lib/Octans/CLI.rakumod | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'lib/Octans/CLI.rakumod') diff --git a/lib/Octans/CLI.rakumod b/lib/Octans/CLI.rakumod index f3501df..4d94b69 100644 --- a/lib/Octans/CLI.rakumod +++ b/lib/Octans/CLI.rakumod @@ -1,6 +1,7 @@ use Octans::Puzzle; use Octans::WordSearch; use Octans::Puzzle::Get; +use Octans::GenerateFrame; proto MAIN(|) is export { unless so @*ARGS { say $*USAGE; exit }; {*} } @@ -9,6 +10,7 @@ multi sub MAIN( Str :$dict = (%?RESOURCES // "/usr/share/dict/words").Str, #= dictionary file Int :$length = 7, #= minimum word length (default: 7) + Bool :$visualize, #= produces a video output Bool :$verbose, #= increase verbosity ) is export { # @dict holds the sorted dictionary. Only consider words >= 7 @@ -31,18 +33,40 @@ multi sub MAIN( " $_".say for $puzzle.grids; } + constant $SIDE = 128; + my Int %meta = :rows($puzzle.grids.elems), :cols($puzzle.grids[0].elems); + my Int %canvas = :width(%meta * $SIDE), :height(%meta * $SIDE); + + my IO() $output = "%s/octans-%s".sprintf( + '/tmp', ('a'...'z', 'A'...'Z', 0...9).roll(8).join + ); + if $visualize { + mkdir $output; + put "Output: $output"; + die "Output directory doesn't exist" unless $output.d; + } + + my Int $iter = 0; # start-pos block loops over each starting position. start-pos: for $puzzle.gray-squares -> $pos { # gather all the words that word-search finds starting from # $pos. word: for gather word-search( - @dict, $puzzle.grids, $pos[0], $pos[1], + @dict, $puzzle.grids, $pos[0], $pos[1], :visualize ) -> ( # word-search returns the word along with @visited which # holds the list of all grids that were visited when the # word was found. $word, @visited ) { + if $visualize { + generate-frame( + :%canvas, :side($SIDE), :puzzle($puzzle.grids), :@visited, :%meta, + :out("%s/%08d.png".sprintf: $output, $iter++), :found($word ne "") + ); + next word; + } + printf "%s$word\n", $verbose ?? "\n" !! ""; next word unless so $verbose; @@ -61,6 +85,14 @@ multi sub MAIN( } } } + + if $visualize { + put "Creating a slideshow."; + my Str $log-level = $verbose ?? "info" !! "error"; + run «ffmpeg -loglevel "$log-level" -r 1.5 -i "$output/\%08d.png" + -vf 'tpad=stop_mode=clone:stop_duration=1' + -vcodec libx264 -crf 24 -pix_fmt yuv420p "$output/solution.mp4"»; + } } multi sub MAIN( -- cgit 1.4.1-2-gfad0