Skip to content
  • The version below minifes to 1086 bytes.

    let g = 14;
    let width = 784;
    let height = 210;
    let d = document;
    let cE = (tag) => d.createElement(tag)
    let qA = (tag) => d.querySelectorAll(tag)
    let setText = (text) => l.innerText = text;
    let c = qA(".user-calendar")[0];
    let append = (element) => c.append(element)
    let l = cE("div");
    
    let left;
    let can;
    let ctx;
    let ival;
    let s;
    let a;
    
    
    let fillSquare = (col,coordinates) => {
      ctx.fillStyle = col;
      ctx.fillRect(coordinates.x,coordinates.y,g-1,g-1)
    };
    
    let r = (max) => ~~(Math.random() * (max));
    
    let placeFood = () => {
      a = { x: r(56) * g,y: r(15) * g}
    };
    
    let reset = text => {
      setText(`You ${text}!`);
      clearInterval(ival);
      setTimeout(init, 5000);
    };
    
    let check = () => {
      if (left > 0) {
        setText(`${left} contributions left`);
      } else {
        reset("win");
      }
    };
    
    let ranCol = () => {
      let colors = ["#d2dcff", "#7992f5", "#3f51ae", "#2a2b59"];
      return colors[r(3)];
    };
    
    let sameCell = (a,b) => a && a.x == b.x && a.y == b.y
    
    let loop = () => {
      // Reset the canvas
      ctx.reset();
    
      // Advance the snake's head
      s.x += s.dx;
      s.y += s.dy;
    
      // Wrap the snake's head when out of bounds
      s.x = s.x < 0 ? width - g : s.x < width ? s.x : 0;
      s.y = s.y < 0 ? height - g : s.y < height ? s.y : 0;
    
      // prepend the snake's head and truncate to snake's length
      s.c = [{ x: s.x, y: s.y },...s.c].slice(0,s.m);
    
      // paint food
      fillSquare("#fc6d26", a);
    
      // `some` is shorter than `forEach`
      // Paint the snake
      s.c.some((cell, idx) => {
        fillSquare(ranCol(), cell);
    
        // Nom-nom-nom
        if (sameCell(cell,a)) {
          s.m++;
    
          placeFood()
          left -=100;
          check();
        }
    
        // Ouch
        // We do not return because we want to paint the whole Snake!
        if (idx > 0 && sameCell(s.c[0], cell)) {
          reset("lose");
        }
      });
    };
    
    let init = () => {
      // reset state
      placeFood()
      s = {x: 140,y : 70,c: [],m: 30,dx:g,dy:0}
    
      // count contributions
      left = [...qA("rect")]
        .map(rect => +rect.getAttribute("title").slice(0,2))
        .reduce((acc, t) => t ? acc + t: acc, 0);
    
      // have we won yet?
      check();
    
      if (can) can.remove();
      can = cE("canvas");
      can.width = width;
      can.height = height;
      ctx = can.getContext("2d");
      append(can);
    
      ival = setInterval(loop, 50);
    }
    
    d.addEventListener("keydown", (e) => {
      e.preventDefault();
      let r;
      if (s.dx == 0) {
        r = { 37: [0, -g], 39: [0, g] }[e.which];
      } else if (s.dy == 0) {
        r = { 38: [-g, 0], 40: [g, 0] }[e.which];
      }
      if (r) {
        [s.dy, s.dx] = r;
      }
    });
    
    append(l);
    init();
    • Edit: Realized that min in our random function was always 0. Some more bytes gone!
    • Edit2: Without the trim() the map is smaller!
    Edited by Lukas 'ai-pi' Eipert
  • Here is the compress to less than 1024B version (1019 to be exact)

    let blockSize = 14;
    
    let canvasWidth = 784;
    let canvasHeight = 210;
    
    /**
     * Elements and stuff
     */
    let doc = document;
    let createElement = (tag) => doc.createElement(tag);
    let querySelectorAll = (tag) => doc.querySelectorAll(tag);
    let calendarContainer = querySelectorAll(".user-calendar")[0];
    let append = (element) => calendarContainer.append(element);
    let textContainer = createElement("div");
    let canvas;
    let context;
    
    /**
     * Global state
     */
    // How many contributions to play down
    let contributions;
    // Current loop interval
    let interval;
    // Direction the snake head is gonna go
    let direction;
    
    let fillSquare = (col, coordinates) => {
      context.fillStyle = col;
      context.fillRect(coordinates.x, coordinates.y, blockSize - 1, blockSize - 1);
    };
    
    let r = (max) => ~~(Math.random() * max);
    
    let setText = (text, done = 1) => {
      textContainer.innerText = text;
      if (done) {
        clearInterval(interval);
        setTimeout(init, 5000);
      }
    };
    
    let check = () => {
      if (contributions > 0) {
        setText(`${contributions} contributions left`, 0);
      } else {
        setText("Win!");
      }
    };
    
    let randomColor = () => {
      let colors = ["#d2dcff", "#7992f5", "#3f51ae", "#2a2b59"];
      return colors[r(3)];
    };
    
    let sameCell = (a, b) => a && a.x == b.x && a.y == b.y;
    
    let init = () => {
      // reset state
      let snakeLength = 4;
      let coordinates = [];
      let x = 140;
      let y = 70;
      let food;
      let placeFood = () => {
        food = { x: r(56) * blockSize, y: r(15) * blockSize };
      };
      placeFood();
      direction = { x: blockSize, y: 0 };
    
      let loop = () => {
        // Reset the canvas
        context.reset();
    
        // Advance the snake's head
        x += direction.x;
        y += direction.y;
    
        // Wrap the snake's head when out of bounds
        x = x < 0 ? canvasWidth - blockSize : x < canvasWidth ? x : 0;
        y = y < 0 ? canvasHeight - blockSize : y < canvasHeight ? y : 0;
    
        // prepend the snake's head and truncate to snake's length
        coordinates = [{ x, y }, ...coordinates].slice(0, snakeLength);
    
        // paint food
        fillSquare("#fc6d26", food);
    
        // `some` is shorter than `forEach`
        // Paint the snake
        coordinates.some((cell, index) => {
          fillSquare(randomColor(), cell);
    
          // Nom-nom-nom
          if (sameCell(cell, food)) {
            snakeLength++;
    
            placeFood();
            contributions -= 100;
            check();
          }
    
          // Ouch
          // We do not return because we want to paint the whole Snake!
          if (index > 0 && sameCell(coordinates[0], cell)) {
            setText("Loss!");
          }
        });
      };
    
      // count contributions
      contributions = [...querySelectorAll("rect")]
        .map((rect) => +rect.getAttribute("title").slice(0, 2))
        .reduce((acc, t) => (t ? acc + t : acc), 0);
    
      // have we won yet?
      check();
    
      if (canvas) canvas.remove();
      canvas = createElement("canvas");
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      context = canvas.getContext("2d");
      append(canvas);
    
      interval = setInterval(loop, 50);
    };
    
    doc.addEventListener("keydown", (e) => {
      e.preventDefault();
      let r = (
        !direction.x
          ? { 37: [0, -blockSize], 39: [0, blockSize] }
          : !direction.y
            ? {
              38: [-blockSize, 0],
              40: [blockSize, 0],
            }
            : direction
      )[e.which];
      if (r) {
        [direction.y, direction.x] = r;
      }
    });
    
    append(textContainer);
    init();

    Biggest jump was the move of some state to the init function rather than having it in a global state object.

  • Lorenz van Herwaarden @lorenzvanherwaarden ·

    Thanks @leipert for turning this into a valid submission! 🙏 I'll update the description to reflect this one is below 1024 Bytes!

0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment