Dots and Boxes v1 from the P5js editor

This commit is contained in:
Eryn Wells 2023-10-12 11:05:29 -07:00
parent c56f91da2c
commit e751bd31b7
2 changed files with 225 additions and 0 deletions

View file

@ -0,0 +1,10 @@
---
title: "Dots and Boxes"
draft: true
resource:
- src: sketch.js
params:
is_module: false
---
{{< figures/p5 >}}

View file

@ -0,0 +1,215 @@
// Eryn Wells <eryn@erynwells.me>
class Player {
name;
#color;
constructor(name, color) {
this.name = name;
this.#color = color;
}
get color() {
}
}
class Point {
static fromEventCoordinates(x, y) {
return new Point(x - marginSize, y - marginSize);
}
x = 0;
y = 0;
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
/// Return a value that uniquely identifies this Point.
get identifier() {
return `x:${this.x},y:${this.y}`;
}
/// Convert this point to an array of coordinates.
get coordinates() {
return [this.x, this.y];
}
/// Convert a Point in grid space to pixel space.
toPixelPoint() {
return [marginSize + this.x * cellSize, marginSize + this.y * cellSize];
}
convertPixelPointToGridPointWithRemainder() {
let clickCol = Math.floor(this.x / cellSize);
let clickRow = Math.floor(this.y / cellSize);
let clickColRemainder = this.x - (clickCol * cellSize);
let clickRowRemainder = this.y - (clickRow * cellSize);
if (clickColRemainder >= (cellSize - hitBoxMargin)) {
clickCol += 1;
clickColRemainder = clickColRemainder - cellSize;
}
if (clickRowRemainder >= (cellSize - hitBoxMargin)) {
clickRow += 1;
clickRowRemainder = clickRowRemainder - cellSize;
}
return [new Point(clickCol, clickRow), new Point(clickColRemainder, clickRowRemainder)];
}
/// Return a string that's nice to read.
toString() {
return `(${this.x}, ${this.y})`;
}
}
class Line {
player;
from;
to;
constructor(player, from, to) {
this.player = player;
this.from = from;
this.to = to;
}
get identifier() {
return `from:[${this.from.identifier}],to:[${this.to.identifier}]`;
}
}
const sketch = p => {
const marginSize = 10;
const cellSize = 40;
const gridSize = 20;
const hitBoxMargin = 7;
let player = 1;
let lines = new Map();
p.setup = () => {
const canvasSize = [
cellSize * (gridSize - 1) + marginSize * 2,
cellSize * (gridSize - 1) + marginSize * 2
];
createCanvas(...canvasSize);
};
let mouseBoundingBoxRect;
let debugNeighboringBoxA;
let debugNeighboringBoxB;
p.draw = () => {
background(220);
for (const l of lines.values()) {
const strokeColor = l.player === 1 ? color(255, 0, 0) : color(0, 0, 255);
p.stroke(strokeColor);
p.strokeWeight(2);
p.line(
...l.from.toPixelPoint(),
...l.to.toPixelPoint()
);
}
drawGrid();
debugDrawMouseBoundingBoxRect();
debugDrawNeighboringBoxes();
p.noLoop();
};
function drawGrid() {
for (let i = 0; i < gridSize; i++) {
for (let j = 0; j < gridSize; j++) {
const [x, y] = [marginSize + cellSize * j, marginSize + cellSize * i];
p.noStroke();
p.fill(128);
p.circle(x, y, 6);
}
}
}
function debugDrawMouseBoundingBoxRect() {
if (!mouseBoundingBoxRect) {
return;
}
p.stroke(255, 0, 0);
p.strokeWeight(1);
p.noFill();
p.rect(...mouseBoundingBoxRect);
}
function debugDrawNeighboringBoxes() {
}
p.mouseMoved = (event) => {
mouseBoundingBoxRect = findHitBox(event);
if (mouseBoundingBoxRect) {
loop();
}
};
p.mouseClicked = (event) => {
const clickPoint = Point.fromEventCoordinates(event.x, event.y);
const [gridPoint, gridPointRemainder] = clickPoint.convertPixelPointToGridPointWithRemainder();
const isVertical = gridPointRemainder.x > -hitBoxMargin && gridPointRemainder.x < hitBoxMargin;
const from = gridPoint;
const to = isVertical ? new Point(gridPoint.x, gridPoint.y + 1) : new Point(gridPoint.x + 1, gridPoint.y);
console.log(
"Mouse clicked.",
clickPoint.toString(),
gridPoint.toString(),
gridPointRemainder.toString(),
from.toString(),
to.toString(),
event
);
const newLine = new Line(player, from, to);
const newLineId = newLine.identifier;
if (!lines.has(newLineId)) {
lines.set(newLineId, newLine);
player = (player === 1 ? 2 : 1);
loop();
}
};
function findHitBox(mouseEvent) {
const clickPoint = Point.fromEventCoordinates(mouseEvent.x, mouseEvent.y);
const [gridPoint, gridPointRemainder] = clickPoint.convertPixelPointToGridPointWithRemainder();
const isHorizontal = gridPointRemainder.y > -hitBoxMargin && gridPointRemainder.y < hitBoxMargin;
const isVertical = gridPointRemainder.x > -hitBoxMargin && gridPointRemainder.x < hitBoxMargin;
if (isHorizontal === isVertical) {
return null;
}
return [
marginSize + gridPoint.x * cellSize + (isVertical ? -hitBoxMargin : 0),
marginSize + gridPoint.y * cellSize + (!isVertical ? -hitBoxMargin : 0),
isVertical ? 2 * hitBoxMargin : cellSize,
isVertical ? cellSize : 2 * hitBoxMargin,
];
}
};