Thursday, February 3, 2022

BBC Micro:bit Snake-Game


 Code

JavaScript

function isOnSnake (x: number, y: number) {
    for (let body of snake) {
        if (body.x() == x && body.y() == y) {
            return true
        }
    }
    return false
}
function moveForward () {
    dx = dxOffset[direction]
    px += dx[0]
    py += dx[1]
    if (!(validPixelCoordinate(px, py))) {
        gameOver()
    }
    snake.unshift(game.createSprite(px, py))
    last = snake.pop()
    last.delete()
}
function turnLeft () {
    direction = (direction + 3) % 4
}
function resetGame () {
    game.setScore(0)
    score = 0
    direction = 0
    px = 0
    py = 0
    for (let s of snake) {
        s.delete()
    }
    snake = initSnake([px, py, px + 1, py]);
placeNextApple()
    game.resume()
}
input.onButtonPressed(Button.Afunction () {
    turnLeft()
})
function gameOver () {
    game.setScore(score)
    game.pause()
    basic.pause(1000)
    game.gameOver()
}
function turnRight () {
    direction = (direction + 1) % 4
}
input.onButtonPressed(Button.ABfunction () {
    resetGame()
})
function letComputerPlay () {
    let x2 = snake[0].x();
let y2 = snake[0].y();
// next distance to apple if moving forward
    dx2 = dxOffset[direction]
    nx1 = x2 + dx2[0]
    ny1 = y2 + dx2[1]
    dist1 = 9999
    if (validPixelCoordinate(nx1, ny1)) {
        dist1 = Math.abs(nx1 - apple.x()) + Math.abs(ny1 - apple.y())
    }
    // next distance to apple if turning right
    dx1 = (direction + 1) % 4
    dx2 = dxOffset[dx1]
    nx2 = x2 + dx2[0]
    ny2 = y2 + dx2[1]
    dist2 = 9999
    if (validPixelCoordinate(nx2, ny2)) {
        dist2 = Math.abs(nx2 - apple.x()) + Math.abs(ny2 - apple.y())
    }
    // next distance to apple if turning left
    dx22 = (direction + 3) % 4
    dx2 = dxOffset[dx22]
    nx3 = x2 + dx2[0]
    ny3 = y2 + dx2[1]
    dist3 = 9999
    if (validPixelCoordinate(nx3, ny3)) {
        dist3 = Math.abs(nx3 - apple.x()) + Math.abs(ny3 - apple.y())
    }
    if (dist1 <= dist2 && dist1 <= dist3) {
        // best strategy is moving forward without turning
        return
    } else if (dist2 <= dist1 && dist2 <= dist3) {
        turnRight()
    } else if (dist3 <= dist1 && dist3 <= dist2) {
        turnLeft()
    }
}
input.onButtonPressed(Button.Bfunction () {
    turnRight()
})
function placeNextApple () {
    let x, y;
do {
        x = Math.randomRange(04);
        y = Math.randomRange(04);
    } while (isOnSnake(x, y));
apple.goTo(x, y);
apple.setBrightness(100);
}
function validPixelCoordinate (nx: number, ny: number) {
    return nx >= 0 && nx <= 4 && ny >= 0 && ny <= 4 && !(isOnSnake(nx, ny))
}
let delay = 0
let dist3 = 0
let ny3 = 0
let nx3 = 0
let dx22 = 0
let dist2 = 0
let ny2 = 0
let nx2 = 0
let dx1 = 0
let dist1 = 0
let ny1 = 0
let nx1 = 0
let dx2: number[] = []
let score = 0
let last: game.LedSprite = null
let dx: number[] = []
let dxOffset: number[][] = []
let direction = 0
let py = 0
let px = 0
direction = 1
dxOffset = [
[10],
[01],
[-10],
[0, -1]
]
let snake = initSnake([px, py, px + 1, py]);
let apple = game.createSprite(22)
// when snake grows to 10 pixels, it stops growing
// to avoid filling the LED
let maxLength = 10
placeNextApple()
function initSnake(arr: Array<number>) {
    let result = [];
    for (let i = 0; i + 1 < arr.length; i += 2) {
        result.push(game.createSprite(arr[i], arr[i + 1]));
    }
    return result;
}
basic.forever(function () {
    if (game.isGameOver()) {
        return;
    }
    delay = Math.max(1001000 - score * 50)
    basic.pause(delay)
    // letComputerPlay();
    moveForward()
    if (snake[0].isTouching(apple)) {
        if (snake.length < maxLength) {
            snake.push(snake[snake.length - 1])
        }
        score += 1
        placeNextApple()
    }
})

Blocks

let px = 0let py = 01array ofarray of10array of01array of-10array of0-1let snake = initSnake([px, py, px + 1, py]);22create sprite atx:y:10callplaceNextApplefunction initSnake(arr: Array<number>) {    let result = [];    for (let i = 0; i + 1 < arr.length; i += 2) {        result.push(game.createSprite(arr[i], arr[i + 1]));    }    return result;}setmaxLengthtosetappletosetdxOffsettosetdirectiontoon startcallturnLefton buttonApressedcallturnRighton buttonBpressedcallresetGameon buttonA+Bpressedis game overreturn;1001000score50×-maxofanddelaycallmoveForwardsnake0get value atappleistouchingsnakelength of arraymaxLength‏<snakesnakesnakelength of array1-get value atadd valueto end1callplaceNextApplechangescorebyifthenifthenpause (ms)setdelaytoifthenforeverfunctionvalidPixelCoordinatenxnyreturnnx0‏≥nx4‏≤andny0‏≥andny4‏≤andcallisOnSnakenxnynotandfunctiongameOverscore1000game overpause (ms)pauseset scorefunctionresetGame00000ssnakesdeletesnake = initSnake([px, py, px + 1, py]);callplaceNextAppleresumefor elementofdosetpytosetpxtosetdirectiontosetscoretoset scorefunctionmoveForwarddxOffsetdirectionget value atdx0get value atdx1get value atcallvalidPixelCoordinatepxpynotcallgameOversnakepxpycreate sprite atx:y:snakeget and remove last value fromlastdeletesetlasttoinsertat beginningifthenchangepybychangepxbysetdxtofunctionisOnSnakexybodysnakebody.x()x=body.y()y=andreturntrueifthenreturnfalsefor elementofdofunctionplaceNextApplelet x, y;do {        x = Math.randomRange(0, 4);        y = Math.randomRange(0, 4);    } while (isOnSnake(x, y));apple.goTo(x, y);apple.setBrightness(100);functionturnLeftdirection3+4remainder of÷setdirectiontofunctionturnRightdirection1+4remainder of÷setdirectiontofunctionletComputerPlaylet x2 = snake[0].x();let y2 = snake[0].y();dxOffsetdirectionget value atx2dx20get value at+y2dx21get value at+9999callvalidPixelCoordinatenx1ny1nx1apple.x()-absolute ofny1apple.y()-absolute of+setdist1todirection1+4remainder of÷dxOffsetdx1get value atx2dx20get value at+y2dx21get value at+9999callvalidPixelCoordinatenx2ny2nx2apple.x()-absolute ofny2apple.y()-absolute of+setdist2todirection3+4remainder of÷dxOffsetdx22get value atx2dx20get value at+y2dx21get value at+9999callvalidPixelCoordinatenx3ny3nx3apple.x()-absolute ofny3apple.y()-absolute of+setdist3toifthenelse ifthenelse ifthendist1dist2‏≤dist1dist3‏≤andreturndist2dist1‏≤dist2dist3‏≤andcallturnRightdist3dist1‏≤dist3dist2‏≤andcallturnLeftifthensetdist3tosetny3tosetnx3tosetdx2tosetdx22toifthensetdist2tosetny2tosetnx2tosetdx2tosetdx1toifthensetdist1tosetny1tosetnx1tosetdx2to

Extensions

  • radio, *
  • microphone, *

2 comments: