Playing Chess In Universe – Amber (Lingwen Zhu) – Margret Minsky
Conception and Design:
My project is to present the evolution of a very small part of the universe while two planets collide, only one can win, which shows the indifferent evolving of nature. By designing the interaction part as when the user moves the king chess, the position of the planet will also move in the universe, making the user feel like they can control the large planets in the endless universe but actually humans are only a very small part of the universe. Creating this contrast is aimed at presenting the interesting relationships between humans and the entire universe. I have searched online about the interactive chess game and most of these games are normal chess but the chess boards are normal ones with different colors of light under every grid. Therefore, I decided to use acrylic board to make a chess board and engrave certain grids of it to make it look like a chess board. I also choose to use normal chess in the project. My design in the very beginning is like below.
During the user test session, users said that the chess rules are difficult to understand when I just told them by speaking so I decided to write it down as below in a pattern format, which I consider can be easier to read and understand. Some people also said that the outlook of my chess box is not very good so I use black paper to wrap every piece of acrylic board to make the entire atmosphere more likely to the universe, which makes it look much more better. However, it is harder to connect all pieces together with the previous empty spaces for inserting because the black paper has some thickness. Some people also said that the background as universe is not that obvious so I also added some very small stars on it.
Fabrication and Production:
Throughout the entire production process, making the decision of the material of chess board and sensor to detect the king chess are both difficult for me in the physical producing dimension. For the chess board, I first wanted to use wooden board and project screen onto it. Professor Margret also gave me some suggestions about choosing what materials to use when designing this chess board. She suggested that the transparent board which makes user to look into it is more interesting and adds more mystery into this project. Then I finally decided to use acrylic board to make chess board. This is the file that I designed for the chess board. I also downloaded an example of laser cutting for boxes from this website and adjusted it into the size I wanted. I also added one more interlayer to put my ipad on it and add four more holes on the four pieces on the side.
However, when I laser cut it on the machine with the help of lab assistants, I found it to engrave the lines because if I set the lines wrong, it just cut it off. For these kind of mistakes, I cut one more time. Here are the videos of how the laser cutting machine works under the cutting and engraving setting.
For the sensor, I first wanted to use pressure sensor but I found it a little bit larger than I expected, which may influence the outlook of the project since the chessboard is transparent. Then I tested whether the reading number of light sensor changes significantly when the chess on and off it with the transparent chess board in the middle. Fortunately, it works well with light sensor. However, I found that I can only use six light sensors in total in one arduino board since it only has six analogRead pins. However, it is hard for me to find another sensor that fits into the project well so I just declined the number of grids where king chess can stay on. For this restriction, I designed the rules by myself and also the winning strategy, which is listed below. I combined the rules from the traditional Chinese chess game and Chinese checkers in my design.
Since I can not add more light sensor in the middle, I also use the if statement to detect whether the two planet collides by setting the condition as when all the three sensors do not detect any sensors on them which means the king chess must reach the center. I also found that the light sensor can make mistakes because users’ hands may pass it when moving the chess.
For the coding part, the most difficult part is that since I use if statement to detect which king chess arrive the middle first by detecting which three sensors has nothing on it, it may go wrong when users are moving chess. Because when moving, there are a few seconds that no chess is on the three sensors. Then I asked professor Margret for help, she drew the sketch like below for me to revise my codes.
I finally made my codes for this part like this.
if (value1 >= 100 && value2 >= 25 && value3 >= 25) {
sensor1 = true;
}
if (presensor1 == false && sensor1 == true) {
startTime = millis();
}
if (sensor1 == true && millis()- startTime >10*1000) {
r = 255;
g = 0;
b = 0;
t = 50;
fill(r, g, b, t);
noStroke();
circle(x1, y1, 200);
x1 = x1 + 20;
if (x1 >= width/2) {
y1 = y1 + 600;
//fill(r,g,b);
//rect(0,0,width,height);
}
} else {
r = 255;
g = 255;
b = 255;
t = 0;
}
presensor1 = sensor1;
I also decided to draw the pattern of planet and the background as universe by myself instead of loading an image because I think the design can be more abstract and interesting.
Conclusion:
The project finally works like this.
The outlook is like this.
The goal of my project is to show the indifferent evolving of nature by presenting the evolution of a very small part of the universe while two planets collide, only one can win. The basic goal of making the screen show the pattern according to the position of the king chess is fulfilled and making the atmosphere like universe is also successful to some extent. Because I made the entire box as black and draw small stars in the background. I have learnt designing and preparing laser cutting files. I also learnt updating the value of a variable and using class function in processing.
However, I think the design of the change in the background is not that obvious and not satisfied as the collision of two planets. If I have more time, I may design an explosion process after the king chess reach the middle. For the interaction part, I found users are quite interested in how the chess and patterns moves instead of playing the chess game. I think I may try to find another way to detect chess and simplify the rules which can make users easier to understand and have interests to play.
Annex:
Codes for arduino:
const int LDR1 = A0;
const int LDR2 = A1;
const int LDR3 = A2;
const int LDR4 = A3;
const int LDR5 = A4;
const int LDR6 = A5;
int input_val1 = 0;
int input_val2 = 0;
int input_val3 = 0;
int input_val4 = 0;
int input_val5 = 0;
int input_val6 = 0;
#include "SerialRecord.h"
SerialRecord writer(6);
void setup() {
Serial.begin(9600);
}
void loop() {
input_val1 = analogRead(LDR1);
input_val2 = analogRead(LDR2);
input_val3 = analogRead(LDR3);
input_val4 = analogRead(LDR4);
input_val5 = analogRead(LDR5);
input_val6 = analogRead(LDR6);
writer[0] = input_val1;
writer[1] = input_val2;
writer[2] = input_val3;
writer[3] = input_val4;
writer[4] = input_val5;
writer[5] = input_val6;
writer.send();
delay(20);
}
Codes from processing:
import processing.serial.*;
import osteele.processing.SerialRecord.*;
Serial serialPort;
SerialRecord serialRecord;
int col;
int r = 0;
int g = 0;
int b = 0;
int t;
int timer1;
int timer2;
int x1 = 300;
int x2 = 1200;
int y1 = 300;
int y2 = 300;
Star[] stars;
int currentStar = 0;
Boolean sensor1 = false;
Boolean presensor1 = false;
Boolean sensor2 = false;
Boolean presensor2 = false;
int startTime1;
int startTime2;
void setup() {
fullScreen();
background(0);
String serialPortName = SerialUtils.findArduinoPort();
serialPort = new Serial(this, serialPortName, 9600);
serialRecord = new SerialRecord(this, serialPort, 6);
col = 0;
stars = new Star[100];
for (int i = 0; i<50; i++) {
stars[i] = new Star();
}
//serialRecord.logToCanvas(false);
}
void draw() {
serialRecord.read();
if (frameCount <50) {
return;
}
for (int i = 0; i<50; i++) {
stars[i].display();
}
stars[currentStar].constructor(random(width), random(height));
currentStar++;
if (currentStar>=50) {
currentStar = 49;
}
int value1 = serialRecord.values[0];
if (value1 < 100) {
col = 255;
}
push();
translate(300, 100);
rotate(radians(frameCount));
rectMode(CENTER);
stroke(col, 10);
noFill();
rect(0, 0, 20, 200);
pop();
if (col > 0) {
col = col - 255;
}
int value2 = serialRecord.values[1];
if (value2 < 25) {
col = 255;
}
push();
translate(100, 300);
rotate(radians(frameCount));
rectMode(CENTER);
stroke(col, 10);
noFill();
rect(0, 0, 20, 200);
pop();
if (col>0) {
col = col - 255;
}
int value3 = serialRecord.values[2];
if (value3 < 25) {
col = 255;
}
push();
translate(300, 500);
rotate(radians(frameCount));
rectMode(CENTER);
stroke(col, 10);
noFill();
rect(0, 0, 20, 200);
pop();
if (col>0) {
col = col - 255;
}
int value4 = serialRecord.values[3];
if (value4 < 80) {
col = 255;
}
push();
translate(1100, 100);
rotate(radians(frameCount));
rectMode(CENTER);
stroke(col, 10);
noFill();
rect(0, 0, 20, 200);
pop();
if (col>0) {
col = col-255;
}
int value5 = serialRecord.values[4];
if (value5 < 50) {
col = 255;
}
push();
translate(1300, 300);
rotate(radians(frameCount));
rectMode(CENTER);
stroke(col, 10);
noFill();
rect(0, 0, 20, 200);
pop();
if (col>0) {
col = col-255;
}
int value6 = serialRecord.values[5];
if (value6 < 20) {
col = 255;
}
push();
translate(1100, 600);
rotate(radians(frameCount));
rectMode(CENTER);
stroke(col, 10);
noFill();
rect(0, 0, 20, 200);
pop();
if (col>0) {
col = col-255;
}
if (value1 >= 100 && value2 >= 25 && value3 >= 25) {
sensor1 = true;
}
if (presensor1 == false && sensor1 == true) {
startTime1 = millis();
}
if (sensor1 == true && millis()- startTime1 >10*1000) {
r = 255;
g = 0;
b = 0;
t = 50;
fill(r, g, b, t);
noStroke();
circle(x1, y1, 200);
x1 = x1 + 20;
if (x1 >= width/2) {
y1 = y1 + 600;
//fill(r,g,b);
//rect(0,0,width,height);
}
} else {
r = 255;
g = 255;
b = 255;
t = 0;
}
presensor1 = sensor1;
if (presensor2 == false && sensor2 == true) {
startTime2 = millis();
}
if (sensor2 == true && millis()- startTime2 >10*1000) {
r = 255;
g = 255;
b = 255;
t = 50;
fill(r, g, b, t);
noStroke();
circle(x2, y2, 200);
x2 = x2 + 20;
if (x2 <= width/2) {
y2 = y2 + 600;
}
} else {
r = 255;
g = 255;
b = 255;
t = 0;
}
presensor2 = sensor2;
}
class Star {
float x, y;
void constructor (float pox, float poy) {
x = pox;
y = poy;
}
void display() {
float angle = TWO_PI / 5;
float halfAngle = angle/2.0;
beginShape();
noStroke();
fill(255, 100);
for (float a = 0; a < TWO_PI; a += angle) {
float sx = x + cos(a) * 3;
float sy = y + sin(a) * 3;
vertex(sx, sy);
sx = x + cos(a+halfAngle) * 1;
sy = y + sin(a+halfAngle) * 1;
vertex(sx, sy);
}
endShape(CLOSE);
}
}