├── Chess ├── Board.js ├── MinimaxFunctions.js ├── Piece.js ├── assets │ ├── 2000px-Chess_Pieces_Sprite_01.png │ ├── 2000px-Chess_Pieces_Sprite_02.png │ ├── 2000px-Chess_Pieces_Sprite_03.png │ ├── 2000px-Chess_Pieces_Sprite_04.png │ ├── 2000px-Chess_Pieces_Sprite_05.png │ ├── 2000px-Chess_Pieces_Sprite_06.png │ ├── 2000px-Chess_Pieces_Sprite_07.png │ ├── 2000px-Chess_Pieces_Sprite_08.png │ ├── 2000px-Chess_Pieces_Sprite_09.png │ ├── 2000px-Chess_Pieces_Sprite_10.png │ ├── 2000px-Chess_Pieces_Sprite_11.png │ └── 2000px-Chess_Pieces_Sprite_12.png ├── index.html ├── libraries │ ├── p5.dom.js │ ├── p5.js │ └── p5.sound.js └── sketch.js └── README.md /Chess/Board.js: -------------------------------------------------------------------------------- 1 | class Board { 2 | constructor() { 3 | this.whitePieces = []; 4 | this.blackPieces = []; 5 | this.score = 0; 6 | this.setupPieces(); 7 | 8 | 9 | } 10 | 11 | setupPieces() { 12 | this.whitePieces.push(new King(4, 7, true)); 13 | this.whitePieces.push(new Queen(3, 7, true)); 14 | this.whitePieces.push(new Bishop(2, 7, true)); 15 | this.whitePieces.push(new Bishop(5, 7, true)); 16 | this.whitePieces.push(new Knight(1, 7, true)); 17 | this.whitePieces.push(new Rook(0, 7, true)); 18 | this.whitePieces.push(new Knight(6, 7, true)); 19 | this.whitePieces.push(new Rook(7, 7, true)); 20 | 21 | this.whitePieces.push(new Pawn(4, 6, true)); 22 | this.whitePieces.push(new Pawn(3, 6, true)); 23 | this.whitePieces.push(new Pawn(2, 6, true)); 24 | this.whitePieces.push(new Pawn(5, 6, true)); 25 | this.whitePieces.push(new Pawn(1, 6, true)); 26 | this.whitePieces.push(new Pawn(0, 6, true)); 27 | this.whitePieces.push(new Pawn(6, 6, true)); 28 | this.whitePieces.push(new Pawn(7, 6, true)); 29 | 30 | //black pieces 31 | this.blackPieces.push(new King(4, 0, false)); 32 | this.blackPieces.push(new Queen(3, 0, false)); 33 | this.blackPieces.push(new Bishop(2, 0, false)); 34 | this.blackPieces.push(new Bishop(5, 0, false)); 35 | this.blackPieces.push(new Knight(1, 0, false)); 36 | this.blackPieces.push(new Rook(0, 0, false)); 37 | this.blackPieces.push(new Knight(6, 0, false)); 38 | this.blackPieces.push(new Rook(7, 0, false)); 39 | 40 | this.blackPieces.push(new Pawn(4, 1, false)); 41 | this.blackPieces.push(new Pawn(3, 1, false)); 42 | this.blackPieces.push(new Pawn(2, 1, false)); 43 | this.blackPieces.push(new Pawn(5, 1, false)); 44 | this.blackPieces.push(new Pawn(1, 1, false)); 45 | this.blackPieces.push(new Pawn(0, 1, false)); 46 | this.blackPieces.push(new Pawn(6, 1, false)); 47 | this.blackPieces.push(new Pawn(7, 1, false)); 48 | 49 | 50 | } 51 | 52 | show() { 53 | for (var i = 0; i < this.whitePieces.length; i++) { 54 | this.whitePieces[i].show(); 55 | } 56 | for (var i = 0; i < this.blackPieces.length; i++) { 57 | this.blackPieces[i].show(); 58 | } 59 | } 60 | 61 | isPieceAt(x, y) { 62 | for (var i = 0; i < this.whitePieces.length; i++) { 63 | if (!this.whitePieces[i].taken && this.whitePieces[i].matrixPosition.x == 64 | x && this.whitePieces[i].matrixPosition.y == y) { 65 | return true; 66 | } 67 | } 68 | for (var i = 0; i < this.blackPieces.length; i++) { 69 | if (!this.blackPieces[i].taken && this.blackPieces[i].matrixPosition.x == 70 | x && this.blackPieces[i].matrixPosition.y == y) { 71 | return true; 72 | } 73 | } 74 | return false; 75 | } 76 | 77 | getPieceAt(x, y) { 78 | for (var i = 0; i < this.whitePieces.length; i++) { 79 | if (!this.whitePieces[i].taken && this.whitePieces[i].matrixPosition.x == 80 | x && this.whitePieces[i].matrixPosition.y == y) { 81 | return this.whitePieces[i]; 82 | } 83 | } 84 | for (var i = 0; i < this.blackPieces.length; i++) { 85 | if (!this.blackPieces[i].taken && this.blackPieces[i].matrixPosition.x == 86 | x && this.blackPieces[i].matrixPosition.y == y) { 87 | return this.blackPieces[i]; 88 | } 89 | } 90 | return null; 91 | } 92 | 93 | 94 | generateNewBoardsWhitesTurn() { 95 | var boards = []; 96 | for (var i = 0; i < this.whitePieces.length; i++) { 97 | if (!this.whitePieces[i].taken) { 98 | var tempArr = this.whitePieces[i].generateNewBoards(this); 99 | for (var j = 0; j < tempArr.length; j++) { 100 | boards.push(tempArr[j]); 101 | } 102 | } 103 | } 104 | return boards; 105 | } 106 | generateNewBoardsBlacksTurn() { 107 | var boards = []; 108 | for (var i = 0; i < this.blackPieces.length; i++) { 109 | if (!this.blackPieces[i].taken) { 110 | var tempArr = this.blackPieces[i].generateNewBoards(this); 111 | for (var j = 0; j < tempArr.length; j++) { 112 | boards.push(tempArr[j]); 113 | } 114 | } 115 | } 116 | return boards; 117 | } 118 | 119 | setScore() { 120 | this.score = 0; 121 | for (var i = 0; i < this.whitePieces.length; i++) { 122 | if (!this.whitePieces[i].taken) { 123 | this.score -= this.whitePieces[i].value; 124 | } else { 125 | //print("something"); 126 | } 127 | } 128 | for (var i = 0; i < this.blackPieces.length; i++) { 129 | if (!this.blackPieces[i].taken) { 130 | this.score += this.blackPieces[i].value; 131 | } else { 132 | //print("something"); 133 | } 134 | } 135 | 136 | } 137 | 138 | move(from, to) { 139 | var pieceToMove = this.getPieceAt(from.x, from.y); 140 | if (pieceToMove == null) { 141 | //print("shit"); 142 | return; 143 | } 144 | // if (pieceToMove.canMove(to.x, to.y, this)) { 145 | pieceToMove.move(to.x, to.y, this); 146 | // } 147 | } 148 | 149 | 150 | clone() { 151 | var clone = new Board(); 152 | for (var i = 0; i < this.whitePieces.length; i++) { 153 | clone.whitePieces[i] = this.whitePieces[i].clone(); 154 | } 155 | for (var i = 0; i < this.blackPieces.length; i++) { 156 | clone.blackPieces[i] = this.blackPieces[i].clone(); 157 | } 158 | return clone; 159 | } 160 | 161 | isDone() { 162 | return this.whitePieces[0].taken || this.blackPieces[0].taken; 163 | } 164 | isDead() { 165 | if (whiteAI && whitesMove) { 166 | return this.whitePieces[0].taken; 167 | } 168 | if (blackAI && !whitesMove) { 169 | return this.blackPieces[0].taken; 170 | } 171 | 172 | return false; 173 | } 174 | 175 | hasWon() { 176 | if (whiteAI && whitesMove) { 177 | return this.blackPieces[0].taken; 178 | } 179 | if (blackAI && !whitesMove) { 180 | return this.whitePieces[0].taken; 181 | } 182 | 183 | return false; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Chess/MinimaxFunctions.js: -------------------------------------------------------------------------------- 1 | var maxDepth = 3; 2 | 3 | 4 | function minFun(board, depth) { 5 | if (depth >= maxDepth) { 6 | board.setScore(); 7 | return board.score; 8 | } 9 | 10 | var boards = board.generateNewBoardsWhitesTurn(); 11 | var lowestBoardNo = 0; 12 | var lowestScore = 100000; 13 | for (var i = 0; i < boards.length; i++) { 14 | if (!boards[i].isDead()) { 15 | var score = maxFun(boards[i], depth + 1); 16 | if (score < lowestScore) { 17 | lowestBoardNo = i; 18 | lowestScore = score; 19 | } 20 | } 21 | } 22 | return lowestScore; 23 | } 24 | 25 | function maxFun(board, depth) { 26 | if (depth >= maxDepth) { 27 | board.setScore(); 28 | return board.score; 29 | } 30 | 31 | 32 | var boards = board.generateNewBoardsBlacksTurn(); 33 | if (depth == 0) { 34 | //////print(boards); 35 | } 36 | var topBoardNo = 0; 37 | var topScore = -100000; 38 | for (var i = 0; i < boards.length; i++) { 39 | var score = minFun(boards[i], depth + 1); 40 | if (score > topScore) { 41 | topBoardNo = i; 42 | topScore = score; 43 | } 44 | } 45 | 46 | if (depth == 0) { 47 | ////print(topScore); 48 | return boards[topBoardNo]; 49 | } 50 | return topScore; 51 | } 52 | 53 | 54 | function minFunAB(board, alpha, beta, depth) { 55 | if (depth >= maxDepth) { 56 | board.setScore(); 57 | return board.score; 58 | } 59 | 60 | 61 | if (board.isDead()) { 62 | if (whiteAI && whitesMove) { 63 | return 200; 64 | } 65 | if (blackAI && !whitesMove) { 66 | return -200; 67 | } 68 | } 69 | 70 | if (board.hasWon()) { 71 | 72 | if (whiteAI && whitesMove) { 73 | return -200; 74 | } 75 | if (blackAI && !whitesMove) { 76 | return 200; 77 | } 78 | } 79 | 80 | var boards = board.generateNewBoardsWhitesTurn(); 81 | var lowestBoardNo = 0; 82 | var lowestScore = 300; 83 | for (var i = 0; i < boards.length; i++) { 84 | 85 | var score = maxFunAB(boards[i], alpha, beta, depth + 1); 86 | if (depth == 0) { 87 | //print(score, i, boards[i]); 88 | } 89 | if (score < lowestScore) { 90 | lowestBoardNo = i; 91 | lowestScore = score; 92 | } else { 93 | if (depth == 0 && score == lowestScore) { 94 | //print("same as so i do what i want", i); 95 | if (random(1) < 0.3) { 96 | lowestBoardNo = i; 97 | } 98 | } 99 | } 100 | if (score < alpha) { 101 | return lowestScore; 102 | } 103 | if (score < beta) { 104 | beta = score; 105 | } 106 | 107 | } 108 | 109 | if (depth == 0) { 110 | ////print(lowestScore); 111 | ////print("i made it here"); 112 | return boards[lowestBoardNo]; 113 | } 114 | ////print("ohNo"); 115 | ////print(lowestScore); 116 | return lowestScore; 117 | } 118 | //--------------------------------------------------------------------------------------- 119 | function maxFunAB(board, alpha, beta, depth) { 120 | if (depth >= maxDepth) { 121 | board.setScore(); 122 | return board.score; 123 | } 124 | 125 | if (board.isDead()) { 126 | if (whiteAI && whitesMove) { 127 | return 200; 128 | } 129 | if (blackAI && !whitesMove) { 130 | return -200; 131 | } 132 | } 133 | 134 | if (board.hasWon()) { 135 | if (whiteAI && whitesMove) { 136 | return -200; 137 | } 138 | if (blackAI && !whitesMove) { 139 | return 200; 140 | } 141 | } 142 | 143 | var boards = board.generateNewBoardsBlacksTurn(); 144 | if (depth == 0) { 145 | //////print(boards); 146 | } 147 | var topBoardNo = 0; 148 | var topScore = -300; 149 | for (var i = 0; i < boards.length; i++) { 150 | 151 | var score = minFunAB(boards[i], alpha, beta, depth + 1); 152 | if (score > topScore) { 153 | topBoardNo = i; 154 | topScore = score; 155 | } else { 156 | if (depth == 0 && score == topScore) { 157 | if (random(1) < 0.3) { 158 | topBoardNo = i; 159 | } 160 | } 161 | } 162 | if (score > beta) { 163 | return topScore; 164 | } 165 | if (score > alpha) { 166 | alpha = score; 167 | } 168 | 169 | } 170 | 171 | if (depth == 0) { 172 | ////print(topScore); 173 | return boards[topBoardNo]; 174 | } 175 | return topScore; 176 | } 177 | -------------------------------------------------------------------------------- /Chess/Piece.js: -------------------------------------------------------------------------------- 1 | class Piece { 2 | constructor(x, y, isWhite, letter, pic) { 3 | this.matrixPosition = createVector(x, y); 4 | this.pixelPosition = createVector(x * tileSize + tileSize / 2, y * 5 | tileSize + tileSize / 2); 6 | 7 | this.taken = false; 8 | this.white = isWhite; 9 | this.letter = letter; 10 | this.pic = pic; 11 | this.movingThisPiece = false; 12 | this.value = 0; 13 | } 14 | 15 | //needs to extend these 16 | show() { 17 | if (!this.taken) { 18 | 19 | // textSize(40); 20 | // strokeWeight(5); 21 | // if(this.white){ 22 | // fill(255); 23 | // stroke(0); 24 | // }else{ 25 | // fill(30); 26 | // stroke(255); 27 | // } 28 | // textAlign(CENTER,CENTER); 29 | imageMode(CENTER); 30 | if (this.movingThisPiece) { 31 | // text(this.letter, mouseX,mouseY); 32 | image(this.pic, mouseX, mouseY, tileSize * 1.5, tileSize * 1.5); 33 | 34 | } else { 35 | // text(this.letter, this.pixelPosition.x,this.pixelPosition.y); 36 | image(this.pic, this.pixelPosition.x, this.pixelPosition.y, tileSize, 37 | tileSize); 38 | 39 | } 40 | } 41 | } 42 | 43 | 44 | generateNewBoards(currentBoard) { 45 | var boards = []; //all boards created from moving this piece 46 | var moves = this.generateMoves(currentBoard); //all the posible moves this piece can do ,as vectors 47 | for (var i = 0; i < moves.length; i++) { //for each move 48 | boards[i] = currentBoard.clone(); //create a new board 49 | boards[i].move(this.matrixPosition, moves[i]); //move this piece to the mvoe location 50 | } 51 | 52 | return boards; 53 | } 54 | 55 | 56 | withinBounds(x, y) { 57 | 58 | if (x >= 0 && y >= 0 && x < 8 && y < 8) { 59 | return true; 60 | } 61 | return false; 62 | 63 | } 64 | 65 | 66 | 67 | move(x, y, board) { 68 | var attacking = board.getPieceAt(x, y); 69 | if (attacking != null) { 70 | attacking.taken = true; 71 | } 72 | this.matrixPosition = createVector(x, y); 73 | this.pixelPosition = createVector(x * tileSize + tileSize / 2, y * 74 | tileSize + tileSize / 2); 75 | 76 | } 77 | attackingAllies(x, y, board) { 78 | var attacking = board.getPieceAt(x, y); 79 | if (attacking != null) { 80 | if (attacking.white == this.white) { 81 | //if they are of the same player 82 | return true; 83 | } 84 | } 85 | return false; 86 | } 87 | canMove(x, y, board) { 88 | if (!this.withinBounds(x, y)) { 89 | return false; 90 | } 91 | return true; 92 | } 93 | 94 | moveThroughPieces(x, y, board) { 95 | var stepDirectionX = x - this.matrixPosition.x; 96 | if (stepDirectionX > 0) { 97 | stepDirectionX = 1; 98 | } else if (stepDirectionX < 0) { 99 | stepDirectionX = -1; 100 | } 101 | var stepDirectionY = y - this.matrixPosition.y; 102 | if (stepDirectionY > 0) { 103 | stepDirectionY = 1; 104 | } else if (stepDirectionY < 0) { 105 | stepDirectionY = -1; 106 | } 107 | var tempPos = createVector(this.matrixPosition.x, this.matrixPosition.y); 108 | tempPos.x += stepDirectionX; 109 | tempPos.y += stepDirectionY; 110 | while (tempPos.x != x || tempPos.y != y) { 111 | 112 | if (board.getPieceAt(tempPos.x, tempPos.y) != null) { 113 | return true; 114 | } 115 | tempPos.x += stepDirectionX; 116 | tempPos.y += stepDirectionY; 117 | } 118 | 119 | return false; 120 | } 121 | 122 | 123 | 124 | } 125 | 126 | class King extends Piece { 127 | constructor(x, y, isWhite) { 128 | super(x, y, isWhite); 129 | this.letter = "K"; 130 | if (isWhite) { 131 | this.pic = images[0]; 132 | 133 | } else { 134 | this.pic = images[6]; 135 | } 136 | this.value = 99; 137 | } 138 | 139 | clone() { 140 | var clone = new King(this.matrixPosition.x, this.matrixPosition.y, this.white); 141 | clone.taken = this.taken; 142 | return clone; 143 | 144 | } 145 | 146 | 147 | 148 | canMove(x, y, board) { 149 | if (!this.withinBounds(x, y)) { 150 | return false; 151 | } 152 | if (this.attackingAllies(x, y, board)) { 153 | return false; 154 | } 155 | if (abs(x - this.matrixPosition.x) <= 1 && abs(y - this.matrixPosition.y) <= 156 | 1) { 157 | return true; 158 | } 159 | return false; 160 | } 161 | 162 | generateMoves(board) { 163 | var moves = []; 164 | for (var i = -1; i < 2; i++) { 165 | for (var j = -1; j < 2; j++) { 166 | var x = this.matrixPosition.x + i; 167 | var y = this.matrixPosition.y + j; 168 | if (this.withinBounds(x, y)) { 169 | if (i != 0 || j != 0) { 170 | if (!this.attackingAllies(x, y, board)) { 171 | moves.push(createVector(x, y)) 172 | } 173 | } 174 | } 175 | } 176 | 177 | } 178 | return moves; 179 | 180 | } 181 | } 182 | 183 | class Queen extends Piece { 184 | constructor(x, y, isWhite) { 185 | super(x, y, isWhite); 186 | this.letter = "Q"; 187 | if (isWhite) { 188 | this.pic = images[1]; 189 | 190 | } else { 191 | this.pic = images[7]; 192 | } 193 | this.value = 9; 194 | 195 | } 196 | canMove(x, y, board) { 197 | if (!this.withinBounds(x, y)) { 198 | return false; 199 | } 200 | if (this.attackingAllies(x, y, board)) { 201 | return false; 202 | } 203 | 204 | if (x == this.matrixPosition.x || y == this.matrixPosition.y) { 205 | if (this.moveThroughPieces(x, y, board)) { 206 | return false; 207 | } 208 | 209 | return true; 210 | } 211 | //diagonal 212 | if (abs(x - this.matrixPosition.x) == abs(y - this.matrixPosition.y)) { 213 | if (this.moveThroughPieces(x, y, board)) { 214 | return false; 215 | } 216 | 217 | return true; 218 | } 219 | return false; 220 | } 221 | generateMoves(board) { 222 | var moves = []; 223 | 224 | //generateHorizontal moves 225 | for (var i = 0; i < 8; i++) { 226 | var x = i; 227 | var y = this.matrixPosition.y; 228 | if (x != this.matrixPosition.x) { 229 | if (!this.attackingAllies(x, y, board)) { 230 | if (!this.moveThroughPieces(x, y, board)) { 231 | moves.push(createVector(x, y)); 232 | } 233 | } 234 | } 235 | } 236 | //generateVertical moves 237 | for (var i = 0; i < 8; i++) { 238 | var x = this.matrixPosition.x;; 239 | var y = i; 240 | if (i != this.matrixPosition.y) { 241 | if (!this.attackingAllies(x, y, board)) { 242 | if (!this.moveThroughPieces(x, y, board)) { 243 | moves.push(createVector(x, y)); 244 | } 245 | } 246 | } 247 | } 248 | 249 | //generateDiagonal Moves 250 | for (var i = 0; i < 8; i++) { 251 | var x = i; 252 | var y = this.matrixPosition.y - (this.matrixPosition.x - i); 253 | if (x != this.matrixPosition.x) { 254 | if (this.withinBounds(x, y)) { 255 | if (!this.attackingAllies(x, y, board)) { 256 | if (!this.moveThroughPieces(x, y, board)) { 257 | moves.push(createVector(x, y)); 258 | } 259 | } 260 | } 261 | } 262 | } 263 | 264 | for (var i = 0; i < 8; i++) { 265 | var x = this.matrixPosition.x + (this.matrixPosition.y - i); 266 | var y = i; 267 | if (x != this.matrixPosition.x) { 268 | if (this.withinBounds(x, y)) { 269 | if (!this.attackingAllies(x, y, board)) { 270 | if (!this.moveThroughPieces(x, y, board)) { 271 | moves.push(createVector(x, y)); 272 | } 273 | } 274 | } 275 | } 276 | } 277 | //print("Queen", moves); 278 | return moves; 279 | } 280 | clone() { 281 | var clone = new Queen(this.matrixPosition.x, this.matrixPosition.y, 282 | this.white); 283 | clone.taken = this.taken; 284 | return clone; 285 | 286 | } 287 | } 288 | class Bishop extends Piece { 289 | constructor(x, y, isWhite) { 290 | super(x, y, isWhite); 291 | this.letter = "B"; 292 | if (isWhite) { 293 | this.pic = images[2]; 294 | 295 | } else { 296 | this.pic = images[8]; 297 | } 298 | this.value = 3; 299 | 300 | } 301 | canMove(x, y, board) { 302 | if (!this.withinBounds(x, y)) { 303 | return false; 304 | } 305 | if (this.attackingAllies(x, y, board)) { 306 | return false; 307 | } 308 | 309 | 310 | //diagonal 311 | if (abs(x - this.matrixPosition.x) == abs(y - this.matrixPosition.y)) { 312 | if (this.moveThroughPieces(x, y, board)) { 313 | return false; 314 | } 315 | 316 | return true; 317 | } 318 | return false; 319 | } 320 | 321 | generateMoves(board) { 322 | var moves = []; 323 | //generateDiagonal Moves 324 | for (var i = 0; i < 8; i++) { 325 | var x = i; 326 | var y = this.matrixPosition.y - (this.matrixPosition.x - i); 327 | if (x != this.matrixPosition.x) { 328 | if (this.withinBounds(x, y)) { 329 | if (!this.attackingAllies(x, y, board)) { 330 | if (!this.moveThroughPieces(x, y, board)) { 331 | moves.push(createVector(x, y)); 332 | } 333 | } 334 | } 335 | } 336 | } 337 | 338 | for (var i = 0; i < 8; i++) { 339 | var x = this.matrixPosition.x + (this.matrixPosition.y - i); 340 | var y = i; 341 | if (x != this.matrixPosition.x) { 342 | if (this.withinBounds(x, y)) { 343 | if (!this.attackingAllies(x, y, board)) { 344 | if (!this.moveThroughPieces(x, y, board)) { 345 | moves.push(createVector(x, y)); 346 | } 347 | } 348 | } 349 | } 350 | } 351 | //print("Bishop", moves); 352 | 353 | return moves; 354 | } 355 | clone() { 356 | var clone = new Bishop(this.matrixPosition.x, this.matrixPosition.y, 357 | this.white); 358 | clone.taken = this.taken; 359 | return clone; 360 | 361 | } 362 | } 363 | class Rook extends Piece { 364 | constructor(x, y, isWhite) { 365 | super(x, y, isWhite); 366 | this.letter = "R"; 367 | if (isWhite) { 368 | this.pic = images[4]; 369 | 370 | } else { 371 | this.pic = images[10]; 372 | } 373 | this.value = 5; 374 | 375 | } 376 | canMove(x, y, board) { 377 | if (!this.withinBounds(x, y)) { 378 | return false; 379 | } 380 | if (this.attackingAllies(x, y, board)) { 381 | return false; 382 | } 383 | 384 | 385 | if (x == this.matrixPosition.x || y == this.matrixPosition.y) { 386 | if (this.moveThroughPieces(x, y, board)) { 387 | return false; 388 | } 389 | 390 | return true; 391 | } 392 | return false; 393 | } 394 | 395 | generateMoves(board) { 396 | var moves = []; 397 | 398 | //generateHorizontal moves 399 | for (var i = 0; i < 8; i++) { 400 | var x = i; 401 | var y = this.matrixPosition.y; 402 | if (x != this.matrixPosition.x) { 403 | if (!this.attackingAllies(x, y, board)) { 404 | if (!this.moveThroughPieces(x, y, board)) { 405 | moves.push(createVector(x, y)); 406 | } 407 | } 408 | } 409 | } 410 | //generateVertical moves 411 | for (var i = 0; i < 8; i++) { 412 | var x = this.matrixPosition.x;; 413 | var y = i; 414 | if (i != this.matrixPosition.y) { 415 | if (!this.attackingAllies(x, y, board)) { 416 | if (!this.moveThroughPieces(x, y, board)) { 417 | moves.push(createVector(x, y)); 418 | } 419 | } 420 | } 421 | } 422 | //print("Rook", moves); 423 | 424 | return moves; 425 | 426 | 427 | } 428 | 429 | clone() { 430 | var clone = new Rook(this.matrixPosition.x, this.matrixPosition.y, this 431 | .white); 432 | clone.taken = this.taken; 433 | return clone; 434 | 435 | } 436 | } 437 | class Knight extends Piece { 438 | constructor(x, y, isWhite) { 439 | super(x, y, isWhite); 440 | this.letter = "Kn"; 441 | if (isWhite) { 442 | this.pic = images[3]; 443 | 444 | } else { 445 | this.pic = images[9]; 446 | } 447 | this.value = 3; 448 | 449 | } 450 | 451 | canMove(x, y, board) { 452 | if (!this.withinBounds(x, y)) { 453 | return false; 454 | } 455 | if (this.attackingAllies(x, y, board)) { 456 | return false; 457 | } 458 | 459 | 460 | if ((abs(x - this.matrixPosition.x) == 2 && abs(y - this.matrixPosition 461 | .y) == 1) || (abs(x - this.matrixPosition.x) == 1 && abs(y - this.matrixPosition 462 | .y) == 2)) { 463 | return true; 464 | } 465 | return false; 466 | } 467 | 468 | 469 | 470 | generateMoves(board) { 471 | var moves = []; 472 | for (var i = -2; i < 3; i += 4) { 473 | for (var j = -1; j < 2; j += 2) { 474 | 475 | var x = i + this.matrixPosition.x; 476 | var y = j + this.matrixPosition.y; 477 | if (!this.attackingAllies(x, y, board)) { 478 | if (this.withinBounds(x, y)) { 479 | moves.push(createVector(x, y)); 480 | 481 | } 482 | } 483 | } 484 | } 485 | for (var i = -1; i < 2; i += 2) { 486 | for (var j = -2; j < 3; j += 4) { 487 | 488 | var x = i + this.matrixPosition.x; 489 | var y = j + this.matrixPosition.y; 490 | 491 | if (this.withinBounds(x, y)) { 492 | if (!this.attackingAllies(x, y, board)) { 493 | moves.push(createVector(x, y)); 494 | 495 | } 496 | } 497 | } 498 | } 499 | //print("Knight", moves); 500 | 501 | return moves; 502 | 503 | } 504 | clone() { 505 | var clone = new Knight(this.matrixPosition.x, this.matrixPosition.y, 506 | this.white); 507 | clone.taken = this.taken; 508 | return clone; 509 | 510 | } 511 | } 512 | class Pawn extends Piece { 513 | constructor(x, y, isWhite) { 514 | super(x, y, isWhite); 515 | this.letter = "p"; 516 | this.firstTurn = true; 517 | if (isWhite) { 518 | this.pic = images[5]; 519 | 520 | } else { 521 | this.pic = images[11]; 522 | } 523 | this.value = 1; 524 | 525 | } 526 | 527 | canMove(x, y, board) { 528 | if (!this.withinBounds(x, y)) { 529 | return false; 530 | } 531 | if (this.attackingAllies(x, y, board)) { 532 | return false; 533 | } 534 | var attacking = board.isPieceAt(x, y); 535 | if (attacking) { 536 | //if attacking a player 537 | if (abs(x - this.matrixPosition.x) == abs(y - this.matrixPosition.y) && 538 | ((this.white && (y - this.matrixPosition.y) == -1) || (!this.white && 539 | (y - this.matrixPosition.y) == 1))) { 540 | this.firstTurn = false; 541 | return true; 542 | } 543 | return false; 544 | } 545 | if (x != this.matrixPosition.x) { 546 | return false; 547 | } 548 | if ((this.white && y - this.matrixPosition.y == -1) || (!this.white && 549 | y - this.matrixPosition.y == 1)) { 550 | this.firstTurn = false; 551 | return true; 552 | } 553 | if (this.firstTurn && ((this.white && y - this.matrixPosition.y == -2) || 554 | (!this.white && y - this.matrixPosition.y == 2))) { 555 | if (this.moveThroughPieces(x, y, board)) { 556 | return false; 557 | } 558 | 559 | this.firstTurn = false; 560 | return true; 561 | } 562 | return false; 563 | } 564 | 565 | 566 | generateMoves(board) { 567 | var moves = []; 568 | 569 | for (var i = -1; i < 2; i += 2) { 570 | var x = this.matrixPosition.x + i; 571 | if (this.white) { 572 | var y = this.matrixPosition.y - 1; 573 | } else { 574 | var y = this.matrixPosition.y + 1; 575 | } 576 | var attacking = board.getPieceAt(x, y); 577 | if (attacking) { 578 | if (!this.attackingAllies(x, y, board)) { 579 | moves.push(createVector(x, y)); 580 | } 581 | } 582 | } 583 | 584 | var x = this.matrixPosition.x; 585 | if (this.white) { 586 | var y = this.matrixPosition.y - 1; 587 | } else { 588 | var y = this.matrixPosition.y + 1; 589 | } 590 | if (!board.isPieceAt(x, y) && this.withinBounds(x, y)) { 591 | moves.push(createVector(x, y)); 592 | } 593 | 594 | if (this.firstTurn) { 595 | 596 | if (this.white) { 597 | var y = this.matrixPosition.y - 2; 598 | } else { 599 | var y = this.matrixPosition.y + 2; 600 | } 601 | if (!board.isPieceAt(x, y) && this.withinBounds(x, y)) { 602 | if (!this.moveThroughPieces(x, y, board)) { 603 | moves.push(createVector(x, y)); 604 | } 605 | } 606 | } 607 | //print("pawn", moves); 608 | return moves; 609 | } 610 | clone() { 611 | var clone = new Pawn(this.matrixPosition.x, this.matrixPosition.y, this 612 | .white); 613 | clone.taken = this.taken; 614 | clone.firstTurn = this.firstTurn; 615 | return clone; 616 | } 617 | 618 | move(x, y, board) { 619 | var attacking = board.getPieceAt(x, y); 620 | if (attacking != null) { 621 | attacking.taken = true; 622 | } 623 | this.matrixPosition = createVector(x, y); 624 | this.pixelPosition = createVector(x * tileSize + tileSize / 2, y * 625 | tileSize + tileSize / 2); 626 | this.firstTurn = false; 627 | } 628 | } 629 | -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_01.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_02.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_03.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_04.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_05.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_06.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_07.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_08.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_09.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_10.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_11.png -------------------------------------------------------------------------------- /Chess/assets/2000px-Chess_Pieces_Sprite_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Bullet/Chess-AI/c5910012ab15126aca1a211e268fcb350d48df59/Chess/assets/2000px-Chess_Pieces_Sprite_12.png -------------------------------------------------------------------------------- /Chess/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Chess/libraries/p5.dom.js: -------------------------------------------------------------------------------- 1 | /*! p5.dom.js v0.3.2 March 25, 2017 */ 2 | /** 3 | *

The web is much more than just canvas and p5.dom makes it easy to interact 4 | * with other HTML5 objects, including text, hyperlink, image, input, video, 5 | * audio, and webcam.

6 | *

There is a set of creation methods, DOM manipulation methods, and 7 | * an extended p5.Element that supports a range of HTML elements. See the 8 | * 9 | * beyond the canvas tutorial for a full overview of how this addon works. 10 | * 11 | *

Methods and properties shown in black are part of the p5.js core, items in 12 | * blue are part of the p5.dom library. You will need to include an extra file 13 | * in order to access the blue functions. See the 14 | * using a library 15 | * section for information on how to include this library. p5.dom comes with 16 | * p5 complete or you can download the single file 17 | * 18 | * here.

19 | *

See tutorial: beyond the canvas 20 | * for more info on how to use this libary. 21 | * 22 | * @module p5.dom 23 | * @submodule p5.dom 24 | * @for p5.dom 25 | * @main 26 | */ 27 | 28 | (function (root, factory) { 29 | if (typeof define === 'function' && define.amd) 30 | define('p5.dom', ['p5'], function (p5) { (factory(p5));}); 31 | else if (typeof exports === 'object') 32 | factory(require('../p5')); 33 | else 34 | factory(root['p5']); 35 | }(this, function (p5) { 36 | 37 | // ============================================================================= 38 | // p5 additions 39 | // ============================================================================= 40 | 41 | /** 42 | * Searches the page for an element with the given ID, class, or tag name (using the '#' or '.' 43 | * prefixes to specify an ID or class respectively, and none for a tag) and returns it as 44 | * a p5.Element. If a class or tag name is given with more than 1 element, 45 | * only the first element will be returned. 46 | * The DOM node itself can be accessed with .elt. 47 | * Returns null if none found. You can also specify a container to search within. 48 | * 49 | * @method select 50 | * @param {String} name id, class, or tag name of element to search for 51 | * @param {String} [container] id, p5.Element, or HTML element to search within 52 | * @return {Object|p5.Element|Null} p5.Element containing node found 53 | * @example 54 | *

55 | * function setup() { 56 | * createCanvas(100,100); 57 | * //translates canvas 50px down 58 | * select('canvas').position(100, 100); 59 | * } 60 | *
61 | *
62 | * // these are all valid calls to select() 63 | * var a = select('#moo'); 64 | * var b = select('#blah', '#myContainer'); 65 | * var c = select('#foo', b); 66 | * var d = document.getElementById('beep'); 67 | * var e = select('p', d); 68 | *
69 | * 70 | */ 71 | p5.prototype.select = function (e, p) { 72 | var res = null; 73 | var container = getContainer(p); 74 | if (e[0] === '.'){ 75 | e = e.slice(1); 76 | res = container.getElementsByClassName(e); 77 | if (res.length) { 78 | res = res[0]; 79 | } else { 80 | res = null; 81 | } 82 | }else if (e[0] === '#'){ 83 | e = e.slice(1); 84 | res = container.getElementById(e); 85 | }else { 86 | res = container.getElementsByTagName(e); 87 | if (res.length) { 88 | res = res[0]; 89 | } else { 90 | res = null; 91 | } 92 | } 93 | if (res) { 94 | return wrapElement(res); 95 | } else { 96 | return null; 97 | } 98 | }; 99 | 100 | /** 101 | * Searches the page for elements with the given class or tag name (using the '.' prefix 102 | * to specify a class and no prefix for a tag) and returns them as p5.Elements 103 | * in an array. 104 | * The DOM node itself can be accessed with .elt. 105 | * Returns an empty array if none found. 106 | * You can also specify a container to search within. 107 | * 108 | * @method selectAll 109 | * @param {String} name class or tag name of elements to search for 110 | * @param {String} [container] id, p5.Element, or HTML element to search within 111 | * @return {Array} Array of p5.Elements containing nodes found 112 | * @example 113 | *
114 | * function setup() { 115 | * createButton('btn'); 116 | * createButton('2nd btn'); 117 | * createButton('3rd btn'); 118 | * var buttons = selectAll('button'); 119 | * 120 | * for (var i = 0; i < buttons.length; i++){ 121 | * buttons[i].size(100,100); 122 | * } 123 | * } 124 | *
125 | *
126 | * // these are all valid calls to selectAll() 127 | * var a = selectAll('.moo'); 128 | * var b = selectAll('div'); 129 | * var c = selectAll('button', '#myContainer'); 130 | * var d = select('#container'); 131 | * var e = selectAll('p', d); 132 | * var f = document.getElementById('beep'); 133 | * var g = select('.blah', f); 134 | *
135 | * 136 | */ 137 | p5.prototype.selectAll = function (e, p) { 138 | var arr = []; 139 | var res; 140 | var container = getContainer(p); 141 | if (e[0] === '.'){ 142 | e = e.slice(1); 143 | res = container.getElementsByClassName(e); 144 | } else { 145 | res = container.getElementsByTagName(e); 146 | } 147 | if (res) { 148 | for (var j = 0; j < res.length; j++) { 149 | var obj = wrapElement(res[j]); 150 | arr.push(obj); 151 | } 152 | } 153 | return arr; 154 | }; 155 | 156 | /** 157 | * Helper function for select and selectAll 158 | */ 159 | function getContainer(p) { 160 | var container = document; 161 | if (typeof p === 'string' && p[0] === '#'){ 162 | p = p.slice(1); 163 | container = document.getElementById(p) || document; 164 | } else if (p instanceof p5.Element){ 165 | container = p.elt; 166 | } else if (p instanceof HTMLElement){ 167 | container = p; 168 | } 169 | return container; 170 | } 171 | 172 | /** 173 | * Helper function for getElement and getElements. 174 | */ 175 | function wrapElement(elt) { 176 | if(elt.tagName === "INPUT" && elt.type === "checkbox") { 177 | var converted = new p5.Element(elt); 178 | converted.checked = function(){ 179 | if (arguments.length === 0){ 180 | return this.elt.checked; 181 | } else if(arguments[0]) { 182 | this.elt.checked = true; 183 | } else { 184 | this.elt.checked = false; 185 | } 186 | return this; 187 | }; 188 | return converted; 189 | } else if (elt.tagName === "VIDEO" || elt.tagName === "AUDIO") { 190 | return new p5.MediaElement(elt); 191 | } else { 192 | return new p5.Element(elt); 193 | } 194 | } 195 | 196 | /** 197 | * Removes all elements created by p5, except any canvas / graphics 198 | * elements created by createCanvas or createGraphics. 199 | * Event handlers are removed, and element is removed from the DOM. 200 | * @method removeElements 201 | * @example 202 | *
203 | * function setup() { 204 | * createCanvas(100, 100); 205 | * createDiv('this is some text'); 206 | * createP('this is a paragraph'); 207 | * } 208 | * function mousePressed() { 209 | * removeElements(); // this will remove the div and p, not canvas 210 | * } 211 | *
212 | * 213 | */ 214 | p5.prototype.removeElements = function (e) { 215 | for (var i=0; i 243 | * var myDiv; 244 | * function setup() { 245 | * myDiv = createDiv('this is some text'); 246 | * } 247 | * 248 | */ 249 | 250 | /** 251 | * Creates a <p></p> element in the DOM with given inner HTML. Used 252 | * for paragraph length text. 253 | * Appends to the container node if one is specified, otherwise 254 | * appends to body. 255 | * 256 | * @method createP 257 | * @param {String} html inner HTML for element created 258 | * @return {Object|p5.Element} pointer to p5.Element holding created node 259 | * @example 260 | *
261 | * var myP; 262 | * function setup() { 263 | * myP = createP('this is some text'); 264 | * } 265 | *
266 | */ 267 | 268 | /** 269 | * Creates a <span></span> element in the DOM with given inner HTML. 270 | * Appends to the container node if one is specified, otherwise 271 | * appends to body. 272 | * 273 | * @method createSpan 274 | * @param {String} html inner HTML for element created 275 | * @return {Object|p5.Element} pointer to p5.Element holding created node 276 | * @example 277 | *
278 | * var mySpan; 279 | * function setup() { 280 | * mySpan = createSpan('this is some text'); 281 | * } 282 | *
283 | */ 284 | var tags = ['div', 'p', 'span']; 285 | tags.forEach(function(tag) { 286 | var method = 'create' + tag.charAt(0).toUpperCase() + tag.slice(1); 287 | p5.prototype[method] = function(html) { 288 | var elt = document.createElement(tag); 289 | elt.innerHTML = typeof html === undefined ? "" : html; 290 | return addElement(elt, this); 291 | } 292 | }); 293 | 294 | /** 295 | * Creates an <img> element in the DOM with given src and 296 | * alternate text. 297 | * Appends to the container node if one is specified, otherwise 298 | * appends to body. 299 | * 300 | * @method createImg 301 | * @param {String} src src path or url for image 302 | * @param {String} [alt] alternate text to be used if image does not load 303 | * @param {Function} [successCallback] callback to be called once image data is loaded 304 | * @return {Object|p5.Element} pointer to p5.Element holding created node 305 | * @example 306 | *
307 | * var img; 308 | * function setup() { 309 | * img = createImg('http://p5js.org/img/asterisk-01.png'); 310 | * } 311 | *
312 | */ 313 | p5.prototype.createImg = function() { 314 | var elt = document.createElement('img'); 315 | var args = arguments; 316 | var self; 317 | var setAttrs = function(){ 318 | self.width = elt.offsetWidth || elt.width; 319 | self.height = elt.offsetHeight || elt.height; 320 | if (args.length > 1 && typeof args[1] === 'function'){ 321 | self.fn = args[1]; 322 | self.fn(); 323 | }else if (args.length > 1 && typeof args[2] === 'function'){ 324 | self.fn = args[2]; 325 | self.fn(); 326 | } 327 | }; 328 | elt.src = args[0]; 329 | if (args.length > 1 && typeof args[1] === 'string'){ 330 | elt.alt = args[1]; 331 | } 332 | elt.onload = function(){ 333 | setAttrs(); 334 | } 335 | self = addElement(elt, this); 336 | return self; 337 | }; 338 | 339 | /** 340 | * Creates an <a></a> element in the DOM for including a hyperlink. 341 | * Appends to the container node if one is specified, otherwise 342 | * appends to body. 343 | * 344 | * @method createA 345 | * @param {String} href url of page to link to 346 | * @param {String} html inner html of link element to display 347 | * @param {String} [target] target where new link should open, 348 | * could be _blank, _self, _parent, _top. 349 | * @return {Object|p5.Element} pointer to p5.Element holding created node 350 | * @example 351 | *
352 | * var myLink; 353 | * function setup() { 354 | * myLink = createA('http://p5js.org/', 'this is a link'); 355 | * } 356 | *
357 | */ 358 | p5.prototype.createA = function(href, html, target) { 359 | var elt = document.createElement('a'); 360 | elt.href = href; 361 | elt.innerHTML = html; 362 | if (target) elt.target = target; 363 | return addElement(elt, this); 364 | }; 365 | 366 | /** INPUT **/ 367 | 368 | 369 | /** 370 | * Creates a slider <input></input> element in the DOM. 371 | * Use .size() to set the display length of the slider. 372 | * Appends to the container node if one is specified, otherwise 373 | * appends to body. 374 | * 375 | * @method createSlider 376 | * @param {Number} min minimum value of the slider 377 | * @param {Number} max maximum value of the slider 378 | * @param {Number} [value] default value of the slider 379 | * @param {Number} [step] step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value) 380 | * @return {Object|p5.Element} pointer to p5.Element holding created node 381 | * @example 382 | *
383 | * var slider; 384 | * function setup() { 385 | * slider = createSlider(0, 255, 100); 386 | * slider.position(10, 10); 387 | * slider.style('width', '80px'); 388 | * } 389 | * 390 | * function draw() { 391 | * var val = slider.value(); 392 | * background(val); 393 | * } 394 | *
395 | * 396 | *
397 | * var slider; 398 | * function setup() { 399 | * colorMode(HSB); 400 | * slider = createSlider(0, 360, 60, 40); 401 | * slider.position(10, 10); 402 | * slider.style('width', '80px'); 403 | * } 404 | * 405 | * function draw() { 406 | * var val = slider.value(); 407 | * background(val, 100, 100, 1); 408 | * } 409 | *
410 | */ 411 | p5.prototype.createSlider = function(min, max, value, step) { 412 | var elt = document.createElement('input'); 413 | elt.type = 'range'; 414 | elt.min = min; 415 | elt.max = max; 416 | if (step === 0) { 417 | elt.step = .000000000000000001; // smallest valid step 418 | } else if (step) { 419 | elt.step = step; 420 | } 421 | if (typeof(value) === "number") elt.value = value; 422 | return addElement(elt, this); 423 | }; 424 | 425 | /** 426 | * Creates a <button></button> element in the DOM. 427 | * Use .size() to set the display size of the button. 428 | * Use .mousePressed() to specify behavior on press. 429 | * Appends to the container node if one is specified, otherwise 430 | * appends to body. 431 | * 432 | * @method createButton 433 | * @param {String} label label displayed on the button 434 | * @param {String} [value] value of the button 435 | * @return {Object|p5.Element} pointer to p5.Element holding created node 436 | * @example 437 | *
438 | * var button; 439 | * function setup() { 440 | * createCanvas(100, 100); 441 | * background(0); 442 | * button = createButton('click me'); 443 | * button.position(19, 19); 444 | * button.mousePressed(changeBG); 445 | * } 446 | * 447 | * function changeBG() { 448 | * var val = random(255); 449 | * background(val); 450 | * } 451 | *
452 | */ 453 | p5.prototype.createButton = function(label, value) { 454 | var elt = document.createElement('button'); 455 | elt.innerHTML = label; 456 | elt.value = value; 457 | if (value) elt.value = value; 458 | return addElement(elt, this); 459 | }; 460 | 461 | /** 462 | * Creates a checkbox <input></input> element in the DOM. 463 | * Calling .checked() on a checkbox returns if it is checked or not 464 | * 465 | * @method createCheckbox 466 | * @param {String} [label] label displayed after checkbox 467 | * @param {boolean} [value] value of the checkbox; checked is true, unchecked is false.Unchecked if no value given 468 | * @return {Object|p5.Element} pointer to p5.Element holding created node 469 | * @example 470 | *
471 | * var checkbox; 472 | * 473 | * function setup() { 474 | * checkbox = createCheckbox('label', false); 475 | * checkbox.changed(myCheckedEvent); 476 | * } 477 | * 478 | * function myCheckedEvent() { 479 | * if (this.checked()) { 480 | * console.log("Checking!"); 481 | * } else { 482 | * console.log("Unchecking!"); 483 | * } 484 | * } 485 | *
486 | */ 487 | p5.prototype.createCheckbox = function() { 488 | var elt = document.createElement('div'); 489 | var checkbox = document.createElement('input'); 490 | checkbox.type = 'checkbox'; 491 | elt.appendChild(checkbox); 492 | //checkbox must be wrapped in p5.Element before label so that label appears after 493 | var self = addElement(elt, this); 494 | self.checked = function(){ 495 | var cb = self.elt.getElementsByTagName('input')[0]; 496 | if (cb) { 497 | if (arguments.length === 0){ 498 | return cb.checked; 499 | }else if(arguments[0]){ 500 | cb.checked = true; 501 | }else{ 502 | cb.checked = false; 503 | } 504 | } 505 | return self; 506 | }; 507 | this.value = function(val){ 508 | self.value = val; 509 | return this; 510 | }; 511 | if (arguments[0]){ 512 | var ran = Math.random().toString(36).slice(2); 513 | var label = document.createElement('label'); 514 | checkbox.setAttribute('id', ran); 515 | label.htmlFor = ran; 516 | self.value(arguments[0]); 517 | label.appendChild(document.createTextNode(arguments[0])); 518 | elt.appendChild(label); 519 | } 520 | if (arguments[1]){ 521 | checkbox.checked = true; 522 | } 523 | return self; 524 | }; 525 | 526 | /** 527 | * Creates a dropdown menu <select></select> element in the DOM. 528 | * @method createSelect 529 | * @param {boolean} [multiple] true if dropdown should support multiple selections 530 | * @return {Object|p5.Element} pointer to p5.Element holding created node 531 | * @example 532 | *
533 | * var sel; 534 | * 535 | * function setup() { 536 | * textAlign(CENTER); 537 | * background(200); 538 | * sel = createSelect(); 539 | * sel.position(10, 10); 540 | * sel.option('pear'); 541 | * sel.option('kiwi'); 542 | * sel.option('grape'); 543 | * sel.changed(mySelectEvent); 544 | * } 545 | * 546 | * function mySelectEvent() { 547 | * var item = sel.value(); 548 | * background(200); 549 | * text("it's a "+item+"!", 50, 50); 550 | * } 551 | *
552 | */ 553 | p5.prototype.createSelect = function(mult) { 554 | var elt = document.createElement('select'); 555 | if (mult){ 556 | elt.setAttribute('multiple', 'true'); 557 | } 558 | var self = addElement(elt, this); 559 | self.option = function(name, value){ 560 | var opt = document.createElement('option'); 561 | opt.innerHTML = name; 562 | if (arguments.length > 1) 563 | opt.value = value; 564 | else 565 | opt.value = name; 566 | elt.appendChild(opt); 567 | }; 568 | self.selected = function(value){ 569 | var arr = []; 570 | if (arguments.length > 0){ 571 | for (var i = 0; i < this.elt.length; i++){ 572 | if (value.toString() === this.elt[i].value){ 573 | this.elt.selectedIndex = i; 574 | } 575 | } 576 | return this; 577 | }else{ 578 | if (mult){ 579 | for (var i = 0; i < this.elt.selectedOptions.length; i++){ 580 | arr.push(this.elt.selectedOptions[i].value); 581 | } 582 | return arr; 583 | }else{ 584 | return this.elt.value; 585 | } 586 | } 587 | }; 588 | return self; 589 | }; 590 | 591 | /** 592 | * Creates a radio button <input></input> element in the DOM. 593 | * The .option() method can be used to set options for the radio after it is 594 | * created. The .value() method will return the currently selected option. 595 | * 596 | * @method createRadio 597 | * @param {String} [divId] the id and name of the created div and input field respectively 598 | * @return {Object|p5.Element} pointer to p5.Element holding created node 599 | * @example 600 | *
601 | * var radio; 602 | * 603 | * function setup() { 604 | * radio = createRadio(); 605 | * radio.option("black"); 606 | * radio.option("white"); 607 | * radio.option("gray"); 608 | * radio.style('width', '60px'); 609 | * textAlign(CENTER); 610 | * fill(255, 0, 0); 611 | * } 612 | * 613 | * function draw() { 614 | * var val = radio.value(); 615 | * background(val); 616 | * text(val, width/2, height/2); 617 | * } 618 | *
619 | *
620 | * var radio; 621 | * 622 | * function setup() { 623 | * radio = createRadio(); 624 | * radio.option('apple', 1); 625 | * radio.option('bread', 2); 626 | * radio.option('juice', 3); 627 | * radio.style('width', '60px'); 628 | * textAlign(CENTER); 629 | * } 630 | * 631 | * function draw() { 632 | * background(200); 633 | * var val = radio.value(); 634 | * if (val) { 635 | * text('item cost is $'+val, width/2, height/2); 636 | * } 637 | * } 638 | *
639 | */ 640 | p5.prototype.createRadio = function() { 641 | var radios = document.querySelectorAll("input[type=radio]"); 642 | var count = 0; 643 | if(radios.length > 1){ 644 | var length = radios.length; 645 | var prev=radios[0].name; 646 | var current = radios[1].name; 647 | count = 1; 648 | for(var i = 1; i < length; i++) { 649 | current = radios[i].name; 650 | if(prev != current){ 651 | count++; 652 | } 653 | prev = current; 654 | } 655 | } 656 | else if (radios.length == 1){ 657 | count = 1; 658 | } 659 | var elt = document.createElement('div'); 660 | var self = addElement(elt, this); 661 | var times = -1; 662 | self.option = function(name, value){ 663 | var opt = document.createElement('input'); 664 | opt.type = 'radio'; 665 | opt.innerHTML = name; 666 | if (arguments.length > 1) 667 | opt.value = value; 668 | else 669 | opt.value = name; 670 | opt.setAttribute('name',"defaultradio"+count); 671 | elt.appendChild(opt); 672 | if (name){ 673 | times++; 674 | var ran = Math.random().toString(36).slice(2); 675 | var label = document.createElement('label'); 676 | opt.setAttribute('id', "defaultradio"+count+"-"+times); 677 | label.htmlFor = "defaultradio"+count+"-"+times; 678 | label.appendChild(document.createTextNode(name)); 679 | elt.appendChild(label); 680 | } 681 | return opt; 682 | }; 683 | self.selected = function(){ 684 | var length = this.elt.childNodes.length; 685 | if(arguments.length == 1) { 686 | for (var i = 0; i < length; i+=2){ 687 | if(this.elt.childNodes[i].value == arguments[0]) 688 | this.elt.childNodes[i].checked = true; 689 | } 690 | return this; 691 | } else { 692 | for (var i = 0; i < length; i+=2){ 693 | if(this.elt.childNodes[i].checked == true) 694 | return this.elt.childNodes[i].value; 695 | } 696 | } 697 | }; 698 | self.value = function(){ 699 | var length = this.elt.childNodes.length; 700 | if(arguments.length == 1) { 701 | for (var i = 0; i < length; i+=2){ 702 | if(this.elt.childNodes[i].value == arguments[0]) 703 | this.elt.childNodes[i].checked = true; 704 | } 705 | return this; 706 | } else { 707 | for (var i = 0; i < length; i+=2){ 708 | if(this.elt.childNodes[i].checked == true) 709 | return this.elt.childNodes[i].value; 710 | } 711 | return ""; 712 | } 713 | }; 714 | return self 715 | }; 716 | 717 | /** 718 | * Creates an <input></input> element in the DOM for text input. 719 | * Use .size() to set the display length of the box. 720 | * Appends to the container node if one is specified, otherwise 721 | * appends to body. 722 | * 723 | * @method createInput 724 | * @param {Number} [value] default value of the input box 725 | * @param {String} [type] type of text, ie text, password etc. Defaults to text 726 | * @return {Object|p5.Element} pointer to p5.Element holding created node 727 | * @example 728 | *
729 | * function setup(){ 730 | * var inp = createInput(''); 731 | * inp.input(myInputEvent); 732 | * } 733 | * 734 | * function myInputEvent(){ 735 | * console.log('you are typing: ', this.value()); 736 | * } 737 | * 738 | *
739 | */ 740 | p5.prototype.createInput = function(value, type) { 741 | var elt = document.createElement('input'); 742 | elt.type = type ? type : 'text'; 743 | if (value) elt.value = value; 744 | return addElement(elt, this); 745 | }; 746 | 747 | /** 748 | * Creates an <input></input> element in the DOM of type 'file'. 749 | * This allows users to select local files for use in a sketch. 750 | * 751 | * @method createFileInput 752 | * @param {Function} [callback] callback function for when a file loaded 753 | * @param {String} [multiple] optional to allow multiple files selected 754 | * @return {Object|p5.Element} pointer to p5.Element holding created DOM element 755 | * @example 756 | * var input; 757 | * var img; 758 | * 759 | * function setup() { 760 | * input = createFileInput(handleFile); 761 | * input.position(0, 0); 762 | * } 763 | * 764 | * function draw() { 765 | * if (img) { 766 | * image(img, 0, 0, width, height); 767 | * } 768 | * } 769 | * 770 | * function handleFile(file) { 771 | * print(file); 772 | * if (file.type === 'image') { 773 | * img = createImg(file.data); 774 | * img.hide(); 775 | * } 776 | * } 777 | */ 778 | p5.prototype.createFileInput = function(callback, multiple) { 779 | 780 | // Is the file stuff supported? 781 | if (window.File && window.FileReader && window.FileList && window.Blob) { 782 | // Yup, we're ok and make an input file selector 783 | var elt = document.createElement('input'); 784 | elt.type = 'file'; 785 | 786 | // If we get a second argument that evaluates to true 787 | // then we are looking for multiple files 788 | if (multiple) { 789 | // Anything gets the job done 790 | elt.multiple = 'multiple'; 791 | } 792 | 793 | // Function to handle when a file is selected 794 | // We're simplifying life and assuming that we always 795 | // want to load every selected file 796 | function handleFileSelect(evt) { 797 | // These are the files 798 | var files = evt.target.files; 799 | // Load each one and trigger a callback 800 | for (var i = 0; i < files.length; i++) { 801 | var f = files[i]; 802 | var reader = new FileReader(); 803 | function makeLoader(theFile) { 804 | // Making a p5.File object 805 | var p5file = new p5.File(theFile); 806 | return function(e) { 807 | p5file.data = e.target.result; 808 | callback(p5file); 809 | }; 810 | }; 811 | reader.onload = makeLoader(f); 812 | 813 | // Text or data? 814 | // This should likely be improved 815 | if (f.type.indexOf('text') > -1) { 816 | reader.readAsText(f); 817 | } else { 818 | reader.readAsDataURL(f); 819 | } 820 | } 821 | } 822 | 823 | // Now let's handle when a file was selected 824 | elt.addEventListener('change', handleFileSelect, false); 825 | return addElement(elt, this); 826 | } else { 827 | console.log('The File APIs are not fully supported in this browser. Cannot create element.'); 828 | } 829 | }; 830 | 831 | 832 | /** VIDEO STUFF **/ 833 | 834 | function createMedia(pInst, type, src, callback) { 835 | var elt = document.createElement(type); 836 | 837 | // allow src to be empty 838 | var src = src || ''; 839 | if (typeof src === 'string') { 840 | src = [src]; 841 | } 842 | for (var i=0; i