peteyboy
8fe95c88b6
-Fixed regext for black & white text squares (so it actually works out of Discord, _ not -) -Updated html template, fixing textareas so 2nd one didn't get squished for unknown reason. -Updated text in Template, still too wordy! -Fixed RLE to end on ! instead of $ which is why the next item wasn't working -Added a [[..]] section to end of generated RLE file to set generations per second, zoom, and colors to custom values to generally be better defaults.
407 lines
13 KiB
Perl
Executable File
407 lines
13 KiB
Perl
Executable File
#!/usr/pkg/bin/perl
|
|
#Above is the particular location for system binaries in SDF's metaarray, not the usual spot
|
|
use strict;
|
|
use warnings;
|
|
use utf8;
|
|
#add my user perl library path, this is particular to each person's setup
|
|
use lib qw( /usr/pkg/lib/perl5/5.24.0 /meta/p/peteyboy/perl5/lib/perl5 );
|
|
#make request for all of the following
|
|
use CGI::Tiny;
|
|
use Mojo::Template;
|
|
use Mojo::Loader 'data_section';
|
|
#use Routes::Tiny; #don't even need
|
|
use Readonly;
|
|
|
|
#===
|
|
# MAKE SURE ORIGIN PAGE MATCHES FILENAME (especially if you are testing changes)!
|
|
#
|
|
#===
|
|
my $ORIGIN_PAGE = "/wordle-life.cgi";
|
|
my $defaulttext = "Paste your wordle share here (replace this text)";
|
|
|
|
cgi {
|
|
|
|
#error handler from the CGI:Tiny cookbook
|
|
my $cgi = $_;
|
|
|
|
$cgi->set_error_handler(sub {
|
|
my ($cgi, $error, $rendered) = @_;
|
|
warn $error;
|
|
unless ($rendered) {
|
|
if ($cgi->response_status_code == 413) {
|
|
$cgi->render(json => {error => 'Request body limit exceeded'});
|
|
}elsif ($cgi->response_status_code == 400) {
|
|
$cgi->render(json => {error => 'Bad request'});
|
|
} else {
|
|
$cgi->render(json => {error => 'Internal server error'});
|
|
}
|
|
}
|
|
});
|
|
|
|
my $wordle;
|
|
my $method = $cgi->method;
|
|
my $rle = "";
|
|
|
|
#Simple switch: make a one page app, and always go back to the same page.
|
|
#GET or HEAD loads the page blank, POST runs the Life file maker
|
|
if ($method eq 'GET' or $method eq 'HEAD') {
|
|
$wordle = $defaulttext;
|
|
#$wordle = "";
|
|
} elsif ($method eq 'POST') {
|
|
#textarea name, pull the value from POST and reload into textarea
|
|
$wordle = $cgi->body_param('wordle-result');
|
|
|
|
#if input textarea not changed from default text, do nothing
|
|
unless ($wordle =~ /\Q$defaulttext\E/) {
|
|
#[Cc] /){ #cheat, if they put in something that looks like an RLE, pass output through
|
|
if ($wordle =~ /^#[Cc] /){
|
|
$rle = $wordle;
|
|
#if none of that, do the thing: generate RLE
|
|
}else{
|
|
$rle = generate_rle($wordle);
|
|
}
|
|
}
|
|
|
|
} else { #some other request? PUT, DELETE?
|
|
$cgi->set_response_status(405)->render;
|
|
exit;
|
|
}
|
|
|
|
die "Invalid wordle parameter" unless length $wordle;
|
|
|
|
#Load template from DATA section and output
|
|
my $mt = Mojo::Template->new(auto_escape => 1, vars => 1);
|
|
my $template = data_section __PACKAGE__, 'index.html.ep';
|
|
my $output = $mt->render($template, { ORIGIN_PAGE =>$ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle });
|
|
#my $output = $mt->render($template, {wordle => $wordle});
|
|
|
|
$cgi->render(html => $output );
|
|
|
|
};
|
|
|
|
#Try to Generate the RLE. Makes a lot of assumptions
|
|
sub generate_rle {
|
|
|
|
my $headline = "";
|
|
my $rleline;
|
|
my $rowcount;
|
|
my $myline;
|
|
|
|
Readonly my $headline_prefix => "#C "; #Part of RLE spec https://conwaylife.com/wiki/Run_Length_Encoded
|
|
Readonly my $row_prefix => "x = 5"; #for wordle always 5
|
|
Readonly my $col_prefix => ",y = ";
|
|
Readonly my $lifeviewer_settings => "\n[[\n GPS 3\n ZOOM 23\n COLOR ALIVE LIME\n COLOR BACKGROUND BLUE\n STOP 100\n GRID\n]]"; #Part of Viewer Spec
|
|
|
|
my $wordle = shift; # this is how you get variables in your function call!
|
|
$rowcount = 0;
|
|
|
|
my @lines = split /^/, $wordle;
|
|
foreach $myline (@lines) {
|
|
chomp($myline);
|
|
if ($headline eq "" && $myline =~ /Wordle/){
|
|
$headline = $headline_prefix . $myline;
|
|
}else{
|
|
|
|
#remove all line endings with magic perl identifier R
|
|
$myline =~ s/\R//;
|
|
$myline =~ s/^(.*)$/$1\$/;
|
|
#these replaces are logicless, so they need to be done in this order!
|
|
|
|
#in case of text mode (Discord)
|
|
$myline =~ s/:yellow_square:/o/g;
|
|
$myline =~ s/:green_square:/o/g;
|
|
$myline =~ s/:blue_square:/o/g; #HC equiv yellow
|
|
$myline =~ s/:orange_square:/o/g; #HC equiv green
|
|
|
|
|
|
$myline =~ s/:[a-z_]*square:/b/g;
|
|
# for normal unicode
|
|
$myline =~ s/\N{U+1f7e8}/o/g; #yellow hit
|
|
$myline =~ s/\N{U+1f7e9}/o/g; #green hit
|
|
$myline =~ s/\N{U+1F7E6}/o/g; #blue
|
|
$myline =~ s/\N{U+1F7E7}/o/g; #orange
|
|
|
|
|
|
$myline =~ s/\N{U+2B1B}/b/g; #black
|
|
$myline =~ s/\N{U+2B1C}/b/g; #white
|
|
|
|
#broken copy/paste text
|
|
$myline =~ s/black_large_square/b/g;
|
|
$myline =~ s/white_large_square/b/g;
|
|
$myline =~ s/yellow_square/o/g;
|
|
$myline =~ s/green_square/o/g;
|
|
$myline =~ s/blue_square/o/g;
|
|
$myline =~ s/orange_square/o/g;
|
|
|
|
|
|
|
|
#skip blank lines, count rows added
|
|
if(length($myline) > 1){
|
|
$rowcount += 1;
|
|
$rleline= $rleline . $myline;
|
|
}
|
|
}
|
|
}
|
|
#this is the format with b,o, and $. Done lazily because I don't compress the repeated b or o.
|
|
$rleline =~ s/\$$/\!/; #Correct termination of last line of RLE is !, not $, so replace it.
|
|
return "$headline\n$row_prefix$col_prefix$rowcount\n$rleline\n$lifeviewer_settings";
|
|
}
|
|
|
|
|
|
|
|
__DATA__
|
|
@@ index.html.ep
|
|
<html>
|
|
<head>
|
|
<title>Play Conway's Life with your Wordle Score</title>
|
|
|
|
<link rel="stylesheet" href="https://unpkg.com/some-nice-basic-css/global.css" />
|
|
|
|
<style>
|
|
.lv-rle{
|
|
min-height:140px;
|
|
}
|
|
</style>
|
|
<meta name="LifeViewer" content="viewer textarea"> <!--required tag-->
|
|
<script src="lv-plugin.js"></script>
|
|
|
|
</head>
|
|
|
|
<body><h1>Wordle->Life</h1>
|
|
|
|
|
|
<p><em>Play your Wordle Share score in <a href=https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life> Conway's Life!</a></em></p>
|
|
<p>
|
|
<p> Hey, nerds, isn't it funny how the Wordle Scores can look like a glider in that old computer programming exercise, Conway's Life?</p> <img src="https://conwaylife.com/w/images/e/e2/Lwss.png" alt="Glider image from Conwaylife.org, it looks like an 8-bit staple gun" align= float />
|
|
|
|
<ol>
|
|
<li>
|
|
<p> Paste your wordle share below and submit to convert it to a Conway's Life file so you can run it (to learn more about Conway's Life, read <a href=https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life> this)</a>.</p>
|
|
|
|
|
|
<form id="wordle-form" name="wordle-form" action="<%= $ORIGIN_PAGE =%>" method="POST" class="flow">
|
|
|
|
<label for="wordle">Wordle Share Chart:</label>
|
|
<textarea id="wordle" name="wordle-result" rows="9" cols="50" placeholder="<%= $defaulttext =%>" style="vertical-align: middle class="lv-rle"">
|
|
<%= $wordle %>
|
|
</textarea>
|
|
</p>
|
|
<br>
|
|
</li>
|
|
<li>
|
|
<p>Click "Submit" and an RLE format file made for Conway's Game of Life will appear in the box below and get loaded into the Life Viewer.</p>
|
|
<input type="submit" value="Submit">
|
|
|
|
</li>
|
|
<li>
|
|
<p>Watch your Wordle score play LIFE!</p>
|
|
<!--viewer container-->
|
|
<div class="viewer" class="flow">
|
|
<label for="wordle">
|
|
<p>If the conversion is successful, you should see your Wordle converted to a Run Length Encoded Conway Life file in this box:</p>
|
|
</label>
|
|
|
|
<textarea id="life" name="life-file" rows="9" cols="50" style="vertical-align: middle" class="lv-rle" class="flow">
|
|
<%= $rle %>
|
|
</textarea>
|
|
<p>If the RLE is correct, it should be loaded in the Life Viewer, and so you are ready to go!</p>
|
|
|
|
<ul>
|
|
<li><p>For best results with the Life Viewer, you may adjust the default Zoom and the playback speed, then press the Play button:</p>
|
|
<canvas height=400 width=400></canvas></li>
|
|
<li><p>Press "[Pause]" when it seems stable. </p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</li>
|
|
</ol>
|
|
<!--end viewer container-->
|
|
|
|
</form>
|
|
<p>
|
|
|
|
<p> This should work with the share/copy button in wordle, or copy/pasting your friends' wordles out of Discord or wherever as well. See whose Wordle Score runs the coolest!
|
|
|
|
<p>
|
|
<strong>If it doesn't seem to be working:</strong>
|
|
<ol>
|
|
<li><p> If there is extra text or lines in your paste, you might not get a valid file in the box above, so look and make sure it looks like a proper RLE file, for example:
|
|
<p>
|
|
<pre code>
|
|
#C Wordle 235 3/6
|
|
x = 5,y = 3
|
|
boobo$bobbo$ooooo!
|
|
|
|
[[GPS 3
|
|
ZOOM 23
|
|
COLOR ALIVE LIME
|
|
COLOR BACKGROUND BLUE
|
|
STOP 100
|
|
GRID
|
|
]]
|
|
|
|
|
|
</pre code>
|
|
|
|
<p>(the main thing that needs to be right are the first 3 lines. If the 3rd line has any : symbols, just try deleting them. The stuff between double brackets aren't part of the RLE but are comments that set some defaults for the Life Viewer)</p>
|
|
<p>For details about the Life RLE file format above, read <a href=https://conwaylife.com/wiki/Run_Length_Encoded>this</a>.</p>
|
|
|
|
</li>
|
|
|
|
<li>You can also copy the contents of the Conway Life box above and try it somewhere else:
|
|
<ol>
|
|
<li>go to a Conway's Life site, such as <a href= https://copy.sh/life/> this one at copy.sh</a> or <a href="https://lazyslug.com/lifeviewer/">this one at lazyslug.com</a> and load and run your file.</li>
|
|
<ol>
|
|
<li> specifically for the one at copy.sh:</li>
|
|
<li> Press the [Import] button at the top</li>
|
|
<li> paste in your Life file contents in the box and press [Import]</li>
|
|
<li> It will put up a box telling you it loaded your Wordle, press [OK]</li>
|
|
<li> Press the [Run] button and watch your Wordle score play LIFE!</li>
|
|
</ol>
|
|
</ol>
|
|
</ol>
|
|
|
|
<p>
|
|
|
|
|
|
<p>
|
|
<p>
|
|
|
|
<hr 100%>
|
|
<em>Disclaimer: I made this! People and/or corporations may own their marks or copyrights, etc, on words mentioned on this page I don't claim to</em>
|
|
|
|
<p>
|
|
Questions, kudos or comments, mail me @sdf.org
|
|
<p>
|
|
Thanks to the community at <a href="https://conwaylife.com">conwaylife.com</a>, and the friendly folks in the forums there,
|
|
and for their <a href="https://conwaylife.com/wiki/Tutorials/LifeViewer_JavaScript_plug-in">Javascript Life Viewer</a>, which I use here.
|
|
</p>
|
|
|
|
<p>
|
|
Thanks to <a href="https://github.com/hankchizljaw/some-nice-basic-css"> hankchizljaw</a> for making his basic css publicly available
|
|
</p>
|
|
<p> Made in February 2022</p>
|
|
<p>
|
|
<center>
|
|
Hosted by SDF.org
|
|
<p><a href="https://sdf.org"><img src=https://mab.sdf.org/sdfbanner.png alt="SDF.org"></a>
|
|
</center>
|
|
</body></html>
|
|
|
|
|
|
@@ viewer.html.ep
|
|
<html>
|
|
<head>
|
|
<title>Play Conway's Life with your Wordle Score</title>
|
|
|
|
<link rel="stylesheet" href="https://peteyboy.freeshell.org/air.css">
|
|
<meta name="LifeViewer" content="viewer textarea"> <!--required tag-->
|
|
<script src="lv-plugin.js"></script>
|
|
|
|
</head>
|
|
|
|
<body><h1>Wordle->Life</h1>
|
|
|
|
|
|
<p><em>Play your Wordle Share score in <a href=https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life> Conway's Life!</a></em></p>
|
|
<p>
|
|
<p> Hey, nerds, isn't it funny how the Wordle Scores can look like a glider in that old computer programming exercise, Conway's Life?</p> <img src="https://conwaylife.com/w/images/e/e2/Lwss.png" alt="Glider image from Conwaylife.org, it looks like an 8-bit staple gun" align= float />
|
|
|
|
<ol>
|
|
<li>
|
|
<p> Paste your wordle share below and submit to convert it to a Conway's Life file so you can run it.</p>
|
|
<p> To learn more about Conway's Life, read <a href=https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life> this</a>
|
|
</li>
|
|
|
|
<p>
|
|
|
|
|
|
<form id="wordle-form" name="wordle-form" action="<%= $ORIGIN_PAGE =%>" method="POST" class="flow">
|
|
|
|
<label for="wordle">Wordle Share Chart:</label>
|
|
<textarea id="wordle" name="wordle-result" rows="9" cols="50" placeholder="<%= $defaulttext =%>" style="vertical-align: middle; border:none;">
|
|
<%= $wordle %>
|
|
</textarea>
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<li>
|
|
<p>Click "Submit" and and RLE format file for Conway's Game of Life will appear below.</p>
|
|
<input type="submit" value="Submit">
|
|
</li>
|
|
</ol>
|
|
<label for="life">Your wordle as Conway Life RLE file:</label>
|
|
<textarea id="life" name="Life file" rows="9" cols="50" style="vertical-align: middle; border:none;">
|
|
<%= $rle %>
|
|
</textarea>
|
|
|
|
|
|
<!--viewer container-->
|
|
<div class="viewer" class="flow">
|
|
<div class="lv-buttons">
|
|
<button onclick="document.getElementById('life').innerHTML=''">Clear</button>
|
|
<button onclick="updateMe(this)">Show in Viewer</button>
|
|
<!--the element that calls updateMe must be in the viewer container-->
|
|
</div>
|
|
<canvas height=400 width=600></canvas>
|
|
</div>
|
|
|
|
<!--end viewer container-->
|
|
|
|
|
|
</form>
|
|
</div>
|
|
<p> if there is extra text or lines in your paste, you might not get a valid file here, so look and make sure it looks like a proper RLE file, for example:
|
|
<p>
|
|
<pre code>
|
|
#C Wordle 235 3/6
|
|
x = 5,y = 3
|
|
boobo$bobbo$ooooo$
|
|
</pre code>
|
|
|
|
<p>For details about the Life RLE file format above, read <a href=https://conwaylife.com/wiki/Run_Length_Encoded>this</a>.
|
|
|
|
<p>
|
|
<strong>Next steps:</strong>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- not embedded -->
|
|
|
|
<ol>
|
|
<li>copy the contents of the Conway Life box above
|
|
<li>go to a Conway's Life site, such as <a href= https://copy.sh/life/> this one at copy.sh</a> or <a href="https://lazyslug.com/lifeviewer/">this one at lazyslug.com</a> and load and run your file.</li>
|
|
<ol>
|
|
<li> specifically for the one at copy.sh:</li>
|
|
<li> Press the [Import] button at the top</li>
|
|
<li> paste in your Life file contents in the box and press [Import]</li>
|
|
<li> It will put up a box telling you it loaded your Wordle, press [OK]</li>
|
|
<li> Press the [Run] button and watch your Wordle score play LIFE!</li>
|
|
</ol>
|
|
</ol>
|
|
<p> This should work with the share/copy button in wordle, or copy/pasting your friends' wordles out of Discord or wherever as well. See whose Wordle Score looks coolest!
|
|
<p>
|
|
|
|
|
|
<p>
|
|
<p>
|
|
|
|
<hr 100%>
|
|
<em>Disclaimer: I made this! People and/or corporations may own their marks or copyrights, etc, on words mentioned on this page I don't claim to</em>
|
|
|
|
<p>
|
|
Questions, kudos or comments, mail me @sdf.org
|
|
<p>
|
|
Thanks to <a href="https://github.com/hankchizljaw/some-nice-basic-css"> hankchizljaw</a> for making his basic css publicly available
|
|
|
|
<p> Made in February 2022
|
|
<p>
|
|
<center>
|
|
Hosted by SDF.org
|
|
<p><a href="https://sdf.org"><img src=https://mab.sdf.org/sdfbanner.png alt="SDF.org"></a>
|
|
</center>
|
|
</body></html>
|