Last active
May 5, 2019 22:30
-
-
Save y2bd/1fbe926bc902182d71b29477a692b59a to your computer and use it in GitHub Desktop.
SCRIPT-8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// board specs | |
const BOARD_WIDTH = 10 | |
const BOARD_HEIGHT = 24 | |
const BOARD_X = 0 | |
const BOARD_Y = 0 | |
// board states | |
const EMPTY = 0 | |
const FULL = 1 | |
// blok specs | |
const BLOK_TYPES = 7 | |
const BLOK_SIZE = 4 | |
// game states | |
const CHOOSE = 0 | |
const CHOSEN = 1 | |
const FALL = 2 | |
const GROUND = 3 | |
const CLEAR = 4 | |
// FALL sub-state | |
const FALL_GRAV = 0 | |
const FALL_DROP = 1 | |
// DAS sub-states | |
const DAS_CHARGE = 300 | |
const DAS_NONE = 0 | |
const DAS_LEFT = 1 | |
const DAS_RIGHT = 2 | |
// game speed (ms) | |
const TURN_LENGTH = 200 | |
// bloks | |
const bloks = [ | |
// I | |
[[0,0,0,0], | |
[1,1,1,1], | |
[0,0,0,0], | |
[0,0,0,0]], | |
// T | |
[[0,1,0], | |
[1,1,1], | |
[0,0,0]], | |
// L | |
[[0,0,1], | |
[1,1,1], | |
[0,0,0]], | |
// J | |
[[1,0,0], | |
[1,1,1], | |
[0,0,0]], | |
// S | |
[[0,1,1], | |
[1,1,0], | |
[0,0,0]], | |
// Z | |
[[1,1,0], | |
[0,1,1], | |
[0,0,0]], | |
// 0 | |
[[0,0,0,0], | |
[0,1,1,0], | |
[0,1,1,0], | |
[0,0,0,0]] | |
] | |
const initialBoard = () => { | |
const board = [] | |
range(BOARD_HEIGHT).forEach(i => { | |
const row = [] | |
range(BOARD_WIDTH).forEach(j => row.push(EMPTY)) | |
board.push(row) | |
}) | |
return board | |
} | |
const drawBoard = board => { | |
range(BOARD_WIDTH).forEach(x => { | |
range(BOARD_HEIGHT).forEach(y => { | |
const square = board[y][x] | |
if (square === EMPTY) { | |
rectFill( | |
BOARD_X + BLOK_SIZE * x, | |
BOARD_Y + BLOK_SIZE * y, | |
BLOK_SIZE, | |
BLOK_SIZE, | |
4 | |
) | |
} else { | |
rectFill( | |
BOARD_X + BLOK_SIZE * x, | |
BOARD_Y + BLOK_SIZE * y, | |
BLOK_SIZE, | |
BLOK_SIZE | |
) | |
} | |
}) | |
}) | |
} | |
const chooseBlok = () => { | |
const blokChoice = Math.floor(Math.random() * BLOK_TYPES) | |
return bloks[blokChoice] | |
} | |
const cloneMatrix = matrix => { | |
return matrix.map(row => [...row]) | |
} | |
const insertIntoMatrix = (base, piece, lx, ly) => { | |
const baseWidth = base[0].length | |
const baseHeight = base.length | |
const pieceWidth = piece[0].length | |
const pieceHeight = piece.length | |
const result = cloneMatrix(base) | |
range(lx, lx + pieceWidth).forEach(x => { | |
range(ly, ly + pieceHeight).forEach(y => { | |
if (x < 0 || x >= baseWidth || y < 0 || y >= baseHeight) { | |
return | |
} | |
const square = piece[y - ly][x - lx] | |
if (square === EMPTY) { | |
return | |
} | |
result[y][x] = piece[y - ly][x - lx] | |
}) | |
}) | |
return result | |
} | |
const invalidInsert = (base, piece, lx, ly) => { | |
const baseWidth = base[0].length | |
const baseHeight = base.length | |
const pieceWidth = piece[0].length | |
const pieceHeight = piece.length | |
let invalid = false | |
range(lx, lx + pieceWidth).forEach(x => { | |
if (invalid === true) { | |
return | |
} | |
range(ly, ly + pieceHeight).forEach(y => { | |
if (invalid === true) { | |
return | |
} | |
const psquare = piece[y - ly][x - lx] | |
if (x < 0 || x >= baseWidth || y < 0 || y >= baseHeight) { | |
// basically, we can actually extend beyond the board if it's an empty space on the inserted | |
// but if we want to insert a solid piece beyond the board, then it's bad | |
if (psquare !== EMPTY) { | |
invalid = true | |
} | |
return | |
} | |
const bsquare = base[y][x] | |
if (bsquare !== EMPTY && psquare !== EMPTY) { | |
invalid = true | |
} | |
}) | |
}) | |
return invalid | |
} | |
init = state => { | |
state.board = initialBoard() | |
state.gameState = CHOOSE | |
state.fallState = FALL_GRAV | |
state.turnElapsed = 0 | |
state.currentBlok = undefined | |
state.blokX = 4 | |
state.blokY = 0 | |
state.dasCharge = 0 | |
state.dasMode = DAS_NONE | |
} | |
update = (state, input, elapsed) => { | |
let nextGameState = state.gameState | |
let nextBlokX = state.blokX | |
let nextBlokY = state.blokY | |
let nextBoard = state.board | |
let nextDasCharge = state.dasCharge | |
let nextDasMode = state.dasMode | |
state.turnElapsed += elapsed | |
let endOfTurn = false | |
if (state.turnElapsed >= TURN_LENGTH) { | |
state.turnElapsed = 0 | |
endOfTurn = true | |
} | |
if (state.gameState === CHOOSE) { | |
state.currentBlok = chooseBlok() | |
nextBlokX = 4 | |
nextBlokY = 0 | |
nextGameState = CHOSEN | |
} else if (state.gameState === CHOSEN) { | |
if (endOfTurn) { | |
nextGameState = FALL | |
} | |
} else if (state.gameState === FALL) { | |
// first handle inputs | |
// don't let new inputs override old ones | |
if (input.left && !(input.right && nextDasMode === DAS_RIGHT)) { | |
if (nextDasMode === DAS_LEFT) { | |
nextDasCharge += elapsed | |
if (nextDasCharge > DAS_CHARGE) { | |
nextBlokX -= 1 | |
} | |
} else { | |
nextBlokX -= 1 | |
} | |
} else if (input.right && !(input.left && nextDasMode === DAS_LEFT)) { | |
if (nextDasMode === DAS_RIGHT) { | |
nextDasCharge += elapsed | |
if (nextDasCharge > DAS_CHARGE) { | |
nextBlokX -= 1 | |
} | |
} else { | |
nextBlokX -= 1 | |
} | |
} | |
// don't let us slide off the board | |
if (invalidInsert(state.board, state.currentBlok, nextBlokX, nextBlokY)) { | |
nextBlokX = state.blokX | |
} | |
// then handle falling | |
if (state.fallState === FALL_GRAV && endOfTurn) { | |
nextBlokY += 1 | |
} | |
// check if we're gonna fall too far | |
if (invalidInsert(state.board, state.currentBlok, nextBlokX, nextBlokY + 1)) { | |
// TODO go to ground mode for ground spins | |
nextGameState = CHOOSE | |
nextBoard = insertIntoMatrix(nextBoard, state.currentBlok, nextBlokX, nextBlokY) | |
} | |
} | |
state.gameState = nextGameState | |
state.blokX = nextBlokX | |
state.blokY = nextBlokY | |
state.board = nextBoard | |
state.dasCharge = nextDasCharge | |
state.dasMode = nextDasMode | |
} | |
draw = state => { | |
clear() | |
const { | |
board, | |
currentBlok, | |
blokX, | |
blokY | |
} = state | |
const currentBoard = insertIntoMatrix(board, currentBlok, blokX, blokY) | |
drawBoard(currentBoard) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"iframeVersion": "0.1.254", | |
"lines": [ | |
73, | |
41, | |
67, | |
0, | |
0, | |
0, | |
0, | |
107 | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment