JSFiddle - React, Tailwind, and code Playground

by MrHen

HTML

<h1>Widgets: <span id="widget-count">0</span></h1>

<button id="produce-widget">Produce Widget</button>

<h2>Store:</h2>

<button id="novice-widgeteer">Hire Novice Widgeteer</button>
<button id="master-widgeteer">Hire Master Widgeteer</button>
<button id="wisened-widgeteer">Hire Master Widgeteer</button>

<h2>Coding exercises:</h2>

<ul>
    <li>Change the starting costs and see how it affects the game</li>
    <li>Add two more levels of widgeteers</li>
    <li>Add stats near the top showing widgets per second and the number of widgeteers of each type</li>
    <li>Add an upgrades section</li>
    <li>Add save/load buttons that use localStorage.setItem() and localStorage.getItem()</li>
    <li>Check the Bootstrap 3 checkbox in the upper left and change the &lt;button&gt; elements to use &lt;div class="btn btn-primary"&gt; instead</li>
</ul>

JavaScript

// Basic variable declaration - keep track of how many of each
// item we currently own, and how much the new ones should cost.
var numWidgets = 0;
var numNoviceWidgeteers = 0;
var numMasterWidgeteers = 0;
var noviceWidgeteerCost = 10;
var masterWidgeteerCost = 25;

var costScaling = 1.1;

var widgeteers = {
    "novice-widgeteer": {
        "label": "Hire Novice Widgeteer",
            "cost": 10,
            "value": 1,
            "owned": 0,
    },
        "master-widgeteer": {
        "label": "Hire Master Widgeteer",
            "cost": 25,
            "value": 5,
            "owned": 0,
    },
        "wisened-widgeteer": {
        "label": "Hire Wisened Widgeteer",
            "cost": 100,
            "value": 10,
            "owned": 0,
    },
};

// Increase numWidgets every time produce-widget is clicked
$('#produce-widget').on('click', function () {
    numWidgets++;
});

// Same for novice-widgeteer
$('#novice-widgeteer').on('click', function () {
    var widgeteer = widgeteers["novice-widgeteer"];
    widgeteer.owned++;

    // Deduct cost
    numWidgets -= widgeteer.cost;

    // Increase cost for the next one, using Math.ceil() to round up
    widgeteer.cost = Math.ceil(widgeteer.cost * costScaling);
});

// Ditto for master-widgeteer... you get the idea
$('#master-widgeteer').on('click', function () {
    var widgeteer = widgeteers["master-widgeteer"];
    widgeteer.owned++;
    numWidgets -= widgeteer.cost;
    widgeteer.cost = Math.ceil(widgeteer.cost * costScaling);
});

$('#wisened-widgeteer').on('click', function () {
    var widgeteer = widgeteers["wisened-widgeteer"];
    widgeteer.owned++;
    numWidgets -= widgeteer.cost;
    widgeteer.cost = Math.ceil(widgeteer.cost * costScaling);
});

// Run UI update code every 10ms
window.setInterval(function () {
    // Novices add 1 per second (1/100 every 10ms)
    // Masters add 5 per second (5/100 every 10ms)
    for (var name in widgeteers) {
        numWidgets += (widgeteers[name].owned *...