On almost every page in the Stack Exchange Network, there lives a list of some the current "hot" questions across the network (sometimes abbreviated HNQs). Some of these posts have very exotic titles (especially the ones from Arqade) and some have very simple titles.
Either way, I've always found it fun to try and guess what site an question title is associated with. As a result, I created a UserScript that plants this game into a Stack Exchange webpage.
// ==UserScript==
// @name Hot Question Game
// @namespace https://github.com/SirPython/Hot-Postato
// @version 0.1
// @description A Stack Exchange mini game
// @author SirPython
// @match *://*.stackexchange.com/*
// @match *://*.stackoverflow.com/*
// @match *://*.superuser.com/*
// @match *://*.serverfault.com/*
// @match *://*.askubuntu.com/*
// @match *://*.stackapps.com/*
// @match *://*.mathoverflow.net/*
// @grant none
// ==/UserScript==
/* jshint -W097 */
'use strict';
/* Place a button that says "play" right next to "help" in the top-left */
var button = createTopbarButton();
var topbar = document.getElementsByClassName("topbar-menu-links")[0];
topbar.appendChild(button);
var questions = getHNQuestions();
/**
* Play a single round of the guessing game. If the user wishes to
* play again, they can click the play button again.
*/
function play() {
do {
var toGuess = questions[Math.floor(Math.random() * questions.length - 1)];
var guess = prompt(toGuess.title);
/* Case-insensitive string checking */
if(!new RegExp(guess, "i").test(toGuess.site)) {
alert("Incorrect! The answer is...\n" + toGuess.site);
} else {
alert("Correct!");
}
} while(confirm("Play again?"));
}
/**
* Represents a single question in the HNQ list.
*/
function HNQuestion(site, title) {
this.site = site;
this.title = title;
}
/**
* Gets all the questions in the HNQ list and returns them as
* an array of HNQuestions
*/
function getHNQuestions() {
var questionElements = document.getElementById("hot-network-questions").children[1].children;
var questions = [];
for(var i = 0; i < questionElements.length; i++) {
var site = questionElements[i].children[0].title;
var title= questionElements[i].children[1].innerHTML;
site = site.replace(" Stack Exchange", "");
questions.push(new HNQuestion(site, title));
}
return questions;
}
/**
* Initializes the top bar button to be placed on the top bar.
*/
function createTopbarButton() {
var button = document.createElement("a");
button.href = "#";
button.onclick = play;
button.innerHTML = "play";
return button;
}
The game plays out like this:
- The user clicks the "play" button in the top right corner.
- A prompt pops up with a question title in the center of it. This question title is one of the HNQ titles listed on the side.
- The user then tries to guess which SE site this question is coming from by typing in its name.
- The user is told whether or not they were correct and they are asked if they want to play again.
The source code can be found on GitHub and you can download the extension here.
This was meant as a small project for fun, but I still have a few questions.
Is my game design okay? I'm not that familiar with game programming, and although this is hardly a game, I am still curious about code design. Is the idea of having this single
play
function good? Is there anything else?Is my "play" button initialization okay? I've always done it this way for UserScripts that need edit the existing webpage with new, flowing content, but I don't know if this is good practice. Did I split up the functions that accomplish this well?
I have quite a few global variables, and even one that is constantly used (
questions
). Is this sort of practice okay for UserScripts/games in JavaScript? Even if this may suffice for a simple game such as this, would it suffice for other, large games but in a similar context?Are there any inefficiencies in my code, specifically around the DOM traversing and element creation?
How's my design? I know; the
alert
s andprompt
s look terrible, but I couldn't quite think of anything else. Perhaps there are better ways I could be utilizing the pre-existing webpage overall?The UserScript header was pre-generated by Tampermonkey, so I'm not really concerned about practices in that area. However, how are my UserScript practices in other areas?
Don't feel the need to answer all of these in an answer. Any other recommendations are also appreciated.