commit 51c110bda51b6f5a8634b629a86fcb09e7374a67 Author: Edward Peterson Date: Fri Oct 7 09:10:21 2022 -0400 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..2a7d1f3 --- /dev/null +++ b/index.js @@ -0,0 +1,286 @@ +const chalk = require('chalk') + + +var cursorX = 0; +var cursorY = 0; + +var placing = getRandomBlock(false); + +var board = []; +var score = 0; +for (var y = 0; y < 7; y++) { + board.push([]); + for (var x = 0; x < 7; x++) { + board[y].push(0); + } +} + +const blocksToPlace = 25; +const solidRows = 3; +for (var i = 0;i < solidRows;i++){ + for (var x = 0; x < 7; x++) { + dropBlock(-2, x); + + } +} +for (var i = 0; i < blocksToPlace; i++) { + dropBlock(getRandomBlock(true), Math.floor(Math.random() * 7)); +} + + +const readline = require('readline'); +readline.emitKeypressEvents(process.stdin); +process.stdin.setRawMode(true); +process.stdin.on('keypress', (str, key) => { + if (key.ctrl && key.name === 'c') { + process.exit(); + + } else { + switch (key.name) { + case 'left': + cursorX = Math.max(0, cursorX - 1); + break; + case 'right': + cursorX = Math.min(6, cursorX + 1); + break; + case 'up': + cursorY = Math.max(0, cursorY - 1); + break; + case 'down': + cursorY = Math.min(6, cursorY + 1); + break; + case 'enter': + case 'return': + const successfullyDropped = dropBlock(placing, cursorX); + if(successfullyDropped) + placing = getRandomBlock(false); + + } + paintBoard(); + + } +}); +console.log('Press any key...'); + +function getRandomBlock(canBeSolid) { + var value = Math.floor(Math.random() * (canBeSolid ? 10 : 8)) - (canBeSolid ? 2 : 0); + if(value === 0) return getRandomBlock(canBeSolid); //value cannot be 0, try again. + return value; +} +function dropBlock(value, column) { + //find the lowest point it can sit. + var yPos = -1; + for (var y = 6; y >= 0; y--) { + if (board[y][column] === 0) { + yPos = y; + break; + } + } + if (yPos === -1) { + //cannot place block, column full + return false; + } + board[yPos][column] = value; + + var comboMultiplier = 1; + var pointsEarned = 0; + do { + pointsEarned = detectScoring(); + score += pointsEarned * comboMultiplier; + shakedownBoard(); + comboMultiplier *= 2; + } while (pointsEarned > 0); + + return true; +} +function detectScoring() { + //check vertical + //how tall is each stack? + var toPop = []; + for (var x = 0; x < 7; x++) { + var stackHeight = 7; + for (var y = 6; y >= 0; y--) { + if (board[y][x] === 0) { + stackHeight = 6 - y; + break; + } + } + if (stackHeight <= 0) continue; + //are there any in the stack that match the stack height + var poppingWillOccur = false; + for (var y = 0; y < 7; y++) { + if (board[y][x] === stackHeight) { + toPop.push({ x: x, y: y }); + poppingWillOccur = true; + } + } + if (poppingWillOccur) { + //break blank blocks by one level + + for (var y = 0; y < 7; y++) { + if (board[y][x] < 0) { + toPop.push({ x: x, y: y }); + } + } + } + } + //check horizontal groups + for (var y = 6; y >= 0; y--) { //start from the bottom up + const groups = [[]] + var buildingGroupIndex = 0; + for (var x = 0; x < 7; x++) { + if (groups[buildingGroupIndex].length === 0) { + //if current group is empty + if (board[y][x] === 0) continue; + groups[buildingGroupIndex].push({ + x: x, + y: y, + v: board[y][x] + }); + } else { + //current group has at least one element in it + if (board[y][x] === 0) { + if (x < 6) { + //if we're not in the last column, create a new group for the next stuff + buildingGroupIndex++; + groups.push([]); + } + continue; + } else { + groups[buildingGroupIndex].push({ + x: x, + y: y, + v: board[y][x] + }); + } + } + } + for (var g = 0; g < groups.length; g++) { + var popWillOccurrInGroup = false; + for (var j = 0; j < groups[g].length; j++) { + if (groups[g].length === groups[g][j].v) { + popWillOccurrInGroup = true; + toPop.push({ + x: groups[g][j].x, + y: groups[g][j].y + }) + } + } + if (popWillOccurrInGroup) { + for (var j = 0; j < groups[g].length; j++) { + if (groups[g][j].v < 0) { + toPop.push({ + x: groups[g][j].x, + y: groups[g][j].y + }) + } + } + } + } + } + var points = 0; + for (var j = 0; j < toPop.length; j++) { + const value = board[toPop[j].y][toPop[j].x] + if (value < 0) { + var newValue = value + 1; + if (newValue === 0) { + newValue = Math.floor(Math.random() * 7) + 1 + } + board[toPop[j].y][toPop[j].x] = newValue; + } else { + points += board[toPop[j].y][toPop[j].x]; + board[toPop[j].y][toPop[j].x] = 0; + + } + } + + return points; +} +function shakedownBoard() { + for (var x = 0; x < 7; x++) { //loop through each column + + for (var y = 6; y >= 0; y--) { + //check to see if we can push this element down + if (y === 6) continue; // can't push any further than bottom + const below = board[y + 1][x]; + if (below === 0) { + //airspace directly below + + //get top of stack index and swap it with current. + var newPos = -1; + for (var a = 6; a >= 0; a--) { + if (board[a][x] === 0) { + newPos = a; + break; + } + } + if (newPos === -1) { + //cannot place block, column full + system.exit(); // shouldn't ever happen in a shakedown. + } + + + //do the swap + board[newPos][x] = board[y][x]; + board[y][x] = 0; + + } + + + } + } +} +function getBlockColor(value){ + switch(value){ + case 7: return chalk.blue; + case 6: return chalk.cyanBright; + case 5: return chalk.magenta; + case 4: return chalk.red; + case 3: return chalk.yellow; + case 2: return chalk.yellowBright; + case 1: return chalk.greenBright; + case 0: return chalk.black; + case -1: return chalk.white; + case -2: return chalk.white; + } +} + + +function paintBoard() { + console.clear(); + + //paint the placing row; + for(var x = 0;x < 7;x++) + if(x === cursorX) + process.stdout.write(`${placing} `); + else + process.stdout.write(' '); //semi solid + + process.stdout.write('\n'); + + + for (var y = 0; y < 7; y++) { + + for (var x = 0; x < 7; x++) { + var charToPrint = ' '; + switch (board[y][x]) { + case 0: + charToPrint = ' '; + break; + case -1: + charToPrint = '\u2591'; //semi solid + break; + case -2: + charToPrint = '\u2593'; // dark block + break; + default: + charToPrint = `${board[y][x]}` + } + process.stdout.write(`${getBlockColor(board[y][x])(charToPrint)} `) + + } + process.stdout.write('\n'); + } + process.stdout.write('-------------\n\nScore: ' + score + '\n'); +} +paintBoard(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..59abfdf --- /dev/null +++ b/package-lock.json @@ -0,0 +1,51 @@ +{ + "name": "drop7", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9d021a4 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "drop7", + "version": "1.0.0", + "description": "Drop 7 Game", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Edward Peterson", + "license": "ISC", + "dependencies": { + "chalk": "^4.1.2" + } +}