<!DOCTYPE html>
<meta charset="utf-8">

<body>

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
    <style>
      .container {
        display: inline-block;
        float: left;
        width: 60px;
      }
      
      #status {
        display: block;
        height: 48px;
        background-color: #307FBE;
        font-family: arial;
        color: #FFFFFF;
        font-size: 30px;
        font-weight: bold;
        padding: 20px 0px 34px 0px;
        text-align: center;
      }
      
      #nav {
        float: left;
      }
      
      #scoreBoard {
        font-family: arial;
        font-size: .8em;
        font-weight: normal;
      }
    </style>
  </head>
  <div id="status">Ready Player One</div>
  <div id="scoreBoard">Score: 00</div>
  <script>
    //circle details
    var totalCircles = 2, //number of circles to draw
      radius = 30, //size
      colorSteps = 1, //number of colors to include, up to 20
      padding = 4; //spacing between each circle

    //interactive area dimensions
    var width = 600,
      height = 400,
      i = 0,
      k = 1,
      p = 0,
      max = totalCircles + 1,
      min = 1,
      a,
      hot = Math.floor(Math.random() * (max - min)) + min,
      level = 1,
      score = 0;

    function step() {
      p++;
      return p;
    };

    var nodes = d3.range(totalCircles + 1).map(function() {
        return {
          radius
        };
      }),
      root = nodes[0],
      color = d3.scale.category20();

    root.radius = 0;
    root.fixed = true;

    var force = d3.layout.force()
      .gravity(.1)
      .charge(function(d, i) {
        return i ? 0 : -1000;
      })
      .nodes(nodes)
      .size([width, height]);

    force.start();

    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);

    svg.selectAll("circle")
      .data(nodes.slice(1))
      .enter().append("circle")
      .attr("r", function(d) {
        return d.radius;
      })

    .attr("data-sequence", function() {
      return step()
    })

    .call(force.drag)
      .on("click", click)
      .style("fill", function(d, i) {
        return color(i % colorSteps);
      });

    force.on("tick", function(e) {
      var q = d3.geom.quadtree(nodes),
        i = 0,
        n = nodes.length;

      while (++i < n) q.visit(collide(nodes[i]));

      svg.selectAll("circle")
        .attr("cx", function(d) {
          return d.x;
        })
        .attr("cy", function(d) {
          return d.y;
        });
    });


    function collide(node) {
      var r = node.radius + (padding),
        nx1 = node.x - r,
        nx2 = node.x + r,
        ny1 = node.y - r,
        ny2 = node.y + r;
      return function(quad, x1, y1, x2, y2) {
        if (quad.point && (quad.point !== node)) {
          var x = node.x - quad.point.x,
            y = node.y - quad.point.y,
            l = Math.sqrt(x * x + y * y),
            r = node.radius + quad.point.radius + (padding);
          if (l < r) {
            l = (l - r) / l * .5;
            node.x -= x *= l;
            node.y -= y *= l;
            quad.point.x += x;
            quad.point.y += y;
          }
        }
        return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
      };
    }


    function click() {
      if (this.getAttribute("data-sequence") == hot) {
        d3.select(this).transition()
          .duration(200)
          .attr("r", 26)
          .style("fill", "green"),
          score++,
          document.getElementById("scoreBoard").innerHTML = "Score " + score,
          next()
      } else {
        d3.select(this).transition()
          .duration(200)
          .attr("r", 26)
          .style("fill", "red"),
          over()
      }
    }

    function next() {
      document.getElementById("status").innerHTML = "Correct!"
    }

    function over() {
      document.getElementById("status").innerHTML = "Game Over"
    }



    function proceed() {

      d3.select("svg")
        .remove();

      level++;
      totalCircles++;
      document.getElementById("status").innerHTML = "Level " + level;

      //interactive area dimensions
      var width = 600,
        height = 400,
        i = 0,
        k = 1,
        p = 0,
        max = totalCircles + 1,
        min = 1,
        a,
        hot = Math.floor(Math.random() * (max - min)) + min;

      function step() {
        p++;
        return p;
      };

      var nodes = d3.range(totalCircles + 1).map(function() {
          return {
            radius
          };
        }),
        root = nodes[0],
        color = d3.scale.category20();

      root.radius = 0;
      root.fixed = true;

      var force = d3.layout.force()
        .gravity(.1)
        .charge(function(d, i) {
          return i ? 0 : -1000;
        })
        .nodes(nodes)
        .size([width, height]);

      force.start();

      var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);

      svg.selectAll("circle")
        .data(nodes.slice(1))
        .enter().append("circle")
        .attr("r", function(d) {
          return d.radius;
        })

      .attr("data-sequence", function() {
        return step()
      })

      .call(force.drag)
        .on("click", click)
        .style("fill", function(d, i) {
          return color(i % colorSteps);
        });

      force.on("tick", function(e) {
        var q = d3.geom.quadtree(nodes),
          i = 0,
          n = nodes.length;

        while (++i < n) q.visit(collide(nodes[i]));

        svg.selectAll("circle")
          .attr("cx", function(d) {
            return d.x;
          })
          .attr("cy", function(d) {
            return d.y;
          });
      });


      function collide(node) {
        var r = node.radius + (padding),
          nx1 = node.x - r,
          nx2 = node.x + r,
          ny1 = node.y - r,
          ny2 = node.y + r;
        return function(quad, x1, y1, x2, y2) {
          if (quad.point && (quad.point !== node)) {
            var x = node.x - quad.point.x,
              y = node.y - quad.point.y,
              l = Math.sqrt(x * x + y * y),
              r = node.radius + quad.point.radius + (padding);
            if (l < r) {
              l = (l - r) / l * .5;
              node.x -= x *= l;
              node.y -= y *= l;
              quad.point.x += x;
              quad.point.y += y;
            }
          }
          return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
        };
      }


      function click() {
        if (this.getAttribute("data-sequence") == hot) {
          d3.select(this).transition()
            .duration(200)
            .attr("r", 26)
            .style("fill", "green"),
            score++,
            document.getElementById("scoreBoard").innerHTML = "Score " + score,
            setTimeout(proceed, 1000);
        } else {
          d3.select(this).transition()
            .duration(200)
            .attr("r", 26)
            .style("fill", "red"),
            over()
        }
      }

      function next() {
        document.getElementById("status").innerHTML = "Correct!"
      }

      function over() {
        document.getElementById("status").innerHTML = "Game Over"
      }
    }

    function reset() {

      d3.select("svg")
        .remove();
      document.getElementById("status").innerHTML = "Level 1"
      document.getElementById("scoreBoard").innerHTML = "Score: 00"

      score = 0,
        totalCircles = 2, //number of circles to draw
        radius = 30, //size
        colorSteps = 1, //number of colors to include, up to 20
        padding = 4, //spacing between each circle
        level = 1;

      //interactive area dimensions
      var width = 600,
        height = 400,
        i = 0,
        k = 1,
        p = 0,
        max = totalCircles + 1,
        min = 1,
        a,
        hot = Math.floor(Math.random() * (max - min)) + min;


      function step() {
        p++;
        return p;
      };

      var nodes = d3.range(totalCircles + 1).map(function() {
          return {
            radius
          };
        }),
        root = nodes[0],
        color = d3.scale.category20();

      root.radius = 0;
      root.fixed = true;

      var force = d3.layout.force()
        .gravity(.1)
        .charge(function(d, i) {
          return i ? 0 : -1000;
        })
        .nodes(nodes)
        .size([width, height]);

      force.start();

      var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);

      svg.selectAll("circle")
        .data(nodes.slice(1))
        .enter().append("circle")
        .attr("r", function(d) {
          return d.radius;
        })

      .attr("data-sequence", function() {
        return step()
      })

      .call(force.drag)
        .on("click", click)
        .style("fill", function(d, i) {
          return color(i % colorSteps);
        });

      force.on("tick", function(e) {
        var q = d3.geom.quadtree(nodes),
          i = 0,
          n = nodes.length;

        while (++i < n) q.visit(collide(nodes[i]));

        svg.selectAll("circle")
          .attr("cx", function(d) {
            return d.x;
          })
          .attr("cy", function(d) {
            return d.y;
          });
      });


      function collide(node) {
        var r = node.radius + (padding),
          nx1 = node.x - r,
          nx2 = node.x + r,
          ny1 = node.y - r,
          ny2 = node.y + r;
        return function(quad, x1, y1, x2, y2) {
          if (quad.point && (quad.point !== node)) {
            var x = node.x - quad.point.x,
              y = node.y - quad.point.y,
              l = Math.sqrt(x * x + y * y),
              r = node.radius + quad.point.radius + (padding);
            if (l < r) {
              l = (l - r) / l * .5;
              node.x -= x *= l;
              node.y -= y *= l;
              quad.point.x += x;
              quad.point.y += y;
            }
          }
          return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
        };
      }


      function click() {
        if (this.getAttribute("data-sequence") == hot) {
          d3.select(this).transition()
            .duration(200)
            .attr("r", 26)
            .style("fill", "green"),
            score++,
            document.getElementById("scoreBoard").innerHTML = "Score " + score,
            document.getElementById("status").innerHTML = "Correct!",
            setTimeout(proceed(), 3000);
            next()
        } else {
          d3.select(this).transition()
            .duration(200)
            .attr("r", 26)
            .style("fill", "red"),
            over()
        }
      }

      function over() {
        document.getElementById("status").innerHTML = "Game Over"
      }



    }
  </script>
  <button id="nav" onclick="proceed()">Next >></button>
  <button id="startOver" onclick="reset()">Start Over</button>
</body>
// Code goes here

/* Styles go here */

Javascript / D3 Game
Working through mechanics of super-simple little javascript game as a js and d3 learning exercise.