diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/CC_72_Frogger_original.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/CC_72_Frogger_original.pde new file mode 100644 index 0000000000..74d18d9f03 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/CC_72_Frogger_original.pde @@ -0,0 +1,124 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +Frog frog; +Car[] cars; +Log[] logs; + +float grid = 50; + +void resetGame() { + frog = new Frog(width/2-grid/2, height-grid, grid); + frog.attach(null); +} + +void setup() { + size(500, 500); + //frog = new Frog(width/2-grid/2, height-grid, grid); + resetGame(); + + int index = 0; + cars = new Car[8]; + + // ROW 1 + for (int i = 0; i < 2; i++) { + float x = i * 300; + cars[index] = new Car(x, height-grid*2, grid*2, grid, 2); + index++; + } + + // ROW 2 + for (int i = 0; i < 2; i++) { + float x = i * 200 + 150; + cars[index] = new Car(x, height-grid*3, grid, grid, -3.5); + index++; + } + + // ROW 3 + for (int i = 0; i < 4; i++) { + float x = i * 150 + 25; + cars[index] = new Car(x, height-grid*4, grid, grid, 1.2); + index++; + } + + logs = new Log[7]; + + // ROW 5 + index = 0; + for (int i = 0; i < 2; i++) { + float x = i * 250 + 100; + logs[index] = new Log(x, height-grid*6, grid*3, grid, 2.3); + index++; + } + // ROW 6 + for (int i = 0; i < 3; i++) { + float x = i * 200 + 30; + logs[index] = new Log(x, height-grid*7, grid*2, grid, -1.3); + index++; + } + // ROW 7 + for (int i = 0; i < 2; i++) { + float x = i * 400 + 10; + logs[index] = new Log(x, height-grid*8, grid*4, grid, 0.5); + index++; + } +} + +void draw() { + background(0); + fill(255, 100); + rect(0, 0, width, grid*2); + rect(0, height-grid, width, grid); + rect(0, height-grid*5, width, grid); + for (Car car : cars) { + car.show(); + car.update(); + if (frog.intersects(car)) { + resetGame(); + //println("GAME OVER"); + } + } + + for (Log log : logs) { + log.show(); + log.update(); + } + + if (frog.y < height-grid*5 && frog.y > grid*2) { + boolean ok = false; + for (Log log : logs) { + if (frog.intersects(log)) { + ok = true; + frog.attach(log); + } + } + if (!ok) { + resetGame(); + } + } else { + frog.attach(null); + } + + frog.update(); + frog.show(); +} + +void keyPressed() { + + if (keyCode == UP) { + frog.move(0, -1); + } else if (keyCode == DOWN) { + frog.move(0, 1); + } else if (keyCode == RIGHT) { + frog.move(1, 0); + } else if (keyCode == LEFT) { + frog.move(-1, 0); + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Car.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Car.pde new file mode 100644 index 0000000000..c889babc85 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Car.pde @@ -0,0 +1,32 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +class Car extends Rectangle { + float speed; + + Car(float x, float y, float w, float h, float s) { + super(x, y, w, h); + speed = s; + } + + void update() { + x = x + speed; + if (speed > 0 && x > width+grid) { + x = -w-grid; + } else if (speed < 0 && x < -w-grid) { + x = width+grid; + } + } + + void show() { + fill(200); + rect(x, y, w, h); + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Frog.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Frog.pde new file mode 100644 index 0000000000..ccb2b06e9a --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Frog.pde @@ -0,0 +1,40 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +class Frog extends Rectangle { + + Log attached = null; + + Frog(float x, float y, float w) { + super(x, y, w, w); + } + + void attach(Log log) { + attached = log; + } + + void update() { + if (attached != null) { + x += attached.speed; + } + + x = constrain(x, 0, width-w); + } + + void show() { + fill(0, 255, 0, 200); + rect(x, y, w, w); + } + + void move(float xdir, float ydir) { + x += xdir * grid; + y += ydir * grid; + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Log.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Log.pde new file mode 100644 index 0000000000..b61c8ff654 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Log.pde @@ -0,0 +1,16 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +class Log extends Car { + + Log(float x, float y, float w, float h, float s) { + super(x, y, w, h, s); + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Rectangle.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Rectangle.pde new file mode 100644 index 0000000000..2223eb4389 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_original/Rectangle.pde @@ -0,0 +1,40 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +class Rectangle { + float x; + float y; + float w; + float h; + + Rectangle(float x, float y, float w, float h) { + this.x = x; + this.w = w; + this.y = y; + this.h = h; + } + + boolean intersects(Rectangle other) { + float left = x; + float right = x + w; + float top = y; + float bottom = y + h; + + float oleft = other.x; + float oright = other.x + other.w; + float otop = other.y; + float obottom = other.y + other.h; + + return !(left >= oright || + right <= oleft || + top >= obottom || + bottom <= otop); + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/CC_72_Frogger_refactored.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/CC_72_Frogger_refactored.pde new file mode 100644 index 0000000000..f5ce53ebff --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/CC_72_Frogger_refactored.pde @@ -0,0 +1,66 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +Frog frog; +Lane[] lanes; + +int SAFETY = 0; +int CAR = 1; +int LOG = 2; + +float grid = 50; + +void resetGame() { + frog = new Frog(width/2-grid/2, height-grid, grid); + frog.attach(null); +} + +void setup() { + size(500, 550); + //frog = new Frog(width/2-grid/2, height-grid, grid); + resetGame(); + int totalLanes = int(height / grid); + lanes = new Lane[totalLanes]; + lanes[0] = new Lane(0, color(100)); + lanes[1] = new Lane(1, LOG, 3, 1, 150, 3); + lanes[2] = new Lane(2, LOG, 2, 3, 350, -2.5); + lanes[3] = new Lane(3, LOG, 4, 1, 200, 1); + lanes[4] = new Lane(4, LOG, 3, 2, 250, -1.7); + lanes[5] = new Lane(5, color(100)); + lanes[6] = new Lane(6, CAR, 3, 1, 150, 2.4); + lanes[7] = new Lane(7, CAR, 2, 2, 150, -3.6); + lanes[8] = new Lane(8, CAR, 1, 3, 150, 2.3); + lanes[9] = new Lane(9, CAR, 4, 1, 150, -1); + lanes[10] = new Lane(10, color(100)); +} + +void draw() { + background(0); + for (Lane lane : lanes) { + lane.run(); + } + int laneIndex = int(frog.y / grid); + lanes[laneIndex].check(frog); + frog.update(); + frog.show(); +} + +void keyPressed() { + + if (keyCode == UP) { + frog.move(0, -1); + } else if (keyCode == DOWN) { + frog.move(0, 1); + } else if (keyCode == RIGHT) { + frog.move(1, 0); + } else if (keyCode == LEFT) { + frog.move(-1, 0); + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Frog.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Frog.pde new file mode 100644 index 0000000000..3f67868148 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Frog.pde @@ -0,0 +1,41 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +class Frog extends Rectangle { + + Obstacle attached = null; + + Frog(float x, float y, float w) { + super(x, y, w, w); + } + + void attach(Obstacle log) { + attached = log; + } + + void update() { + if (attached != null) { + x += attached.speed; + } + + x = constrain(x, 0, width-w); + } + + void show() { + fill(0, 255, 0, 200); + rect(x, y, w, w); + } + + void move(float xdir, float ydir) { + x += xdir * grid; + y += ydir * grid; + attach(null); + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Lane.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Lane.pde new file mode 100644 index 0000000000..74a10889e2 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Lane.pde @@ -0,0 +1,65 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +class Lane extends Rectangle { + + Obstacle[] obstacles; + int col; + int type; + + Lane(int index, color c) { + super(0, index*grid, width, grid); + type = SAFETY; + obstacles = new Obstacle[0]; + col = c; + } + + Lane(int index, int t, int n, int len, float spacing, float speed) { + super(0, index*grid, width, grid); + obstacles = new Obstacle[n]; + type = t; + float offset = random(0, 200); + for (int i = 0; i < n; i++) { + obstacles[i] = new Obstacle(offset + spacing * i, index*grid, grid*len, grid, speed); + } + col = color(0); + } + + + void check(Frog frog) { + if (type == CAR) { + for (Obstacle o : obstacles) { + if (frog.intersects(o)) { + resetGame(); + } + } + } else if (type == LOG) { + boolean ok = false; + for (Obstacle o : obstacles) { + if (frog.intersects(o)) { + ok = true; + frog.attach(o); + } + } + if (!ok) { + resetGame(); + } + } + } + + void run() { + fill(col); + rect(x, y, w, h); + for (Obstacle o : obstacles) { + o.show(); + o.update(); + } + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Obstacle.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Obstacle.pde new file mode 100644 index 0000000000..21720b3507 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Obstacle.pde @@ -0,0 +1,32 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +class Obstacle extends Rectangle { + float speed; + + Obstacle(float x, float y, float w, float h, float s) { + super(x, y, w, h); + speed = s; + } + + void update() { + x = x + speed; + if (speed > 0 && x > width+grid) { + x = -w-grid; + } else if (speed < 0 && x < -w-grid) { + x = width+grid; + } + } + + void show() { + fill(200); + rect(x, y, w, h); + } +} diff --git a/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Rectangle.pde b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Rectangle.pde new file mode 100644 index 0000000000..2223eb4389 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/CC_72_Frogger_refactored/Rectangle.pde @@ -0,0 +1,40 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Frogger +// Part 1: https://youtu.be/giXV6xErw0Y +// Part 2: https://youtu.be/06-ZvYmSeus +// Part 3: https://youtu.be/hk326ZHlENQ +// Part 4: https://youtu.be/c6WdJltqEtM + +class Rectangle { + float x; + float y; + float w; + float h; + + Rectangle(float x, float y, float w, float h) { + this.x = x; + this.w = w; + this.y = y; + this.h = h; + } + + boolean intersects(Rectangle other) { + float left = x; + float right = x + w; + float top = y; + float bottom = y + h; + + float oleft = other.x; + float oright = other.x + other.w; + float otop = other.y; + float obottom = other.y + other.h; + + return !(left >= oright || + right <= oleft || + top >= obottom || + bottom <= otop); + } +} diff --git a/CodingChallenges/CC_72_Frogger/README.md b/CodingChallenges/CC_72_Frogger/README.md new file mode 100644 index 0000000000..292781d5d9 --- /dev/null +++ b/CodingChallenges/CC_72_Frogger/README.md @@ -0,0 +1,10 @@ +# Coding Challenge 72: Frogger +* Edited Videos for this challenge: [Youtube Playlist](https://www.youtube.com/playlist?list=PLRqwX-V7Uu6Yaeyfbk0xgOPYDRBOjfe6c) +* Live Stream 1: [Youtube](https://youtu.be/7BdfPG3peP4?list=PLRqwX-V7Uu6bxnFR6no70vlxxuxDEzflz) +* Live Stream 2: [Youtube](https://youtu.be/m9EsKBPCggk?list=PLRqwX-V7Uu6bxnFR6no70vlxxuxDEzflz) + +## Community Variations + +#### By: [Jaysonmaw](https://github.com/silver-line/) , [Repository](https://github.com/silver-line/Frogger-Processing) +![Loading gif...](https://github.com/silver-line/Frogger-Processing/raw/master/frogger_230x310px.gif) +Frogger in Processing, Added colors, simple graphics, Randomly generated levels. diff --git a/CodingChallenges/SimplePerceptron/Perceptron.pde b/CodingChallenges/SimplePerceptron/Perceptron.pde new file mode 100644 index 0000000000..e2e9fce199 --- /dev/null +++ b/CodingChallenges/SimplePerceptron/Perceptron.pde @@ -0,0 +1,49 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Machine Learning +// Perceptron +// More: http://natureofcode.com/book/chapter-10-neural-networks/ +// Video: https://youtu.be/ntKn5TPHHAk + +// The activation function +int sign(float n) { + if (n >= 0) { + return 1; + } else { + return -1; + } +} + + +class Perceptron { + float[] weights = new float[2]; + float lr = 0.1; + + // Constructor + Perceptron() { + // Initialize the weights randomly + for (int i = 0; i < weights.length; i++) { + weights[i] = random(-1, 1); + } + } + + int guess(float[] inputs) { + float sum = 0; + for (int i = 0; i < weights.length; i++) { + sum += inputs[i]*weights[i]; + } + int output = sign(sum); + return output; + } + + void train(float[] inputs, int target) { + int guess = guess(inputs); + int error = target - guess; + // Tune all the weights + for (int i = 0; i < weights.length; i++) { + weights[i] += error * inputs[i] * lr; + } + } +} diff --git a/CodingChallenges/SimplePerceptron/SimplePerceptron.pde b/CodingChallenges/SimplePerceptron/SimplePerceptron.pde new file mode 100644 index 0000000000..3435542ff3 --- /dev/null +++ b/CodingChallenges/SimplePerceptron/SimplePerceptron.pde @@ -0,0 +1,65 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Machine Learning +// Perceptron +// More: http://natureofcode.com/book/chapter-10-neural-networks/ +// Video: https://youtu.be/ntKn5TPHHAk + +Perceptron brain; + +Point[] points = new Point[100]; + +int trainingIndex = 0; + +void setup() { + size(800, 800); + brain = new Perceptron(); + + for (int i = 0; i < points.length; i++) { + points[i] = new Point(); + } + + + + float[] inputs = {-1, 0.5}; + int guess = brain.guess(inputs); + println(guess); +} + +void draw() { + background(255); + stroke(0); + line(0, 0, width, height); + for (Point pt : points) { + pt.show(); + } + + for (Point pt : points) { + float[] inputs = {pt.x, pt.y}; + int target = pt.label; + int guess = brain.guess(inputs); + if (guess == target) { + fill(0, 255, 0); + } else { + fill(255, 0, 0); + } + noStroke(); + ellipse(pt.x, pt.y, 16, 16); + } + + Point training = points[trainingIndex]; + float[] inputs = {training.x, training.y}; + int target =training.label; + brain.train(inputs, target); + trainingIndex++; + if (trainingIndex == points.length) { + trainingIndex = 0; + } +} + +void mousePressed() { + for (Point pt : points) { + } +} diff --git a/CodingChallenges/SimplePerceptron/Training.pde b/CodingChallenges/SimplePerceptron/Training.pde new file mode 100644 index 0000000000..aa9f893b88 --- /dev/null +++ b/CodingChallenges/SimplePerceptron/Training.pde @@ -0,0 +1,35 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Machine Learning +// Perceptron +// More: http://natureofcode.com/book/chapter-10-neural-networks/ +// Video: https://youtu.be/ntKn5TPHHAk + +class Point { + float x; + float y; + int label; + + Point() { + x = random(width); + y = random(height); + + if (x > y) { + label = 1; + } else { + label = -1; + } + } + + void show() { + stroke(0); + if (label == 1) { + fill(255); + } else { + fill(0); + } + ellipse(x, y, 32, 32); + } +} diff --git a/Courses/intelligence_learning/session4/SimplePerceptron/Perceptron.pde b/Courses/intelligence_learning/session4/SimplePerceptron/Perceptron.pde new file mode 100644 index 0000000000..e2e9fce199 --- /dev/null +++ b/Courses/intelligence_learning/session4/SimplePerceptron/Perceptron.pde @@ -0,0 +1,49 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Machine Learning +// Perceptron +// More: http://natureofcode.com/book/chapter-10-neural-networks/ +// Video: https://youtu.be/ntKn5TPHHAk + +// The activation function +int sign(float n) { + if (n >= 0) { + return 1; + } else { + return -1; + } +} + + +class Perceptron { + float[] weights = new float[2]; + float lr = 0.1; + + // Constructor + Perceptron() { + // Initialize the weights randomly + for (int i = 0; i < weights.length; i++) { + weights[i] = random(-1, 1); + } + } + + int guess(float[] inputs) { + float sum = 0; + for (int i = 0; i < weights.length; i++) { + sum += inputs[i]*weights[i]; + } + int output = sign(sum); + return output; + } + + void train(float[] inputs, int target) { + int guess = guess(inputs); + int error = target - guess; + // Tune all the weights + for (int i = 0; i < weights.length; i++) { + weights[i] += error * inputs[i] * lr; + } + } +} diff --git a/Courses/intelligence_learning/session4/SimplePerceptron/SimplePerceptron.pde b/Courses/intelligence_learning/session4/SimplePerceptron/SimplePerceptron.pde new file mode 100644 index 0000000000..3435542ff3 --- /dev/null +++ b/Courses/intelligence_learning/session4/SimplePerceptron/SimplePerceptron.pde @@ -0,0 +1,65 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Machine Learning +// Perceptron +// More: http://natureofcode.com/book/chapter-10-neural-networks/ +// Video: https://youtu.be/ntKn5TPHHAk + +Perceptron brain; + +Point[] points = new Point[100]; + +int trainingIndex = 0; + +void setup() { + size(800, 800); + brain = new Perceptron(); + + for (int i = 0; i < points.length; i++) { + points[i] = new Point(); + } + + + + float[] inputs = {-1, 0.5}; + int guess = brain.guess(inputs); + println(guess); +} + +void draw() { + background(255); + stroke(0); + line(0, 0, width, height); + for (Point pt : points) { + pt.show(); + } + + for (Point pt : points) { + float[] inputs = {pt.x, pt.y}; + int target = pt.label; + int guess = brain.guess(inputs); + if (guess == target) { + fill(0, 255, 0); + } else { + fill(255, 0, 0); + } + noStroke(); + ellipse(pt.x, pt.y, 16, 16); + } + + Point training = points[trainingIndex]; + float[] inputs = {training.x, training.y}; + int target =training.label; + brain.train(inputs, target); + trainingIndex++; + if (trainingIndex == points.length) { + trainingIndex = 0; + } +} + +void mousePressed() { + for (Point pt : points) { + } +} diff --git a/Courses/intelligence_learning/session4/SimplePerceptron/Training.pde b/Courses/intelligence_learning/session4/SimplePerceptron/Training.pde new file mode 100644 index 0000000000..aa9f893b88 --- /dev/null +++ b/Courses/intelligence_learning/session4/SimplePerceptron/Training.pde @@ -0,0 +1,35 @@ +// Daniel Shiffman +// http://codingtra.in +// http://patreon.com/codingtrain + +// Machine Learning +// Perceptron +// More: http://natureofcode.com/book/chapter-10-neural-networks/ +// Video: https://youtu.be/ntKn5TPHHAk + +class Point { + float x; + float y; + int label; + + Point() { + x = random(width); + y = random(height); + + if (x > y) { + label = 1; + } else { + label = -1; + } + } + + void show() { + stroke(0); + if (label == 1) { + fill(255); + } else { + fill(0); + } + ellipse(x, y, 32, 32); + } +}