Match sets
Inspired a game I saw once, which in turn is inspired by the board game SET!.
Match sets of three cards, where each set has either all cards or no cards matching in every single attribute: color, shape, or number.
Press H to highlight possible matches. Drag to make a match out of adjacent or diagonally-adjacent tiles.
There is no scoring system yet.
var draw, keyPressed;
function setup() {
createCanvas(400, 400);
let colors = [
color(255, 0, 0),
color(0, 255, 0),
color(0, 0, 255),
]
let shapes = [
(x,y) => rect(x - 5, y - 5, 10, 10),
(x,y) => circle(x, y, 10),
(x,y) => triangle(x, y - 5, x - 5, y + 5, x + 5, y + 5),
// (x,y) => quad(x, y - 5, x - 5, y, x, y + 5, x + 5, y),
]
let arrangements = [
[[0, 0]],
[[-10, 0], [10, 0]],
[[0, -7], [-10, 7], [10, 7]],
// [[10, 0], [-10, 0], [0, 10], [0, -10]],
]
let tiles = Array(8 * 9).fill().map(newTile)
function newTile() {
return {
fall: 0,
sel: false,
t: [
floor(random(colors.length)),
floor(random(shapes.length)),
floor(random(arrangements.length)),
]
}
}
tiles[32] = {fall: 0, sel: false, h: true, t: [0, 0, 0]}
tiles[32+9] = {fall: 0, sel: false, h: true, t: [1, 1, 1]}
tiles[32+18] = {fall: 0, sel: false, h: true, t: [2, 2, 2]}
tiles[12] = {fall: 0, sel: false, h: true, t: [1, 1, 2]}
tiles[13] = {fall: 0, sel: false, h: true, t: [1, 1, 2]}
tiles[14] = {fall: 0, sel: false, h: true, t: [1, 1, 2]}
function drawTile(x, y, {fall, sel, h, t: [c, s, a]}) {
if (h) {
stroke(255, 0, 0)
noFill()
rect(x - 4, y + fall - 4, 40 + 4 * 2)
}
if (sel) {
fill(250, 250, 50)
stroke(100, 100, 0)
} else {
fill(255)
stroke(0)
}
rect(x, y + fall, 40)
fill(colors[c])
stroke(0)
for (let [dx, dy] of arrangements[a]) {
let fn = shapes[s]
fn(x + 40 / 2 + dx, y + 40 / 2 + dy + fall)
}
}
let selectedC = 0
let selectedTraits = {}
draw = function() {
background(220);
for (let i = 0; i < tiles.length; i ++) {
if (tiles[i]) {
let x = floor(i / 9) * (40 + 80/7)
let y = (i % 9 - 1) * (40 + 80/7)
drawTile(x, y, tiles[i])
if (mouseIsPressed && !tiles[i].sel && mouseX > x && mouseX < x + 40 && mouseY > y && mouseY < y + 40 && selectedC < 3) {
let neighbor = (selectedC == 0)
for (let j of [-1, 1, -9, 9, -10, 10, -8, 8]) {
if ((i + j) % 9 == 0 || !tiles[i + j]) continue;
if (tiles[i + j].sel) {
neighbor = true
break
}
}
if (neighbor) {
tiles[i].sel = true
selectedC += tiles[i].sel ? 1 : -1
for (let ti = 0; ti < tiles[i].t.length; ti ++) {
selectedTraits[[ti, tiles[i].t[ti]]] |= 0
selectedTraits[[ti, tiles[i].t[ti]]] += tiles[i].sel ? 1 : -1
}
}
}
if ((!tiles[i + 1] || tiles[i + 1].fall != 0) && (i + 1) % 9 != 0) {
tiles[i].fall += 5
if (tiles[i].fall >= 50) {
tiles[i].fall = 0
tiles[i + 1] = tiles[i]
tiles[i] = undefined
}
}
} else if (i % 9 == 0) {
tiles[i] = newTile()
}
}
if (!mouseIsPressed) {
let matching = selectedC == 3 && Object.values(selectedTraits).every(v => v == 0 || v == 1 || v == 3)
for (let i = 0; i < tiles.length; i ++) {
if (tiles[i] && tiles[i].sel) {
if (matching) {
tiles[i] = undefined
} else {
tiles[i].sel = false
}
}
}
selectedC = 0
selectedTraits = {}
}
}
keyPressed = function() {
if (key != 'h') return
for (let i = 0; i < tiles.length; i ++) {
if (!tiles[i]) continue
let found = {}
let wanted = []
tiles[i].h = false
let ot = tiles[i].t
for (let j of [-1, 1, -9, 9, -10, 10, -8, 8]) {
if ((i + j) % 9 == 0 || !tiles[i + j]) continue;
let t = tiles[i + j].t
let k = 0
k = k * colors.length + t[0]
k = k * shapes.length + t[1]
k = k * arrangements.length + t[2]
let wk = 0
wk = wk * colors.length + (2*t[0] - ot[0] + colors.length) % colors.length
wk = wk * shapes.length + (2*t[1] - ot[1] + shapes.length) % shapes.length
wk = wk * arrangements.length + (2*t[2] - ot[2] + arrangements.length) % arrangements.length
found[k] |= 0
found[k] += wk == k ? 1 : 2
wanted.push(wk)
}
for (let w of wanted) {
if (found[w] >= 2) {
tiles[i].h = w
}
}
}
}
}(Originally seen at https://editor.p5js.org/bojidar-bg/sketches/sijEyG8Ag)
Browse more articles?
← Sling Experiments tagged p5 (58/85) Ninja circle →
← Sling Experiments tagged game (6/11) Scale →
← Circle lockpick Experiments tagged wip (3/5) Reflection fractal →
← Sling Experiments on this site (58/85) Ninja circle →