Skip to content

Instantly share code, notes, and snippets.

@cameronism
Created September 30, 2020 00:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cameronism/ec77823dd65019ea3e64f56b6a2c69f2 to your computer and use it in GitHub Desktop.
Save cameronism/ec77823dd65019ea3e64f56b6a2c69f2 to your computer and use it in GitHub Desktop.
Super Mario Maker 2 Bingo
<div>
<h1>Super Mario Maker <em>2</em> Bingo</h1>
<table></table>
<fieldset>
<legend>Options</legend>
<textarea rows=24></textarea>
<label>Seed <input type=number></label>
<button class=run>Let's Go</button>
<button class=reset>Start Over</button>
</fieldset>
</div>
function toggle(e) {
$(e.target).toggleClass("clicked");
}
function shuffle(a, r: Rand) {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(r.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
}
// adapted from https://stackoverflow.com/a/19301306
class Rand {
m_w = 123456789;
m_z = 987654321;
mask = 0xffffffff;
// seed
constructor(i: number) {
this.m_w = (123456789 + i) & this.mask;
this.m_z = (987654321 - i) & this.mask;
}
// Returns number between 0 (inclusive) and 1.0 (exclusive),
// just like Math.random().
random() {
this.m_z = (36969 * (this.m_z & 65535) + (this.m_z >> 16)) & this.mask;
this.m_w = (18000 * (this.m_w & 65535) + (this.m_w >> 16)) & this.mask;
let result = ((this.m_z << 16) + (this.m_w & 65535)) >>> 0;
result /= 4294967296;
return result;
}
}
function run(e) {
let goals = [
"ENEMY SPAM",
"SOUND EFFECTS EVERYWHERE",
"BRING YOSHI TO THE GOAL",
"TECH LEVEL",
"PICK A DOOR / PIPE",
"1-1 REMAKE",
"COLLECT ALL COINS",
"MUSIC LEVEL",
"SOFTLOCK WITH NO WAY OF DYING",
"INFINITE FIRE FLOWER BOSS FIGHT",
"NO CHECKPOINTS (WITHOUT CLEAR CONDITION)",
"ENEMY SPAM (WITH STAR)",
"GOOD LEVEL",
"BUILDER SUPERBALL LEVEL",
"THEMED AFTER ANOTHER GAME",
"KAIZO BLOCKS",
"LEVEL CAN BE CHEESED",
"AUTO MARIO LEVEL",
'"FIRST LEVEL" IN TITLE',
"MEOWSER OR BOOM-BOOM",
"TITLE LEVEL",
"TERRIBLY NAMED LEVEL",
"KILLS MARIO AT THE START",
"ON/OFF BLOCKS"
];
// read custom goals
const rel = e && e.target && e.target.className;
if (rel === "run") {
const text = $("textarea")
.val()
.split("\n")
.reduce((lines, line) => {
line = line.trim();
if (line) {
lines.push(line);
}
return lines;
}, []);
while (text.length < 24) {
text.push(goals.shift());
}
text.length = 24;
goals = text;
}
goals.sort();
const seed = parseInt($("input").val(), 10);
shuffle(goals, new Rand(isFinite(seed) ? seed : 0));
$("textarea").val(goals.join("\n"));
goals.splice(12, 0, null);
const tbody = $("table").empty();
let tr = null;
for (let i = 0; i < goals.length; i++) {
if (!tr) {
tr = $("<tr>").appendTo(tbody);
}
const goal = goals[i];
const td = $("<td>")
.text(goal || "FREE")
.toggleClass("free", !goal)
.click(toggle)
.appendTo(tr);
if ((i + 1) % 5 == 0) {
tr = null;
}
}
}
// on ready
$("button").click(run);
$("legend").click(() => $("fieldset").toggleClass("hide"));
$("input").val(Date.now() % 1000);
run();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
html, body {
background-color: #fdeb01;
color: #131002;
font-weight: bold;
font-family: Arial, Helvetica, sans-serif;
text-transform: uppercase;
}
button, label {
display: block;
margin: 16px 0;
}
h1 {
margin-top: 0;
}
em {
color: #de0013;
font-style: normal;
font-size: 200%;
}
div {
display: inline-block;
text-align: center;
}
fieldset, td {
border: 1px solid #000;
}
fieldset {
margin-top: 32px;
border-width: 1px 0 0;
text-align: left;
}
textarea {
width: 100%;
}
table {
border-collapse: collapse;
}
td {
width: 128px;
height: 128px;
background-color: #fdfcc6;
text-align: center;
padding: 2px;
}
.free {
background-color: #fdfdfd;
}
.clicked {
background-color: #51bd46;
}
.hide * {
display: none;
}
.hide legend {
display: block;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment