<div id="gamestate">
</div>
<div id="threads">
  <span>Next Image:</span><div id="nextimg"><div class="img-wrapper"></div></div>
  <span>Concept Number:</span> <input type="number" placeholder="concept number" id="threadid"/>
  <span>Sequence Number:</span> <input type="number" placeholder="image number" id="imagenum"/>
  <button id="commit">Commit The Image</button>
  <button id="reset">Reset Game</button>
</div>
<div id="board"></div>
.hidden {
  display: none;
}

body {
  background-color: #aaa;
}

#threads {
  height: 7em;
}

#nextimg {
  display: inline-block;
}

.img-wrapper {
  border: 1px solid black;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 4em;
  height: 4em;
  margin: .25em;
}

.main-img {
   max-width: 100%;
   max-height: 100%;
}

.row-img-wrapper {
  display: inline-flex;
}
var firebaseConfig = {
    apiKey: "AIzaSyBHcN0HVMwxxW-xBkXHYAm2X-kGWjxPzNk",
    authDomain: "basiccrud-ffe19.firebaseapp.com",
    databaseURL: "https://basiccrud-ffe19.firebaseio.com",
    projectId: "basiccrud-ffe19",
    storageBucket: "basiccrud-ffe19.appspot.com",
    messagingSenderId: "47974982638",
    appId: "1:47974982638:web:9a034202ca787ee47764ff"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);

let theGame = firebase.database().ref("cgameblue");
let gameState = {};
let selectedImage = -1;

theGame.on("value", ss=>{
  gameState = ss.val();
  if (!gameState){
    gameState = {};
    displayGame(gameState);
    return;
  }
  displayGame(gameState);
})

let pushGame = function(gameState){
  theGame.set(gameState);
}

let imageClickHandler = function(clickEvent){
  let clickedImageNumber = parseInt($(clickEvent.currentTarget).attr("data-val"));
  $("#nextimg").html(`<div class="img-wrapper"><img class="main-img" src="${makeURL(clickedImageNumber)}"/></div>`);
  selectedImage = clickedImageNumber;
}

let commitClickHandler = function(){
  let conceptNum = $("#threadid").val();
  let sequenceNum = $("#imagenum").val();
  let imageNum = selectedImage;
  if (!gameState.hasOwnProperty(conceptNum)){
    gameState[conceptNum] = {};
  }
  gameState[conceptNum][sequenceNum] = imageNum;
  pushGame(gameState);
  //selectedImage = -1;
}

let makeURL = function(imgID){
  return `https://prof.ninja/gameimages/${imgID}.png`
}

let initGame = function(){
  let i = 1;
  let imgs = [];
  for (i=1; i <= 118; i++){
    imgs.push(makeURL(i));
  }
  i =1;
  imgs.map(imgurl=>{
    $("#board").append(`
<div class="img-wrapper" data-val=${i}>
  <img class="main-img" src=${imgurl}>
</div>
`);
    i += 1;
  });
  
  $(".img-wrapper").on("click", imageClickHandler);
  $("#commit").on("click", commitClickHandler);
  $("#reset").on("click", function(){
    theGame.remove();
    displayGame({});
  })
}

let displayGame = function(gameObj){
  //gameObj has keys as ints, and those have picture numbers:
  let keys = Object.keys(gameObj);
  keys.sort();
  $("#gamestate").html("");
  keys.map(threadid=>{
    let rowid = `thread${threadid}`;
    $("#gamestate").append(`<div class="thread-row" id="${rowid}"><span class="thread-head">Thread #${threadid}</span></div>`);
    let imgseq = Object.keys(gameObj[threadid]);
    imgseq.sort();
    imgseq.map(seqid=>{
      $("#"+rowid).append(`<div class="row-img-wrapper"><div class="img-wrapper"><img class="main-img" src="${makeURL(parseInt(gameObj[threadid][seqid]))}"/></div></div>`);
    });
  });
  
  
}

initGame();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js
  2. https://www.gstatic.com/firebasejs/7.14.5/firebase-app.js
  3. https://www.gstatic.com/firebasejs/7.14.5/firebase-database.js