bio photo

Email

##Mid term, Rock, Paper & Scissors

For this mid-term I was paired with Yuchi Ma to build a midterm project. Yuchi and I didn’t know eachother very well so immediately after our pairing we sat down to figure out what we wanted to do.

First week

I pitched increasing the scope of the nagging hand to interact with the browser and build it out of better materials than a Kellog’s cardboard. I let Yuchi know I was open minded about his ideas.

He suggested building a power glove that we can manipulate in VR. I was happy to consider that option but wanted to limit ourselves to p5 and not have to learn a new software like Maya or 3D Max while we had other projects going on.

We did our own research and played around with Maya, but controlling variables was very hard (could only get the ball to fall off the grid, not much else). With that, we jumped into p5.

Second week

Having done the lab for asynchronous serial communication and handling multiple values coming in we decided to use two flex sensors (as opposed to five which we already bought). Came up with the algorithm, labled and mapped the flex sensors. We got familiar with the use of a wire wrapper too.

Then we started programming p5 with the if statements first. These were critical, if “sensor a” vs “sensor b” are bent, display Image X. This we spent a bit of time on and correlated with the values we’d mapped.

We encountered some problems with the server port not working, but got around that with the help of a resident Laura Chen. We also modified the lab’s code to declare separate variables as opposed to the same variable in the arduino sketch to improve accuracy.

Do nothing

An important aspect was getting the do-nothing gesture to be as effective as a paper gesture because they are similar in nature. We got over that - with a bit of faith - and a lot of sensitive mapping of flex sensors. Hence are annoyance at it during the presentation.

A lot of debugging (console.log which was introduced to us at that point) helped in mapping ‘a’ vs ‘b’.

The last couple of days were spent building a timer (which we shameless found and used code from the internet), but getting it to work in our program wasn’t simple. I would try a function based approach and Yuchi would watch it fail - then he would try creating an array, and I would watch that fail. Until, well, we would get help. Other functions we built out included, game mechanics, adding randomness to play with the computer, assessing wins and a scoring system.

Our program was a patch work of borrowed, tailored and original code.

##Success - it worked. Kind of - and then we ran some user tests on the floor.

var serial;
var savedTime;
var playerChoice;
var computerChoice;
var playerScore = 0;
var computerScore = 0;
var result = "";
var images = [];

function preload() {
  images[0] = loadImage("images/rock.jpg");
  images[1] = loadImage("images/scissors.jpg");
  images[2] = loadImage("images/paper.jpg");
  images[3] = loadImage("images/rock.jpg");
  images[4] = loadImage("images/scissors.jpg");
  images[5] = loadImage("images/paper.jpg");
}

function setup() {
  createCanvas(1300, 600);
  savedTime = millis();

  serial = new p5.SerialPort();
  serial.open("/dev/cu.usbmodemfa131");
  serial.onData(serialEvent);
}

function serialEvent() {
  var inString = serial.readStringUntil('\r\n');
  if (!inString) return;
  if (inString.length > 0) {
    var sensors = split(inString, ',');
    if (sensors.length > 1) {
      a = sensors[0];
      b = sensors[1];
      console.log("a: " + a + ", b: " + b);
    }

    if ((300 < a && a < 380) && (350 < b && b < 420)) {
      console.log("rock");
      image(images[0], width / 2 - 90, height - 180);
      playerChoice = "rock";
    } else if ((300 < a && a < 380) && (420 < b && b < 530)) {
      console.log("scissor");
      image(images[1], width / 2 - 90, height - 180);
      playerChoice = "scissors";
    } else if ((450 < a && a < 530) && (420 < b && b < 530)) {
      console.log("paper");
      image(images[2], width / 2 - 90, height - 180);
      playerChoice = "paper";
    } else {
      console.log("nothing is recognized");
    }
  }
}

function draw() {
  var pastTime = millis() - savedTime;
  textSize(50);
  fill(0, 50);
  if (pastTime > 1000 && pastTime < 2000) {
    background(0);
    fill(255, 50);
    text("3", width / 2, height / 2);
  } else if (pastTime > 2000 && pastTime < 3000) {
    background(0);
    fill(255, 50);
    text("2", width / 2, height / 2);
  } else if (pastTime > 3000 && pastTime < 4000) {
    background(0);
    fill(255, 50);
    text("1", width / 2, height / 2);
  } else if (pastTime > 4000 && pastTime < 5000) {

    background(0);
    var compImg;

    var randomPick = int(random(3));
    if (randomPick === 0) {
      computerChoice = "rock";
    } else if (randomPick === 1) {
      computerChoice = "scissors";
    } else if (randomPick === 2) {
      computerChoice = "paper";
    }

    push();
    angleMode(DEGREES);
    translate(width / 2 + 90, 180);
    rotate(180);
    compImg = image(images[randomPick], 0, 0);
    pop();


    serialEvent();
    assess(playerChoice, computerChoice);
    updateScore();

    stroke(0);
    fill(255);
    textSize(32);
    text(result, width / 2 - 40, height / 2);
    text("Your Score:" + " " + playerScore, 20, 500);
    text("Computer Score:" + " " + computerScore, 20, 100);
    savedTime = millis();
  }
}

function assess(playerChoice, computerChoice) {
  // Update the images for player and computer

  if (playerChoice == computerChoice) {
    result = "DRAW";
    return;
  }

  switch (playerChoice) {
    case "rock":
      if (computerChoice == "paper") {
        result = "LOSE";
        return;
      } else {
        result = "WIN";
        return;
      }
      break;
    case "paper":
      if (computerChoice == "scissors") {
        result = "LOSE";
        return;
      } else {
        result = "WIN";
        return;
      }
      break;
    case "scissors":
      if (computerChoice == "paper") {
        result = "WIN";
        return;
      } else {
        result = "LOSE";
        return;
      }
      break;
    default:
      result = "DRAW";
      break;
  }
  print(result);
}

function updateScore() {
  if (result == "WIN") {
    playerScore++;
  }
  if (result == "LOSE") {
    computerScore++;
  }
}


/*
// Got the list of ports
function gotList(thelist) {
  println("List of Serial Ports:");
  // theList is an array of their names
  for (var i = 0; i < thelist.length; i++) {
    // Display in the console
    println(i + " " + thelist[i]);
  }
}*/


//ARDUINO CODE

int sensorV1;
int sensorV2;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {

  sensorV1 = analogRead(A0);
  Serial.print(sensorV1);
  Serial.print(",");

  sensorV2 = analogRead(A1);
  Serial.println(sensorV2);
  delay(500);
}

##Pitfalls

Alot of our programming and testing was done with the user sitting down. 10 minutes before class started we were testing to see if our game worked on the projector but Yuchi stood up when he used the glove - lol - and the wires ripped off. PANIC!

But I asked him to remain calm, and we re-did the wires and crossed our fingers that the values mapped values for the flex sensors didnt change with the wiring. It happened before! Thankfully it worked and everybody who played it enjoyed the game!