fractalkitty looking for math? fractalkitty.com

codepen challenges

light medium dark 1 2 3 - automata roller

#random#trig#vectors#classes#grid#color#interactive#animation#accumulates#geometry#polar#cellular-automata#codepen-challenge

A Game of Life that rolls a hue for you (like rock, paper, scissors), but with light, medium, and dark. Sometimes there is a tie. Each cell plays with a set of rules to determine re-rolls or assimilation.

cellsrockpaperscissorscntRockscntPapercntScissorsCelltriAassignColorplayGamebeatMebeatThemtheSamenNeighnArraythemfindMode

let cells;
let r, c;
let rock, paper, scissors;

function setup() {
  c = max(400, min(windowWidth, windowHeight) * 0.95);
  noStroke();
  cnv = createCanvas(c, c);
  describe(
    "An equilateral triangle made of equilateral triangles in which each has a light, medium, or dark hue of a random color and plays out a game of life with a pie chart to show the amount of each color to determine if it is a tie or winner. Sometimes there are oscillators."
  );
  frameRate(10);
  r1 = random(20, 60);
  g1 = random(20, 60);
  b1 = random(20, 60);
  rock = color(255 - r1 * 4, 255 - g1 * 4, 255 - b1 * 4);
  paper = color(255 - r1, 255 - g1, 255 - b1);
  scissors = color(255 - r1 * 5, 255 - g1 * 5, 255 - b1 * 5);
  background(255 - r1 * 8, 255 - g1 * 8, 255 - b1 * 8);
  nRow = int(random(6, 100));
  r = c / (nRow * 2);
  cells = [];
  cells.push(new Cell(0, 0, -c / 2 + r * 2, 0, [2]));
  l = 2 * r * cos(PI / 6);
  l2 = r * sin(PI / 6);
  cnt = 0;

  for (let i = 1; i < nRow; i++) {
    for (let j = 0; j < i + 1; j++) {
      cnt++;
      if (j === 0 && i < nRow - 1) {
        tmp = [cnt + 1, cnt + (i + 1) * 2];
      } else if (j === 0 && i === nRow - 1) {
        tmp = [cnt + 1];
      } else if (j > 0 && j < i && i < nRow - 1) {
        tmp = [cnt - 1, cnt + 1, cnt + (i + 1) * 2];
      } else if (j > 0 && j < i && i === nRow - 1) {
        tmp = [cnt - 1, cnt + 1];
      } else if (j === i && i < nRow - 1) {
        tmp = [cnt - 1, cnt + (i + 1) * 2];
      } else if (j === i && i === nRow - 1) {
        tmp = [cnt - 1];
      } else {
        tmp = [];
      }

      cells.push(
        new Cell(
          cnt,
          (-l * (i + 1)) / 2 + l / 2 + j * l,
          -c / 2 + r * 2 + (r + l2) * i,
          0,
          tmp
        )
      );
      if (cnt < i * (i + 2)) {
        cnt++;
        if (j < i && i > 1) {
          tmp = [cnt - 1, cnt + 1, cnt - i * 2];
        } else if (j < i && i === 1) {
          tmp = [cnt - 1, cnt + 1];
        } else {
          tmp = [];
        }
        cells.push(
          new Cell(
            cnt,
            (-l * (i + 1)) / 2 + l / 2 + j * l + l / 2,
            -c / 2 + r * 2 + (r + l2) * i - r / 2,
            PI,
            tmp
          )
        );
      }
    }
  }
}

function draw() {
  translate(c / 2, c / 2 + c / 100);
  let cntRocks = 0;
  let cntPaper = 0;
  let cntScissors = 0;
  for (let i = 0; i < cells.length; i++) {
    fill(assignColor(cells[i].type));
    triangle(
      cells[i].v1.x,
      cells[i].v1.y,
      cells[i].v2.x,
      cells[i].v2.y,
      cells[i].v3.x,
      cells[i].v3.y
    );
    if (cells[i].type === 0) {
      cntRocks++;
    } else if (cells[i].type === 1) {
      cntPaper++;
    } else {
      cntScissors++;
    }
    fill(255 - r1 * 8, 255 - g1 * 8, 255 - b1 * 8);
    circle(-c / 3, -c / 3, c / 4.9);
    fill(rock);
    pRock = cntRocks / cells.length;
    arc(-c / 3, -c / 3, c / 5, c / 5, 0, TWO_PI * pRock);
    pPaper = cntPaper / cells.length;
    fill(paper);
    arc(
      -c / 3,
      -c / 3,
      c / 5,
      c / 5,
      TWO_PI * pRock,
      TWO_PI * pRock + TWO_PI * pPaper
    );
    fill(scissors);
    pScissors = cntScissors / cells.length;
    arc(
      -c / 3,
      -c / 3,
      c / 5,
      c / 5,
      TWO_PI * pRock + TWO_PI * pPaper,
      TWO_PI * pRock + TWO_PI * pPaper + TWO_PI * pScissors
    );
  }
  playGame();
}

class Cell {
  constructor(n, x, y, rot, neigh) {
    this.n = n;
    this.x = x;
    this.y = y;
    this.v1 = createVector(
      x + r * Math.cos((0 * TWO_PI) / 3 + PI / 6 + rot),
      y + r * Math.sin((0 * TWO_PI) / 3 + PI / 6 + rot)
    );
    this.v2 = createVector(
      x + r * Math.cos((1 * TWO_PI) / 3 + PI / 6 + rot),
      y + r * Math.sin((1 * TWO_PI) / 3 + PI / 6 + rot)
    );
    this.v3 = createVector(
      x + r * Math.cos((2 * TWO_PI) / 3 + PI / 6 + rot),
      y + r * Math.sin((2 * TWO_PI) / 3 + PI / 6 + rot)
    );
    this.neigh = neigh;
    this.type = random([0, 1, 2]);
  }
}

function triA() {
  beginShape();
  for (let i = 0; i < 3; i++) {
    vertex(r * Math.cos((i * TWO_PI) / 3), r * Math.sin((i * TWO_PI) / 3));
  }
  endShape();
}

function assignColor(n) {
  if (n === 0) {
    return rock;
  } else if (n === 1) {
    return paper;
  } else {
    return scissors;
  }
}

function playGame() {
  for (let i = 0; i < cells.length; i++) {
    let beatMe = 0;
    let beatThem = 0;
    let theSame = 0;
    let me = cells[i].type;
    let nNeigh = cells[i].neigh.length;
    let nArray = [];

    for (let j = 0; j < nNeigh; j++) {
      let them = cells[cells[i].neigh[j]].type;
      nArray[j] = them;
      if (me === them) {
        theSame++;
      } else if (
        (me === 0 && them === 2) ||
        (me === 1 && them === 0) ||
        (me === 2 && them === 1)
      ) {
        beatThem++;
      } else if (
        (me === 0 && them === 1) ||
        (me === 1 && them === 2) ||
        (me === 2 && them === 0)
      ) {
        beatMe++;
      }
    }
    if (theSame / nNeigh >= 0.5 || beatMe === 0) {
    } else if (beatMe / nNeigh >= 0.5) {
      t1 = nArray;
      if (findMode(nArray) != 4) {
        cells[i].type = findMode(nArray);
      }
    } else {
      cells[i].type = random([0, 1, 2]);
    }
  }
}

function findMode(arr) {
  if (arr.length === 0) return 4;
  let count = { 0: 0, 1: 0, 2: 0 };
  arr.forEach((num) => {
    if (num in count) {
      count[num]++;
    }
  });
  for (let num in count) {
    if (count[num] > 1) {
      return parseInt(num);
    }
  }

  return 4;
}

function mousePressed() {
  setup();
  draw();
}

function windowResized() {
  c = max(400, min(windowWidth, windowHeight) * 0.95);
  setup();
  draw();
}