// Zhengshan Shi // Music 220a Final Project // Interface Part - The Chessboard // Need OSCP5 library import oscP5.*; import netP5.*; OscP5 oscP5; NetAddress myRemoteLocation; // about the button int posX1 = 40; int posY1 = 50; int rectLength = 70; int rectWidth = 40; int spare = 40; int rx1 = posX1 + 380; int rx2 = rx1 + rectLength + spare; int rx3 = rx2 + rectLength + spare; int yRect = posY1+20; int soloWt = 20; int soloWtH = 20; int soloBk = 100; int soloBkH = 20; int soloL = 20; int soloW = 20; int exitX = 900; int exitY = 20; int exitR = 20; int firstChess = 0; float scale = 100.0; int nRows = 16; int nCols = 16; int pieceColor; float side = scale * 2/5; float chessRadius = side * 8/9; float rowBegin = scale*1.3; float colBegin = scale*1.8; float rowEnd = rowBegin + nRows * side; float colEnd = colBegin + nCols * side; Cell[][] board; int[][] boardUsed; ArrayList pieces; Cat mycat = new Cat(); boolean whitePiece = true; boolean gameStarts = false; boolean soloStarts = false; boolean soloWhite = false; boolean soloBlack = false; void setup() { size(1000, 1500); background(255); smooth(); clearBoard(); // start oscP5, listening for incoming messages at port 8889 oscP5 = new OscP5(this,8888); myRemoteLocation = new NetAddress("127.0.0.1",8889); //sendSetupMessage(nRows,nCols); } // The main loop void draw() { // button if (mousePressed) { if (inButton1()){ soloStarts = true; gameStarts = false; soloWhite = true; soloBlack = false; clearBoard(); sendStartMessage(0); sendClearMessage(); firstChess = 0; } else if (inButton2()) { gameStarts = true; soloStarts = false; clearBoard(); sendStartMessage(0); sendClearMessage(); firstChess = 0; } else if (inButton3()) { soloStarts = false; gameStarts = false; clearBoard(); sendStartMessage(0); sendClearMessage(); firstChess = 0; } else if (inExit()) { clearBoard(); sendClearMessage(); sendStartMessage(0); sendExitMessage(); exit(); } else if (soloStarts && inSoloWhite()) { soloWhite = true; soloBlack = false; clearBoard(); //soloInterface(); sendSoloMessage(0); sendClearMessage(); firstChess = 0; } else if (soloStarts && inSoloBlack()) { soloBlack = true; soloWhite = false; firstChess = 0; clearBoard(); //soloInterface(); sendSoloMessage(1); sendClearMessage(); } //} else { } } if (soloStarts) { soloInterface(); } else if (gameStarts){ gameInterface(); } else { welcome(); } } // Case 1: welcome menu void welcome() { background(255); smooth(); clearBoard(); mycat.drawCat(); textSize(32); fill(0,102,153); text("Welcome to Shanshan's Go-bang Music",posX1,posY1); text("Click to choose mode",posX1,posY1+40); drawButtons(); } // Case 2: The solo interface part void soloInterface() { if (soloWhite) { background(0); textSize(15); fill(255); text("Play White to beat Black!",100,60); } else{ background(255); fill(0); text("Play Black to beat White!",100,60); } smooth(); mycat.drawCat(); textSize(15); stroke(255,0,156); text("Solo~",100,100); drawButtons(); // draw solo button stroke(255,255,0); noFill(); rect(soloWt,soloWtH,soloL,soloW); rect(soloBk,soloBkH,soloL,soloW); runBoard(); } // Case 3: The game interface void gameInterface() { background(255); smooth(); drawBackground(); text("Go Game",100,100); mycat.drawCat(); drawButtons(); runBoard(); } // The true gobang game void runBoard() { drawBoard(); // Draw the chess pieces for (int i = pieces.size()-1; i >= 0; i--) { Piece p = (Piece) pieces.get(i); p.displayPiece(); } if (mousePressed) { mouseMap(); } int winSide = whoWins(); if (winSide != -1) { winView(winSide); } } void clearBoard() { pieces = new ArrayList(); board = new Cell[nRows][nCols]; boardUsed = new int[nRows][nCols]; // 1 for black, 0 for white, -1 for unknown for (int i = 0; i < nRows; i++) { for (int j = 0; j < nCols; j++) { boardUsed[i][j] = -1; } } } // return the number representing the winner // -1 for not win, 0 for white, 1 for black int whoWins() { int count; // search for 8 directions return -1; } void winView(int winSide) { } // Mainly used for sending nRows and nCols void sendSetupMessage(int n1,int n2) { OscMessage myMessage = new OscMessage("/setup"); myMessage.add(n1); myMessage.add(n2); } /////////////////Some Helper Functions////////////////// // This function maps mousePressed action during the game void mouseMap() { // Normalize the position of mouse to the board position if (inBound(mouseX,mouseY)) { float[] piecePos = mapMouseToBoard(mouseX, mouseY); int row = int (piecePos[2]); int col = int (piecePos[3]); if (boardUsed[row][col] != -1){ print("You can't place the chess piece here!"); println(); } else { if (soloStarts && soloWhite) { pieceColor = 255; } else if (soloStarts && soloBlack){ pieceColor = 0; } else { setPieceColor(); } firstChess = 1; pieces.add(new Piece(piecePos[0], piecePos[1], chessRadius, pieceColor)); // Send the message when the user first click the board if (soloStarts && soloWhite) { boardUsed[row][col] = 0; } else if (soloStarts && soloBlack) { boardUsed[row][col] = 1; } else { boardUsed[row][col] = (whitePiece)? 0:1; } sendPieceMessage(row,col,boardUsed[row][col]); } } else { print("Please click the place on the board"); println(); } } // Choosing the color of the piece void setPieceColor() { if (whitePiece) { pieceColor = 255; whitePiece = false; } else { pieceColor = 0; whitePiece = true; } } // This function determines if a position is inside the board boolean inBound(int xPos, int yPos) { float leftBound = rowBegin-side/2; float rightBound = rowEnd -side/2; float upBound = colBegin-side/2; float downBound = colEnd;//+side/2; return (xPos > leftBound && xPos < rightBound && yPos > upBound && yPos < downBound); } // This function maps mouseX and mouseY to normalized position in board // It returns normalized boardX, boardY, and index position for the board float[] mapMouseToBoard(int x, int y) { float[] pt = new float[4]; float minDist = 500.0; for (int i = 0; i < nRows; i++) { for (int j = 0; j < nCols; j++) { Cell mycell = board[i][j]; float myDist = dist(mycell.getX(), mycell.getY(), x, y); if ( myDist< minDist) { minDist = myDist; pt[0] = mycell.getX(); pt[1] = mycell.getY(); pt[2] = i; pt[3] = j; } } } return pt; } /////////////End of Helper Functions///////////////// //////////////// Some Drawing Functions////////////// void drawBackground() { rectMode(CORNER); stroke(255, 0, 156); fill(255); rect(-2, -2, height*2, width*2); strokeWeight(1); noFill(); int startPos = 3; for (int i=15; i= rx1 && mouseX <= rx1+rectLength && mouseY >= yRect && mouseY <= yRect+rectWidth); } boolean inButton2(){ return (mouseX >= rx2 && mouseX <= rx2+rectLength && mouseY >= yRect && mouseY <= yRect+rectWidth); } boolean inButton3(){ return (mouseX >= rx3 && mouseX <= rx3+rectLength && mouseY >= yRect && mouseY <= yRect+rectWidth); } boolean inSoloWhite() { return (mouseX >= soloWt && mouseX <= soloWt+soloL && mouseY >= soloWtH && mouseY <= soloWtH+soloW); } boolean inSoloBlack() { return (mouseX >= soloBk && mouseX <= soloBk+soloL && mouseY >= soloBkH && mouseY <= soloBkH+soloW); } boolean inExit() { return (dist(mouseX,mouseY,exitX,exitY) <= exitR); } ////////////End of Drawing helper functions/////////// ////////////////For OSC Message/////////////////////// // Sending the first message (only once) void sendClearMessage() { OscMessage myMessage = new OscMessage("/setup/clr"); myMessage.add(1); oscP5.send(myMessage, myRemoteLocation); print("sending the start messaage"); println(); } void sendExitMessage() { OscMessage myMessage = new OscMessage("/setup/exit"); myMessage.add(1); oscP5.send(myMessage, myRemoteLocation); print("sending the start messaage"); println(); } void sendSoloMessage(int sol) { OscMessage myMessage = new OscMessage("/mode/solo"); myMessage.add(sol); oscP5.send(myMessage,myRemoteLocation); print("sending solo message"); println(); } void sendStartMessage(int sol) { if (sol == 0) { OscMessage myMessage = new OscMessage("/mode/start"); myMessage.add(sol); oscP5.send(myMessage,myRemoteLocation); print("sending first chess message 0 "); } else { if (sol == 1) { OscMessage myMessage = new OscMessage("/mode/start"); myMessage.add(sol); oscP5.send(myMessage,myRemoteLocation); print("sending first chess message 1"); } } } // Sending the individual cell of the piece void sendPieceMessage(int row,int col,int boardUser) { OscMessage myMessage = new OscMessage("/piece"); myMessage.add(row); myMessage.add(col); myMessage.add(boardUser); oscP5.send(myMessage, myRemoteLocation); print("sending osc message"); println(); } // The Cat Class class Cat { //setup the variable int x=750; int foot=0; Cat() {} void display() { drawCat(); drawBody(); } void drawCat() { strokeWeight(4); stroke(255,0,156); //Draw face noFill(); arc(x+110,145,185,140,-9*PI/40,49*PI/40); //Draw cat's whiskers line(x+2,120,x+35,130); //Left top line(x+1,145,x+35,150); //left middle line(x+2,180,x+35,165); //left bottom line(x+220,120,x+190,130);//right top line(x+222,145,x+190,148);//right middle line(x+220,180,x+190,165);//right bottom //Draw mouth noFill(); curve(x+85,88,x+85,170,x+107,156,x+67,3); curve(x+180,2,x+127,170,x+107,156,x+186,113); // Draw eye fill(255,0,126); ellipse(x+78-10+mouseX/30,142-10+mouseY/30,10,18); ellipse(x+139-10+mouseX/30,142-10+mouseY/30,10,18); //Draw ear noFill(); arc(x+100, 100, 120, 120, PI, 5*PI/4); //left ear left arc(x+14, 100, 120, 120, 7*PI/4, 2*PI); //left ear right arc(x+206, 100, 120, 120, PI, 5*PI/4); //right ear left arc(x+120, 100, 120, 120, 7*PI/4, 2*PI);//right ear right //Draw curve between two ears curve(x+60,180,x+74,100,x+146,100,x+160,180); //start at (74,100),ends at (146,100) //Draw hairs curve(x+112,97,x+84,95,x+84,120,x+112,66); //hair left curve(x+132,107,x+110,90,x+110,120,x+132,86); //hair middle curve(x+109,110,x+135,95,x+135,120,x+109,66); //hair right } void drawBody() { strokeWeight(4); //Draw hand noFill(); ellipse(x+80,240,50,30); ellipse(x+185,240,50,30); //Draw body line(x+65,208,x+35,305); line(x+65+100,206,x+35+150,310); arc(x+112,178,300,300,14*PI/40,27*PI/40); //Draw foot ellipse(x+65+foot,340,48,30); ellipse(x+140+foot,340,48,30); } } // The Cell Class class Cell { float x,y; // center location float sideL; // length of side // Cell Constructor Cell(float tempX, float tempY, float tempL) { x = tempX; y = tempY; sideL = tempL; } void display() { rectMode(CENTER); stroke(0); strokeWeight(2); fill(255,255,0); rect(x,y,sideL,sideL); } float getX() { return x; } float getY() { return y; } } // Class of Chess piece class Piece { float xPos; float yPos; float chessSize; int chessColor; Piece(float tempX, float tempY, float tempSize,int tsnailColor) { xPos = tempX; yPos = tempY; chessSize = tempSize; chessColor = tsnailColor; } void displayPiece() { // Snail body ellipseMode(CENTER); fill(chessColor); ellipse(xPos,yPos,chessSize,chessSize); } }