removing outdated tests
This commit is contained in:
parent
d6cc95112c
commit
ceeb366be5
@ -1,222 +0,0 @@
|
|||||||
let AWasPressed: boolean
|
|
||||||
let BWasPressed: boolean
|
|
||||||
let ABWasPressed: boolean
|
|
||||||
let wasShake: boolean
|
|
||||||
let scoreA: number
|
|
||||||
let scoreB: number
|
|
||||||
|
|
||||||
scoreA = 0
|
|
||||||
scoreB = 0
|
|
||||||
startIOMonitor()
|
|
||||||
let gameTime = getGameTime()
|
|
||||||
basic.showLeds(`
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. . # # #
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
while (!BWasPressed) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
BWasPressed = false
|
|
||||||
playOneGame(gameTime)
|
|
||||||
showFinalScores(scoreA, scoreB)
|
|
||||||
|
|
||||||
function startIOMonitor() {
|
|
||||||
input.onButtonPressed(Button.A, () => {
|
|
||||||
AWasPressed = true
|
|
||||||
})
|
|
||||||
input.onButtonPressed(Button.B, () => {
|
|
||||||
BWasPressed = true
|
|
||||||
})
|
|
||||||
input.onButtonPressed(Button.AB, () => {
|
|
||||||
ABWasPressed = true
|
|
||||||
AWasPressed = false
|
|
||||||
BWasPressed = false
|
|
||||||
})
|
|
||||||
input.onShake(() => {
|
|
||||||
wasShake = true
|
|
||||||
})
|
|
||||||
AWasPressed = false
|
|
||||||
BWasPressed = false
|
|
||||||
ABWasPressed = false
|
|
||||||
wasShake = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* display score for A and B on same screen as a graphic
|
|
||||||
* this shows a tug of war line, in the middle if scores the same,
|
|
||||||
* Can cope with differences +/-10
|
|
||||||
* @param scoreA1 TODO
|
|
||||||
* @param scoreB1 TODO
|
|
||||||
*/
|
|
||||||
function showScore(scoreA1: number, scoreB1: number) {
|
|
||||||
let img = images.createImage(`
|
|
||||||
# . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . #
|
|
||||||
# . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . #
|
|
||||||
# . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . #
|
|
||||||
# . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . #
|
|
||||||
# . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . . #
|
|
||||||
`)
|
|
||||||
let diff = Math.clamp(-10, 10, scoreB1 - scoreA1)
|
|
||||||
diff = diff + 10
|
|
||||||
img.plotFrame(diff)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* show digits 0..10
|
|
||||||
* @param digits TODO
|
|
||||||
*/
|
|
||||||
function showDigits(digits: number) {
|
|
||||||
digits = Math.clamp(0, 10, digits)
|
|
||||||
let img = images.createImage(`
|
|
||||||
. . # . . . . # . . . # # . . . # # . . . # . . . . # # # . . . # # . . # # # . . . # . . . . # . . # . . # .
|
|
||||||
. # . # . . # # . . . . . # . . . . # . . # . . . . # . . . . # . . . . . . # . . # . # . . # . # . # . # . #
|
|
||||||
. # . # . . . # . . . . # . . . . # . . . # # # . . . # # . . # # . . . . # . . . . # . . . . # # . # . # . #
|
|
||||||
. # . # . . . # . . . # . . . . . . # . . . # . . . . . # . . # . # . . # . . . . # . # . . . . # . # . # . #
|
|
||||||
. . # . . . # # # . . # # # . . # # . . . . # . . . # # . . . . # . . . # . . . . . # . . . # # . . # . . # .
|
|
||||||
`)
|
|
||||||
img.plotFrame(digits)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* show time graphic for time remaining
|
|
||||||
* @param gameTime TODO
|
|
||||||
*/
|
|
||||||
function showTime(gameTime: number) {
|
|
||||||
let minutes = Math.clamp(0, 10, gameTime / 60)
|
|
||||||
let seconds = gameTime % 60
|
|
||||||
// divide seconds into 10 second stripes
|
|
||||||
let stripes = seconds / 10
|
|
||||||
let img = images.createImage(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . # . . . . # # . . . # # # . . # # # # . # # # # #
|
|
||||||
. . . . . # . . . . # # . . . # # # . . # # # # . # # # # #
|
|
||||||
`)
|
|
||||||
img.plotFrame(stripes)
|
|
||||||
// leave middle row blank
|
|
||||||
// display up to 10 dots in raster on top two rows
|
|
||||||
if (minutes > 0) {
|
|
||||||
for (let i = 0; i < minutes; i++) {
|
|
||||||
let y = i / 5
|
|
||||||
let x = i % 5
|
|
||||||
led.plot(x, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getGameTime(): number {
|
|
||||||
let chosenGameTime = 7
|
|
||||||
showDigits(chosenGameTime)
|
|
||||||
while (!BWasPressed) {
|
|
||||||
if (AWasPressed) {
|
|
||||||
if (chosenGameTime < 10) {
|
|
||||||
chosenGameTime = chosenGameTime + 1
|
|
||||||
} else {
|
|
||||||
chosenGameTime = 1
|
|
||||||
}
|
|
||||||
showDigits(chosenGameTime)
|
|
||||||
AWasPressed = false
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BWasPressed = false
|
|
||||||
return chosenGameTime
|
|
||||||
}
|
|
||||||
|
|
||||||
function playOneGame(gameTime: number) {
|
|
||||||
let gameStartTime = input.runningTime()
|
|
||||||
let gameElapsedTime = 0
|
|
||||||
let gameTimeRemaining = gameTime * 60
|
|
||||||
let timeout = 0
|
|
||||||
let lastDisplayedTime = 0
|
|
||||||
showScore(scoreA, scoreB)
|
|
||||||
let state = "TIME"
|
|
||||||
while (gameTimeRemaining >= 0) {
|
|
||||||
// Tick the game time
|
|
||||||
gameElapsedTime = (input.runningTime() - gameStartTime) / 1000
|
|
||||||
gameTimeRemaining = gameTime * 60 - gameElapsedTime
|
|
||||||
// Handle any global events such as point buttons
|
|
||||||
if (AWasPressed) {
|
|
||||||
AWasPressed = false
|
|
||||||
scoreA = scoreA + 1
|
|
||||||
if (state != "LAST10") {
|
|
||||||
showScore(scoreA, scoreB)
|
|
||||||
state = "SCORE"
|
|
||||||
}
|
|
||||||
} else if (BWasPressed) {
|
|
||||||
BWasPressed = false
|
|
||||||
scoreB = scoreB + 1
|
|
||||||
if (state != "LAST10") {
|
|
||||||
showScore(scoreA, scoreB)
|
|
||||||
state = "SCORE"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle global transitions
|
|
||||||
if (gameTimeRemaining <= 10 && state != "LAST10") {
|
|
||||||
state = "LAST10"
|
|
||||||
}
|
|
||||||
// Handle game states
|
|
||||||
if (state == "SCORE") {
|
|
||||||
if (wasShake) {
|
|
||||||
wasShake = false
|
|
||||||
showTime(gameTimeRemaining)
|
|
||||||
lastDisplayedTime = gameTimeRemaining
|
|
||||||
timeout = input.runningTime() + 5 * 1000
|
|
||||||
state = "TIME"
|
|
||||||
}
|
|
||||||
} else if (state == "TIME") {
|
|
||||||
if (input.runningTime() > timeout) {
|
|
||||||
showScore(scoreA, scoreB)
|
|
||||||
state = "SCORE"
|
|
||||||
}
|
|
||||||
} else if (state == "LAST10") {
|
|
||||||
if (gameTimeRemaining != lastDisplayedTime) {
|
|
||||||
showDigits(gameTimeRemaining)
|
|
||||||
lastDisplayedTime = gameTimeRemaining
|
|
||||||
}
|
|
||||||
}
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showFinalScores(scoreA1: number, scoreB1: number) {
|
|
||||||
basic.showLeds(`
|
|
||||||
# . . . #
|
|
||||||
. # . # .
|
|
||||||
. . # . .
|
|
||||||
. # . # .
|
|
||||||
# . . . #
|
|
||||||
`)
|
|
||||||
while (true) {
|
|
||||||
if (AWasPressed) {
|
|
||||||
basic.showString("A", 150)
|
|
||||||
basic.showNumber(scoreA1, 150)
|
|
||||||
basic.showLeds(`
|
|
||||||
# . . . #
|
|
||||||
. # . # .
|
|
||||||
. . # . .
|
|
||||||
. # . # .
|
|
||||||
# . . . #
|
|
||||||
`)
|
|
||||||
AWasPressed = false
|
|
||||||
} else if (BWasPressed) {
|
|
||||||
basic.showString("B", 150)
|
|
||||||
basic.showNumber(scoreB1, 150)
|
|
||||||
basic.showLeds(`
|
|
||||||
# . . . #
|
|
||||||
. # . # .
|
|
||||||
. . # . .
|
|
||||||
. # . # .
|
|
||||||
# . . . #
|
|
||||||
`)
|
|
||||||
BWasPressed = false
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,248 +0,0 @@
|
|||||||
let speed: number
|
|
||||||
let cupCapacity: number
|
|
||||||
let maxMisses: number
|
|
||||||
let autoEmpty: boolean
|
|
||||||
let movement: boolean
|
|
||||||
let sensitivity: number
|
|
||||||
let cupX: number
|
|
||||||
let cupInverted: boolean
|
|
||||||
|
|
||||||
let highscore = 0
|
|
||||||
while (true) {
|
|
||||||
// configure game settings
|
|
||||||
// ##CHALLENGE1: reconfigure game
|
|
||||||
cupCapacity = 5
|
|
||||||
speed = 6
|
|
||||||
maxMisses = 3
|
|
||||||
autoEmpty = false
|
|
||||||
movement = true
|
|
||||||
sensitivity = 400
|
|
||||||
cupX = 2
|
|
||||||
// show the spash screen
|
|
||||||
// ##CHALLENGE 2: CHANGE SPLASH SCREEN
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . .
|
|
||||||
. . . . . . # . # .
|
|
||||||
. . . . . . . . . .
|
|
||||||
. # . # . . # . # .
|
|
||||||
. # # # . . # # # .
|
|
||||||
`, 400)
|
|
||||||
// Decide what to do based on which button is pressed
|
|
||||||
if (input.buttonIsPressed(Button.A)) {
|
|
||||||
let finalScore = playGame()
|
|
||||||
// ##CHALLENGE 3 ADD HIGH SCORE
|
|
||||||
if (finalScore > highscore) {
|
|
||||||
basic.showString("HIGH", 150)
|
|
||||||
highscore = finalScore
|
|
||||||
}
|
|
||||||
basic.showNumber(finalScore, 150)
|
|
||||||
} else if (input.buttonIsPressed(Button.B)) {
|
|
||||||
testMovement()
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function playGame(): number {
|
|
||||||
let cup = images.createImage(`
|
|
||||||
. . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . .
|
|
||||||
. . . . . . # . # . . . . . .
|
|
||||||
. . . . . . # # # . . . . . .
|
|
||||||
`)
|
|
||||||
let score = 0
|
|
||||||
let dropsInCup = 0
|
|
||||||
let misses = 0
|
|
||||||
let dropX = 0
|
|
||||||
let dropY = 0
|
|
||||||
let prevDropY = -1
|
|
||||||
let cupX1 = 2
|
|
||||||
let prevCupX = -1
|
|
||||||
let state = "NEWDROP"
|
|
||||||
startGame()
|
|
||||||
while (true) {
|
|
||||||
if (state == "NEWDROP") {
|
|
||||||
// create a new drop at a random position
|
|
||||||
dropX = Math.random(5)
|
|
||||||
dropY = 0
|
|
||||||
state = "RAINING"
|
|
||||||
} else if (state == "RAINING") {
|
|
||||||
// calculate new positions
|
|
||||||
cupX1 = getCupPosition()
|
|
||||||
let thisDropY = dropY / speed
|
|
||||||
// Only redraw the screen if something has changed (prevent flashing)
|
|
||||||
if (cupX1 != prevCupX || thisDropY != prevDropY) {
|
|
||||||
basic.clearScreen()
|
|
||||||
// draw cup
|
|
||||||
cup.showImage(7 - cupX1)
|
|
||||||
if (dropsInCup == cupCapacity) {
|
|
||||||
// a full cup
|
|
||||||
led.plot(cupX1, 3)
|
|
||||||
}
|
|
||||||
// draw drop
|
|
||||||
led.plot(dropX, thisDropY)
|
|
||||||
prevCupX = cupX1
|
|
||||||
prevDropY = thisDropY
|
|
||||||
}
|
|
||||||
basic.pause(100)
|
|
||||||
if (thisDropY >= 4) {
|
|
||||||
state = "ATCUP"
|
|
||||||
} else {
|
|
||||||
dropY = dropY + 1
|
|
||||||
}
|
|
||||||
if (cupInverted && dropsInCup >= cupCapacity) {
|
|
||||||
state = "EMPTYING"
|
|
||||||
}
|
|
||||||
} else if (state == "ATCUP") {
|
|
||||||
if (dropX == cupX1) {
|
|
||||||
state = "CATCH"
|
|
||||||
} else {
|
|
||||||
state = "MISS"
|
|
||||||
}
|
|
||||||
} else if (state == "MISS") {
|
|
||||||
// ##CHALLENGE: long beep on miss
|
|
||||||
beep(500)
|
|
||||||
misses = misses + 1
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . # . # . . . . . . . . . . .
|
|
||||||
. . . . . . # # # . . # . # . . . . . .
|
|
||||||
. # . # . . . . . . . # # # . . # . # .
|
|
||||||
. # # # . . . # . . . . . . . . # # # .
|
|
||||||
`, 400)
|
|
||||||
if (misses > maxMisses) {
|
|
||||||
state = "GAMEOVER"
|
|
||||||
} else {
|
|
||||||
state = "NEWDROP"
|
|
||||||
}
|
|
||||||
} else if (state == "CATCH") {
|
|
||||||
// ##CHALLENGE: short beep on catch
|
|
||||||
beep(200)
|
|
||||||
dropsInCup = dropsInCup + 1
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . .
|
|
||||||
. # # # . # . # . # . # . # .
|
|
||||||
. # # # . # # # # # . # # # .
|
|
||||||
`, 400)
|
|
||||||
if (dropsInCup == cupCapacity) {
|
|
||||||
state = "FULL"
|
|
||||||
score = score + 1
|
|
||||||
} else if (dropsInCup > cupCapacity) {
|
|
||||||
state = "OVERFLOW"
|
|
||||||
} else {
|
|
||||||
score = score + 1
|
|
||||||
state = "NEWDROP"
|
|
||||||
}
|
|
||||||
} else if (state == "FULL") {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . .
|
|
||||||
. . . . . . # # # . . . . . .
|
|
||||||
. # # # . . # # # . . # # # .
|
|
||||||
. # # # . . # # # . . # # # .
|
|
||||||
`, 400)
|
|
||||||
if (autoEmpty) {
|
|
||||||
state = "EMPTYING"
|
|
||||||
} else {
|
|
||||||
state = "NEWDROP"
|
|
||||||
}
|
|
||||||
} else if (state == "EMPTYING") {
|
|
||||||
if (cupInverted) {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . # . . . . . . .
|
|
||||||
. . . . . . . . . . . . # . . . . . . . . . . . .
|
|
||||||
. . . . . . . # . . . . . . . . . . . . . . . . .
|
|
||||||
. # # # . . # . # . . # . # . . # . # . . # . # .
|
|
||||||
. # # # . . # # # . . # # # . . # # # . . # # # .
|
|
||||||
`, 400)
|
|
||||||
} else {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . # # # . . # # # . . # # # . . # # # . . # # # . . . . . . . . . . .
|
|
||||||
. . . . . . # # . . . # # # . . # . # . . # . # . . # . # . . # . # . . # # . . . . . . .
|
|
||||||
. . . . . . # # . . . . . . . . . # . . . . . . . . . . . . . . . . . . # . . . . . . . .
|
|
||||||
. # # # . . # # . . . . . . . . . . . . . . # . . . . . . . . . . . . . # # . . . # . # .
|
|
||||||
. # # # . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . # # # .
|
|
||||||
`, 400)
|
|
||||||
}
|
|
||||||
dropsInCup = 0
|
|
||||||
// ##CHALLENGE: Speed up on every level change
|
|
||||||
if (speed > 1) {
|
|
||||||
speed = speed - 1
|
|
||||||
}
|
|
||||||
state = "NEWDROP"
|
|
||||||
} else if (state == "OVERFLOW") {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . # # # . . # . # . . . . . . . . . . . . . . . .
|
|
||||||
. # # # . . # # # . # # # # # # # # # # . # # # . . # # # .
|
|
||||||
. # # # . . # # # . . # # # . . # # # . # # # # # . # # # .
|
|
||||||
`, 400)
|
|
||||||
state = "GAMEOVER"
|
|
||||||
} else if (state == "GAMEOVER") {
|
|
||||||
// ##CHALLENGE: Make a sound on game over
|
|
||||||
beep(700)
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . # # # # # . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . # # # # # . # . # . . . . . . . . . . . . # . # . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . # # # . # # # # # . # . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. # . # . . . . . . . # # # . # # # # # . # . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. # # # . # # # # # . # . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
`, 400)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return score
|
|
||||||
}
|
|
||||||
|
|
||||||
function testMovement() {
|
|
||||||
while (!input.buttonIsPressed(Button.A)) {
|
|
||||||
// ##CHALLENGE 5: Add accelerometer test mode
|
|
||||||
let x = getCupPosition()
|
|
||||||
basic.clearScreen()
|
|
||||||
led.plot(x, 2)
|
|
||||||
basic.pause(200)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCupPosition(): number {
|
|
||||||
if (movement) {
|
|
||||||
let acc = input.acceleration(Dimension.X) / sensitivity
|
|
||||||
cupX = Math.clamp(0, 4, acc + 2)
|
|
||||||
return cupX
|
|
||||||
}
|
|
||||||
if (input.buttonIsPressed(Button.A)) {
|
|
||||||
if (cupX > 0) {
|
|
||||||
cupX = cupX - 1
|
|
||||||
}
|
|
||||||
} else if (input.buttonIsPressed(Button.B)) {
|
|
||||||
if (cupX < 4) {
|
|
||||||
cupX = cupX + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cupX
|
|
||||||
}
|
|
||||||
|
|
||||||
function startGame() {
|
|
||||||
basic.clearScreen()
|
|
||||||
// If button still held from start-game, wait until it is released
|
|
||||||
while (input.buttonIsPressed(Button.A)) {
|
|
||||||
// wait for button to be released
|
|
||||||
}
|
|
||||||
// handlers that work out if cup is turned upside down or not
|
|
||||||
input.onLogoDown(() => {
|
|
||||||
cupInverted = true
|
|
||||||
})
|
|
||||||
input.onLogoUp(() => {
|
|
||||||
cupInverted = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function beep(p: number) {
|
|
||||||
pins.digitalWritePin(DigitalPin.P0, 1)
|
|
||||||
basic.pause(p)
|
|
||||||
pins.digitalWritePin(DigitalPin.P0, 0)
|
|
||||||
}
|
|
@ -1,716 +0,0 @@
|
|||||||
let AWasPressed: boolean
|
|
||||||
let BWasPressed: boolean
|
|
||||||
let ABWasPressed: boolean
|
|
||||||
let wasShake: boolean
|
|
||||||
|
|
||||||
startIOMonitor()
|
|
||||||
let gameNo = 0
|
|
||||||
while (true) {
|
|
||||||
// select a new game
|
|
||||||
if (AWasPressed) {
|
|
||||||
gameNo = (gameNo + 1) % 4
|
|
||||||
AWasPressed = false
|
|
||||||
}
|
|
||||||
// show selected game
|
|
||||||
if (gameNo == 0) {
|
|
||||||
basic.showLeds(`
|
|
||||||
# # # # #
|
|
||||||
# . . . #
|
|
||||||
. # . # .
|
|
||||||
. . . . .
|
|
||||||
. # # # .
|
|
||||||
`)
|
|
||||||
} else if (gameNo == 1) {
|
|
||||||
basic.showLeds(`
|
|
||||||
# # # . .
|
|
||||||
# . . . .
|
|
||||||
# # # # #
|
|
||||||
# # . . .
|
|
||||||
# # # . .
|
|
||||||
`)
|
|
||||||
} else if (gameNo == 2) {
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
# . . . .
|
|
||||||
# # # # #
|
|
||||||
# . . . .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
} else if (gameNo == 3) {
|
|
||||||
basic.showLeds(`
|
|
||||||
# . # # #
|
|
||||||
# # # # #
|
|
||||||
. . . # #
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
// start selected game
|
|
||||||
if (BWasPressed) {
|
|
||||||
// Play the selected game
|
|
||||||
basic.clearScreen()
|
|
||||||
waitBReleased()
|
|
||||||
resetButtons()
|
|
||||||
let finalScore = 0
|
|
||||||
basic.clearScreen()
|
|
||||||
if (gameNo == 0) {
|
|
||||||
finalScore = playCybermen()
|
|
||||||
} else if (gameNo == 1) {
|
|
||||||
finalScore = playDalek()
|
|
||||||
} else if (gameNo == 2) {
|
|
||||||
finalScore = playSonicScrewdriver()
|
|
||||||
} else if (gameNo == 3) {
|
|
||||||
finalScore = playJudoonLanguage()
|
|
||||||
}
|
|
||||||
flashDigit(finalScore, 3)
|
|
||||||
resetButtons()
|
|
||||||
waitBPressed()
|
|
||||||
basic.clearScreen()
|
|
||||||
waitBReleased()
|
|
||||||
resetButtons()
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Game parameters
|
|
||||||
* Percentage chance that cyberman will move left/right to line up with you
|
|
||||||
*/
|
|
||||||
function playCybermen(): number {
|
|
||||||
let maxGameTime = 60
|
|
||||||
let cybermanMoveXProbability = 20
|
|
||||||
// How long (in 100ms ticks) cyberman must line up before moving forward
|
|
||||||
let cybermanMoveYCount = 10
|
|
||||||
// Game variables
|
|
||||||
let startTime = input.runningTime()
|
|
||||||
let gameTime = 0
|
|
||||||
let playerX = 2
|
|
||||||
let cybermanX = 1
|
|
||||||
let cybermanY = 0
|
|
||||||
let cybermanLineupCount = 0
|
|
||||||
let redraw = true
|
|
||||||
while (gameTime < maxGameTime) {
|
|
||||||
if (redraw) {
|
|
||||||
basic.clearScreen()
|
|
||||||
led.plot(playerX, 4)
|
|
||||||
led.plot(cybermanX, cybermanY)
|
|
||||||
redraw = false
|
|
||||||
}
|
|
||||||
// Handle Player Movement
|
|
||||||
if (AWasPressed) {
|
|
||||||
if (playerX > 0) {
|
|
||||||
playerX = playerX - 1
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
AWasPressed = false
|
|
||||||
} else if (BWasPressed) {
|
|
||||||
if (playerX < 4) {
|
|
||||||
playerX = playerX + 1
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
BWasPressed = false
|
|
||||||
}
|
|
||||||
// Handle Cyberman line-of-sight checking
|
|
||||||
if (cybermanX == playerX) {
|
|
||||||
cybermanLineupCount = cybermanLineupCount + 1
|
|
||||||
if (cybermanLineupCount >= cybermanMoveYCount) {
|
|
||||||
if (cybermanY == 4) {
|
|
||||||
// Cyberman caught you, game over
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
cybermanY = cybermanY + 1
|
|
||||||
redraw = true
|
|
||||||
cybermanLineupCount = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cybermanLineupCount = 0
|
|
||||||
// Move Cyberman closer to player, slowly
|
|
||||||
if (Math.random(100) < cybermanMoveXProbability) {
|
|
||||||
if (cybermanX > playerX) {
|
|
||||||
cybermanX = cybermanX - 1
|
|
||||||
} else if (cybermanX < playerX) {
|
|
||||||
cybermanX = cybermanX + 1
|
|
||||||
}
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
basic.pause(100)
|
|
||||||
gameTime = (input.runningTime() - startTime) / 1000
|
|
||||||
}
|
|
||||||
return convertSurvivalTimeToScore(gameTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Game parameters, all probabilities as a percentage
|
|
||||||
*/
|
|
||||||
function playDalek(): number {
|
|
||||||
let maxGameTime = 60
|
|
||||||
let userMoveSensitivity = 40
|
|
||||||
let dalekMoveSensitivity = 20
|
|
||||||
let dalekShootChance = 10
|
|
||||||
let dalekHitChance = 10
|
|
||||||
// Game variables
|
|
||||||
let gameTime = 0
|
|
||||||
let startTime = input.runningTime()
|
|
||||||
let dalekY = 2
|
|
||||||
let userY = 1
|
|
||||||
let redraw = true
|
|
||||||
while (gameTime < maxGameTime) {
|
|
||||||
// Redraw screen if necessary
|
|
||||||
if (redraw) {
|
|
||||||
basic.clearScreen()
|
|
||||||
led.plot(0, dalekY)
|
|
||||||
led.plot(4, userY)
|
|
||||||
redraw = false
|
|
||||||
}
|
|
||||||
// Work out if the user has moved, and move them
|
|
||||||
let tilt = getTilt()
|
|
||||||
if (tilt > 2) {
|
|
||||||
// Moving up, slowly
|
|
||||||
if (userY < 4) {
|
|
||||||
if (Math.random(100) < userMoveSensitivity) {
|
|
||||||
userY = userY + 1
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (tilt < 2) {
|
|
||||||
// Moving down (slowly)
|
|
||||||
if (userY > 0) {
|
|
||||||
if (Math.random(100) < userMoveSensitivity) {
|
|
||||||
userY = userY - 1
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Move the Dalek to line up with user
|
|
||||||
if (dalekY < userY) {
|
|
||||||
if (Math.random(100) < dalekMoveSensitivity) {
|
|
||||||
dalekY = dalekY + 1
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
} else if (dalekY > userY) {
|
|
||||||
if (Math.random(100) < dalekMoveSensitivity) {
|
|
||||||
dalekY = dalekY - 1
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Dalek lines up
|
|
||||||
if (Math.random(100) < dalekShootChance) {
|
|
||||||
// Shoot a raygun at the user
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
led.plot(i + 1, dalekY)
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
if (Math.random(100) < dalekHitChance) {
|
|
||||||
// User has been hit, game over
|
|
||||||
break
|
|
||||||
}
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gameTime = (input.runningTime() - startTime) / 1000
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
return convertSurvivalTimeToScore(gameTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set this in steps of 60
|
|
||||||
*/
|
|
||||||
function playSonicScrewdriver(): number {
|
|
||||||
let maxGameTime = 120
|
|
||||||
let gameTime = 0
|
|
||||||
// @=0, A=1 etc
|
|
||||||
// bit0=N, bit1=E, bit2=S, bit3=W
|
|
||||||
// bit=0 means it is a wall (can not be opened)
|
|
||||||
// bit=1 means it is a door (can be opened)
|
|
||||||
let mazestr = "BLFL@GOIFIGLCJIA"
|
|
||||||
let maze = ([] as number[])
|
|
||||||
// Locks use same number encoding (bits 0,1,2,3)
|
|
||||||
// bit=0 means door is locked (cannot be walked through)
|
|
||||||
// bit=1 means door is open (can be walked through)
|
|
||||||
let doorOpen = ([] as number[])
|
|
||||||
for (let i = 0; i < 16; i++) {
|
|
||||||
doorOpen.push(0)
|
|
||||||
maze.push(mazestr.charCodeAt(i) - 64)
|
|
||||||
}
|
|
||||||
let redraw = true
|
|
||||||
let cellno = 0
|
|
||||||
let direction = "N"
|
|
||||||
let startTime = input.runningTime()
|
|
||||||
while (gameTime < maxGameTime) {
|
|
||||||
// Draw the screen
|
|
||||||
if (redraw) {
|
|
||||||
basic.clearScreen()
|
|
||||||
// Always draw the maze with N at the top
|
|
||||||
drawMazeCell(doorOpen[cellno])
|
|
||||||
// draw user standing next to selected wall
|
|
||||||
if (direction == "N") {
|
|
||||||
led.plot(2, 1)
|
|
||||||
} else if (direction == "E") {
|
|
||||||
led.plot(3, 2)
|
|
||||||
} else if (direction == "S") {
|
|
||||||
led.plot(2, 3)
|
|
||||||
} else if (direction == "W") {
|
|
||||||
led.plot(1, 2)
|
|
||||||
}
|
|
||||||
redraw = false
|
|
||||||
}
|
|
||||||
// Sense any button presses
|
|
||||||
if (AWasPressed) {
|
|
||||||
if (direction == "N") {
|
|
||||||
direction = "E"
|
|
||||||
} else if (direction == "E") {
|
|
||||||
direction = "S"
|
|
||||||
} else if (direction == "S") {
|
|
||||||
direction = "W"
|
|
||||||
} else if (direction == "W") {
|
|
||||||
direction = "N"
|
|
||||||
}
|
|
||||||
redraw = true
|
|
||||||
AWasPressed = false
|
|
||||||
} else if (BWasPressed) {
|
|
||||||
// Try to walk through an open door
|
|
||||||
if (isDoorOpen(doorOpen[cellno], direction)) {
|
|
||||||
cellno = mazeForward(cellno, 4, 4, direction)
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
BWasPressed = false
|
|
||||||
} else if (wasShake) {
|
|
||||||
// energise sonic screwdriver
|
|
||||||
if (isDoorOpen(maze[cellno], direction)) {
|
|
||||||
// It is a door, but is the door open or closed?
|
|
||||||
if (!(isDoorOpen(doorOpen[cellno], direction))) {
|
|
||||||
// Open the door in front of us
|
|
||||||
doorOpen[cellno] = openDoor(doorOpen[cellno], direction)
|
|
||||||
// Also open the return door for when we walk through this door
|
|
||||||
let forwardCellno = mazeForward(cellno, 4, 4, direction)
|
|
||||||
doorOpen[forwardCellno] = openDoor(doorOpen[forwardCellno], opposite(direction))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Not a door
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. # . # .
|
|
||||||
. . # . .
|
|
||||||
. # . # .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
basic.pause(500)
|
|
||||||
}
|
|
||||||
redraw = true
|
|
||||||
wasShake = false
|
|
||||||
}
|
|
||||||
if (cellno == 15) {
|
|
||||||
// Have reached the exit cell
|
|
||||||
break
|
|
||||||
}
|
|
||||||
basic.pause(100)
|
|
||||||
gameTime = (input.runningTime() - startTime) / 1000
|
|
||||||
}
|
|
||||||
return convertPenaltyTimeToScore(gameTime / maxGameTime / 60)
|
|
||||||
}
|
|
||||||
|
|
||||||
function playJudoonLanguage(): number {
|
|
||||||
let maxGameTime = 60
|
|
||||||
let gameTime = 0
|
|
||||||
let startTime = input.runningTime()
|
|
||||||
let font = images.createImage(`
|
|
||||||
# . # # # # . # . # . . . . # # # . . . # # # # # # . # . # # # # . . . . . # # # . . . # # # # # #
|
|
||||||
# # # # # # # # # # . . . # # . # # # # . # . . . # # # # # # # # # # # # # # . # # # # # . . # . .
|
|
||||||
. . . . # # # # . . . . # # # . . . . # . # . . . . . . . # . . . # # . . # # # . . # . . # # # # #
|
|
||||||
# # # # # # # # # # . . # . . # # # # # # # # # # # # # # # # # # # . # # # # # # # # # # # # # . .
|
|
||||||
# # # # # # # # # # # # # # # # . . . . # . . . # # . . . . . . . # # # # # . . # # # # # # # # # #
|
|
||||||
`)
|
|
||||||
let answers = images.createImage(`
|
|
||||||
# # # # # # # # . . . # # # . . . # . . # . # . #
|
|
||||||
# . . . # # . . . . # # # # # . . . . . . . . . .
|
|
||||||
. # . # . # # # # . # . # . # . # . # . # . # . #
|
|
||||||
. . . . . # # # . . # . # . # . . . . . . . . . .
|
|
||||||
. # # # . # # # . . # . # . # # # # # # # . . . #
|
|
||||||
`)
|
|
||||||
let pages = "029 041 167 208 283"
|
|
||||||
let actualAnswer = Math.random(5)
|
|
||||||
let pos = 0
|
|
||||||
let redraw = true
|
|
||||||
while (gameTime < maxGameTime) {
|
|
||||||
// Draw the current frame from pos (0,1,2 codeword, 3,4,5,6,7 answers)
|
|
||||||
if (redraw) {
|
|
||||||
if (pos <= 2) {
|
|
||||||
// Draw codeword symbol for this choice and this position
|
|
||||||
let digit = parseInt(pages[actualAnswer * 4 + pos])
|
|
||||||
font.plotFrame(digit)
|
|
||||||
} else {
|
|
||||||
// Draw answer
|
|
||||||
let item = pos - 3
|
|
||||||
answers.plotFrame(item)
|
|
||||||
}
|
|
||||||
redraw = false
|
|
||||||
}
|
|
||||||
// Process button presses
|
|
||||||
if (AWasPressed) {
|
|
||||||
// Move left, unless at far left already
|
|
||||||
AWasPressed = false
|
|
||||||
if (pos > 0) {
|
|
||||||
pos = pos - 1
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
} else if (BWasPressed) {
|
|
||||||
// Move right, unless already at far right
|
|
||||||
BWasPressed = false
|
|
||||||
if (pos < 7) {
|
|
||||||
pos = pos + 1
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
} else if (wasShake) {
|
|
||||||
// User trying to select an answer, are we at an answer position?
|
|
||||||
wasShake = false
|
|
||||||
if (pos >= 3) {
|
|
||||||
// Is it the right answer?
|
|
||||||
let userChoice = pos - 3
|
|
||||||
if (userChoice == actualAnswer) {
|
|
||||||
// CORRECT
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . #
|
|
||||||
. . . . . . . . . . . . . . . . . . # . . . . # .
|
|
||||||
# . . . . # . . . . # . # . . # . # . . # . # . .
|
|
||||||
. . . . . . # . . . . # . . . . # . . . . # . . .
|
|
||||||
`, 400)
|
|
||||||
basic.pause(1000)
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
// WRONG
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . # # . . . # # . . . # # . . . # # . . . #
|
|
||||||
. . . . . . . . . . . . . . . . . . # . . . . # . . . . # . . # . # . . # . # . . # . # .
|
|
||||||
. . . . . . . . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . .
|
|
||||||
. . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . # . . # . # .
|
|
||||||
# . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . #
|
|
||||||
`, 400)
|
|
||||||
basic.pause(1000)
|
|
||||||
redraw = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gameTime = (input.runningTime() - startTime) / 1000
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
return convertPenaltyTimeToScore(gameTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDirection(): string {
|
|
||||||
let bearing = input.compassHeading()
|
|
||||||
if (bearing < 45 || bearing > 315) {
|
|
||||||
return "N"
|
|
||||||
} else if (bearing < 135) {
|
|
||||||
return "E"
|
|
||||||
} else if (bearing < 225) {
|
|
||||||
return "S"
|
|
||||||
} else {
|
|
||||||
return "W"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function calibrateCompass() {
|
|
||||||
if (input.compassHeading() == -4) {
|
|
||||||
input.calibrate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitBReleased() {
|
|
||||||
while (input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitBPressed() {
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the score 0..9
|
|
||||||
* @param digit TODO
|
|
||||||
* @param times TODO
|
|
||||||
*/
|
|
||||||
function flashDigit(digit: number, times: number) {
|
|
||||||
digit = Math.clamp(0, 9, digit)
|
|
||||||
for (let i = 0; i < times; i++) {
|
|
||||||
basic.showNumber(digit, 0)
|
|
||||||
basic.pause(500)
|
|
||||||
basic.clearScreen()
|
|
||||||
basic.pause(500)
|
|
||||||
}
|
|
||||||
basic.showNumber(digit, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* score is calculated as the amount of time you lasted
|
|
||||||
* @param gameTime TODO
|
|
||||||
*/
|
|
||||||
function convertSurvivalTimeToScore(gameTime: number): number {
|
|
||||||
if (gameTime <= 4) {
|
|
||||||
return 0
|
|
||||||
} else if (gameTime <= 9) {
|
|
||||||
return 1
|
|
||||||
} else if (gameTime <= 14) {
|
|
||||||
return 2
|
|
||||||
} else if (gameTime <= 19) {
|
|
||||||
return 3
|
|
||||||
} else if (gameTime <= 24) {
|
|
||||||
return 4
|
|
||||||
} else if (gameTime <= 29) {
|
|
||||||
return 5
|
|
||||||
} else if (gameTime <= 39) {
|
|
||||||
return 6
|
|
||||||
} else if (gameTime <= 49) {
|
|
||||||
return 7
|
|
||||||
} else if (gameTime <= 59) {
|
|
||||||
return 8
|
|
||||||
} else {
|
|
||||||
return 9
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertPenaltyTimeToScore(penaltyTime: number): number {
|
|
||||||
if (penaltyTime <= 4) {
|
|
||||||
return 9
|
|
||||||
} else if (penaltyTime <= 9) {
|
|
||||||
return 8
|
|
||||||
} else if (penaltyTime <= 14) {
|
|
||||||
return 7
|
|
||||||
} else if (penaltyTime <= 19) {
|
|
||||||
return 6
|
|
||||||
} else if (penaltyTime <= 24) {
|
|
||||||
return 5
|
|
||||||
} else if (penaltyTime <= 29) {
|
|
||||||
return 4
|
|
||||||
} else if (penaltyTime <= 39) {
|
|
||||||
return 3
|
|
||||||
} else if (penaltyTime <= 49) {
|
|
||||||
return 2
|
|
||||||
} else if (penaltyTime <= 59) {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function startIOMonitor() {
|
|
||||||
input.onButtonPressed(Button.A, () => {
|
|
||||||
AWasPressed = true
|
|
||||||
})
|
|
||||||
input.onButtonPressed(Button.B, () => {
|
|
||||||
BWasPressed = true
|
|
||||||
})
|
|
||||||
input.onButtonPressed(Button.AB, () => {
|
|
||||||
ABWasPressed = true
|
|
||||||
})
|
|
||||||
input.onShake(() => {
|
|
||||||
wasShake = true
|
|
||||||
})
|
|
||||||
AWasPressed = false
|
|
||||||
BWasPressed = false
|
|
||||||
ABWasPressed = false
|
|
||||||
wasShake = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* maze is always drawn with north at top
|
|
||||||
* @param cell TODO
|
|
||||||
*/
|
|
||||||
function drawMazeCell(cell: number) {
|
|
||||||
let n = !(isNorth(cell))
|
|
||||||
let e = !(isEast(cell))
|
|
||||||
let s = !(isSouth(cell))
|
|
||||||
let w = !(isWest(cell))
|
|
||||||
// Draw any visible walls
|
|
||||||
if (n) {
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
led.plot(i, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (e) {
|
|
||||||
for (let l = 0; l < 5; l++) {
|
|
||||||
led.plot(4, l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s) {
|
|
||||||
for (let k = 0; k < 5; k++) {
|
|
||||||
led.plot(k, 4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (w) {
|
|
||||||
for (let j = 0; j < 5; j++) {
|
|
||||||
led.plot(0, j)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* work out the cell number in front of this cell
|
|
||||||
* given the direction N E S W (N points to button B)
|
|
||||||
* returns the forward cell number, -1 if outside of maze
|
|
||||||
* Turn cellno into an x and y based on width and height
|
|
||||||
* @param cellno TODO
|
|
||||||
* @param width TODO
|
|
||||||
* @param height TODO
|
|
||||||
* @param direction TODO
|
|
||||||
*/
|
|
||||||
function mazeForward(cellno: number, width: number, height: number, direction: string): number {
|
|
||||||
let y = cellno / width
|
|
||||||
let x = cellno % width
|
|
||||||
// Work out change in x/y and therefore change in cellno
|
|
||||||
// But bounds-check against width and height
|
|
||||||
// as user cannot walk outside of the maze
|
|
||||||
if (direction == "N") {
|
|
||||||
// sub 1 from y
|
|
||||||
if (y > 0) {
|
|
||||||
return cellno - width
|
|
||||||
}
|
|
||||||
} else if (direction == "E") {
|
|
||||||
// Add 1 to x
|
|
||||||
if (x < width - 1) {
|
|
||||||
return cellno + 1
|
|
||||||
}
|
|
||||||
} else if (direction == "S") {
|
|
||||||
// add 1 to y
|
|
||||||
if (y < height - 1) {
|
|
||||||
return cellno + width
|
|
||||||
}
|
|
||||||
} else if (direction == "W") {
|
|
||||||
// sub 1 from x
|
|
||||||
if (x > 0) {
|
|
||||||
return cellno - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Not allowed to move in this direction, it will go outside of maze
|
|
||||||
return - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A door is open if the lock bit is 1
|
|
||||||
* A door is present if the maze bit is 1
|
|
||||||
* @param cell TODO
|
|
||||||
* @param direction TODO
|
|
||||||
*/
|
|
||||||
function isDoorOpen(cell: number, direction: string): boolean {
|
|
||||||
if (direction == "N") {
|
|
||||||
return isNorth(cell)
|
|
||||||
} else if (direction == "E") {
|
|
||||||
return isEast(cell)
|
|
||||||
}
|
|
||||||
if (direction == "S") {
|
|
||||||
return isSouth(cell)
|
|
||||||
} else if (direction == "W") {
|
|
||||||
return isWest(cell)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTilt(): number {
|
|
||||||
let tilt: number
|
|
||||||
tilt = input.acceleration(Dimension.Y)
|
|
||||||
tilt = Math.clamp(-1024, 1023, tilt)
|
|
||||||
tilt = (tilt + 1024) / 512
|
|
||||||
return tilt
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitAReleased() {
|
|
||||||
while (input.buttonIsPressed(Button.A)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitNoButtons() {
|
|
||||||
while (input.buttonIsPressed(Button.A) || input.buttonIsPressed(Button.B) || input.buttonIsPressed(Button.AB)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetButtons() {
|
|
||||||
AWasPressed = false
|
|
||||||
BWasPressed = false
|
|
||||||
ABWasPressed = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The appropriate bit (0,1,2,3) is set, which unlocks the door
|
|
||||||
* @param cell TODO
|
|
||||||
* @param direction TODO
|
|
||||||
*/
|
|
||||||
function openDoor(cell: number, direction: string): number {
|
|
||||||
if (direction == "N") {
|
|
||||||
return cell | 1
|
|
||||||
} else if (direction == "E") {
|
|
||||||
return cell | 2
|
|
||||||
} else if (direction == "S") {
|
|
||||||
return cell | 4
|
|
||||||
} else if (direction == "W") {
|
|
||||||
return cell | 8
|
|
||||||
}
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is the north bit set in the cell?
|
|
||||||
* @param cell TODO
|
|
||||||
*/
|
|
||||||
function isNorth(cell: number): boolean {
|
|
||||||
if ((cell & 1) != 0) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is the east bit set in the cell?
|
|
||||||
* @param cell TODO
|
|
||||||
*/
|
|
||||||
function isEast(cell: number): boolean {
|
|
||||||
if ((cell & 2) != 0) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is the south bit set in the cell?
|
|
||||||
* @param cell TODO
|
|
||||||
*/
|
|
||||||
function isSouth(cell: number): boolean {
|
|
||||||
if ((cell & 4) != 0) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is the west bit set in the cell?
|
|
||||||
* @param cell TODO
|
|
||||||
*/
|
|
||||||
function isWest(cell: number): boolean {
|
|
||||||
if ((cell & 8) != 0) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function opposite(direction: string): string {
|
|
||||||
if (direction == "N") {
|
|
||||||
return "S"
|
|
||||||
} else if (direction == "E") {
|
|
||||||
return "W"
|
|
||||||
} else if (direction == "S") {
|
|
||||||
return "N"
|
|
||||||
} else if (direction == "W") {
|
|
||||||
return "E"
|
|
||||||
}
|
|
||||||
return direction
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSount() { }
|
|
@ -1,165 +0,0 @@
|
|||||||
let sensorType: string
|
|
||||||
|
|
||||||
// ANALOG or TILT
|
|
||||||
sensorType = "TILT"
|
|
||||||
while (true) {
|
|
||||||
// splash screen (flood monitor)
|
|
||||||
basic.showLeds(`
|
|
||||||
# # # . .
|
|
||||||
# . . . .
|
|
||||||
# # . # .
|
|
||||||
# . . # .
|
|
||||||
# . . # #
|
|
||||||
`)
|
|
||||||
while (true) {
|
|
||||||
if (input.buttonIsPressed(Button.A)) {
|
|
||||||
// test that the sensor works
|
|
||||||
testMode()
|
|
||||||
break
|
|
||||||
} else if (input.buttonIsPressed(Button.B)) {
|
|
||||||
// run the real flood monitor
|
|
||||||
floodMonitor()
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test mode - test that the monitor and buzzer work
|
|
||||||
* no filtering in this mode, direct screen update
|
|
||||||
*/
|
|
||||||
function testMode() {
|
|
||||||
basic.showLeds(`
|
|
||||||
# # # # #
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
`)
|
|
||||||
waitNoButtons()
|
|
||||||
let img = images.createImage(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . # # # # #
|
|
||||||
. . . . . . . . . . . . . . . # # # # # . . . . .
|
|
||||||
. . . . . . . . . . # # # # # . . . . . . . . . .
|
|
||||||
. . . . . # # # # # . . . . . . . . . . . . . . .
|
|
||||||
# # # # # . . . . . . . . . . . . . . . . . . . .
|
|
||||||
`)
|
|
||||||
while (!input.buttonIsPressed(Button.A)) {
|
|
||||||
// Show live reading on display
|
|
||||||
let value = readSensor()
|
|
||||||
img.showImage(value * 5)
|
|
||||||
// Turn beeper on only if maximum value seen
|
|
||||||
if (value >= 4) {
|
|
||||||
pins.digitalWritePin(DigitalPin.P1, 1)
|
|
||||||
} else {
|
|
||||||
pins.digitalWritePin(DigitalPin.P1, 0)
|
|
||||||
}
|
|
||||||
basic.pause(50)
|
|
||||||
}
|
|
||||||
waitNoButtons()
|
|
||||||
}
|
|
||||||
|
|
||||||
function floodMonitor() {
|
|
||||||
basic.showLeds(`
|
|
||||||
# . . . #
|
|
||||||
# # . # #
|
|
||||||
# . # . #
|
|
||||||
# . . . #
|
|
||||||
# . . . #
|
|
||||||
`)
|
|
||||||
waitNoButtons()
|
|
||||||
let line = images.createImage(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . # # # # #
|
|
||||||
. . . . . . . . . . . . . . . # # # # # . . . . .
|
|
||||||
. . . . . . . . . . # # # # # . . . . . . . . . .
|
|
||||||
. . . . . # # # # # . . . . . . . . . . . . . . .
|
|
||||||
# # # # # . . . . . . . . . . . . . . . . . . . .
|
|
||||||
`)
|
|
||||||
let state = "SAFE"
|
|
||||||
let averagedValue = 0
|
|
||||||
while (!input.buttonIsPressed(Button.A)) {
|
|
||||||
let value = readSensor()
|
|
||||||
// Apply some 'lag' filtering to the value, so that 'bobbing' doesn't set off alarm
|
|
||||||
// i.e. to go from 0 to 4 takes 4 times round the loop
|
|
||||||
if (value > averagedValue) {
|
|
||||||
// On the way up, changes in reading are slowed down
|
|
||||||
averagedValue = averagedValue + 1
|
|
||||||
} else if (value < averagedValue) {
|
|
||||||
// On the way down, changes in reading happen immediately
|
|
||||||
averagedValue = value
|
|
||||||
}
|
|
||||||
// Work out what to do based on the averaged value (non bobbing value)
|
|
||||||
if (state == "SAFE") {
|
|
||||||
if (averagedValue >= 4) {
|
|
||||||
pins.digitalWritePin(DigitalPin.P1, 1)
|
|
||||||
state = "ALARMING"
|
|
||||||
} else {
|
|
||||||
// Display raw value as a line
|
|
||||||
line.showImage(value * 5)
|
|
||||||
// fill in based on averaged value (long term reading)
|
|
||||||
for (let i = 0; i < averagedValue; i++) {
|
|
||||||
led.plot(2, 4 - i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (state == "ALARMING") {
|
|
||||||
if (input.buttonIsPressed(Button.B)) {
|
|
||||||
pins.digitalWritePin(DigitalPin.P1, 0)
|
|
||||||
state = "SAFE"
|
|
||||||
} else {
|
|
||||||
basic.showAnimation(`
|
|
||||||
# # # # # . . . . .
|
|
||||||
# # # # # . . . . .
|
|
||||||
# # # # # . . . . .
|
|
||||||
# # # # # . . . . .
|
|
||||||
# # # # # . . . . .
|
|
||||||
`, 400)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
basic.pause(300)
|
|
||||||
}
|
|
||||||
waitNoButtons()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a value 0,1,2,3,4 from either ANALOG or TILT
|
|
||||||
*/
|
|
||||||
function readSensor(): number {
|
|
||||||
let value = 0
|
|
||||||
// Produce a sensor value in range 0..1023
|
|
||||||
if (sensorType == "ANALOG") {
|
|
||||||
// Input range is 0..1023
|
|
||||||
value = pins.analogReadPin(AnalogPin.P0)
|
|
||||||
} else if (sensorType == "TILT") {
|
|
||||||
// Input range is -1024 (pads highest)..1023 (pads lowest)
|
|
||||||
value = input.acceleration(Dimension.Y)
|
|
||||||
// Emulator sometimes returns out of range values, so clamp to expected range
|
|
||||||
value = Math.clamp(-1024, 1023, value)
|
|
||||||
// Convert to an entirely positive range from 0 pads full up to 2047 pads full down
|
|
||||||
// (hinged at the 'eyes' end)
|
|
||||||
value = value + 1024
|
|
||||||
// Invert the direction, so that "pads up" is largest, "pads down" is smallest
|
|
||||||
value = 2047 - value
|
|
||||||
// We want the same range as the analog, so halve the range
|
|
||||||
value = value / 2
|
|
||||||
}
|
|
||||||
// 5 possible values (0,1,2,3,4) based on sensible thresholds
|
|
||||||
// We do this by thresholds, so that we have more control over the 5 levels
|
|
||||||
if (value < 200) {
|
|
||||||
return 0
|
|
||||||
} else if (value < 400) {
|
|
||||||
return 1
|
|
||||||
} else if (value < 600) {
|
|
||||||
return 2
|
|
||||||
} else if (value < 800) {
|
|
||||||
return 3
|
|
||||||
}
|
|
||||||
return 4
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitNoButtons() {
|
|
||||||
while (input.buttonIsPressed(Button.A) || input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,529 +0,0 @@
|
|||||||
let opMaxTime: number
|
|
||||||
let procMaxTime: number
|
|
||||||
let procsToDo: number
|
|
||||||
let recoveryTriesMax: number
|
|
||||||
let tenseTime: number
|
|
||||||
let flatlineTimeMax: number
|
|
||||||
let recoveryProbability: number
|
|
||||||
let aWasPressed: boolean
|
|
||||||
let bWasPressed: boolean
|
|
||||||
let digitsImg: Image
|
|
||||||
let tweezerCount_: number
|
|
||||||
let wasTweezers: boolean
|
|
||||||
let wasNose: boolean
|
|
||||||
let isTweezers: boolean
|
|
||||||
|
|
||||||
// P0 blue wire, tweezers (active high)
|
|
||||||
// P1, green wire nose button/LED (active high)
|
|
||||||
// P2/red speaker (not a self toned beeper, but a piezo or a speaker)
|
|
||||||
opMaxTime = 120 * 1000
|
|
||||||
procsToDo = 3
|
|
||||||
procMaxTime = 60 * 1000
|
|
||||||
tenseTime = 4000
|
|
||||||
flatlineTimeMax = 15 * 1000
|
|
||||||
recoveryTriesMax = 3
|
|
||||||
recoveryProbability = 60
|
|
||||||
let highScore = 0
|
|
||||||
digitsImg = images.createImage(`
|
|
||||||
. . # . . . . # . . . # # . . . # # . . . # . . . . # # # . . . # # . . # # # . . . # . . . . # . .
|
|
||||||
. # . # . . # # . . . . . # . . . . # . . # . . . . # . . . . # . . . . . . . . . # . # . . # . # .
|
|
||||||
. # . # . . . # . . . . # . . . . # . . . # # # . . . # . . . # # . . . . # . . . . # . . . . # # .
|
|
||||||
. # . # . . . # . . . # . . . . . . # . . . # . . . . . # . . # . # . . # . . . . # . # . . . . # .
|
|
||||||
. . # . . . # # # . . # # # . . # # . . . . # . . . # # . . . . # . . . # . . . . . # . . . # # . .
|
|
||||||
`)
|
|
||||||
startIOMonitor()
|
|
||||||
while (true) {
|
|
||||||
splashScreen()
|
|
||||||
if (buttonB()) {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . # # . . . . # . . . . # . . . . . . # . . . . . .
|
|
||||||
. . . . # . . . . # # # . . # . # . . # . . # . # . . . . #
|
|
||||||
. . . . # . . . . # . . . . # # # . . # # # . . # # # # # #
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
# . . . # # . . . # # . . . # # . . . # # . . . # # . . . #
|
|
||||||
`, 400)
|
|
||||||
let finalScore = surgery()
|
|
||||||
if (game.score() > highScore) {
|
|
||||||
basic.showString("HI", 150)
|
|
||||||
highScore = finalScore
|
|
||||||
}
|
|
||||||
flashDigit(finalScore)
|
|
||||||
waitButtonB()
|
|
||||||
} else if (buttonA()) {
|
|
||||||
testMode()
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function surgery(): number {
|
|
||||||
let score = 0
|
|
||||||
let speed = 150
|
|
||||||
let opStartTime = input.runningTime()
|
|
||||||
let procStartTime = -1
|
|
||||||
let procNumber = -1
|
|
||||||
let procsDone = 0
|
|
||||||
let recoveryTry = 0
|
|
||||||
let timer = 0
|
|
||||||
let state = "CHOOSE PROC"
|
|
||||||
resetButtons()
|
|
||||||
while (true) {
|
|
||||||
basic.pause(10)
|
|
||||||
let event = getEvent(state)
|
|
||||||
if (event == "CUT") {
|
|
||||||
state = "ARREST"
|
|
||||||
}
|
|
||||||
// CHECK TIMERS
|
|
||||||
if (!(procStartTime == -1)) {
|
|
||||||
if (input.runningTime() - procStartTime > procMaxTime) {
|
|
||||||
state = "LOST"
|
|
||||||
} else {
|
|
||||||
// TODO add code here to speed up near end of proc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (input.runningTime() - opStartTime > opMaxTime) {
|
|
||||||
state = "LOST"
|
|
||||||
} else {
|
|
||||||
// TODO add code here to speed up near end of op
|
|
||||||
}
|
|
||||||
// PROCESS SPECIFIC STATES
|
|
||||||
if (state == "CHOOSE PROC") {
|
|
||||||
if (procNumber == -1) {
|
|
||||||
procNumber = 1
|
|
||||||
showDigit(procNumber)
|
|
||||||
} else if (event == "SCROLL") {
|
|
||||||
procNumber = procNumber + 1
|
|
||||||
if (procNumber > 9) {
|
|
||||||
procNumber = 1
|
|
||||||
}
|
|
||||||
showDigit(procNumber)
|
|
||||||
} else if (event == "SELECT") {
|
|
||||||
procStartTime = input.runningTime()
|
|
||||||
state = "HEALTHY"
|
|
||||||
speed = 100
|
|
||||||
}
|
|
||||||
} else if (state == "HEALTHY") {
|
|
||||||
speed = 100
|
|
||||||
ecg(speed)
|
|
||||||
if (event == "TWINGE") {
|
|
||||||
state = "TENSE"
|
|
||||||
timer = input.runningTime()
|
|
||||||
} else if (event == "DONE") {
|
|
||||||
state = "PROC DONE"
|
|
||||||
}
|
|
||||||
} else if (state == "TENSE") {
|
|
||||||
speed = 25
|
|
||||||
ecg(speed)
|
|
||||||
if (event == "TWINGE") {
|
|
||||||
state = "ARREST"
|
|
||||||
} else if (input.runningTime() - timer > tenseTime) {
|
|
||||||
state = "HEALTHY"
|
|
||||||
}
|
|
||||||
} else if (state == "ARREST") {
|
|
||||||
timer = input.runningTime()
|
|
||||||
recoveryTry = recoveryTriesMax
|
|
||||||
state = "FLATLINE"
|
|
||||||
} else if (state == "FLATLINE") {
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. # . # .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
# # # # #
|
|
||||||
`)
|
|
||||||
beepOn()
|
|
||||||
if (event == "SHOCK") {
|
|
||||||
state = "SHOCKING"
|
|
||||||
} else if (input.runningTime() - timer > flatlineTimeMax) {
|
|
||||||
state = "LOST"
|
|
||||||
}
|
|
||||||
} else if (state == "SHOCKING") {
|
|
||||||
charging()
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . # . . . . # . . . . . . . . . .
|
|
||||||
. . . # . . . . # . . . . # . . . . . .
|
|
||||||
. . . . . . . # . . . . # . . . . # . .
|
|
||||||
. . . . . . . . . . . # . . . . # . . .
|
|
||||||
. . . . . . . . . . . . . . . . # . . .
|
|
||||||
`, 150)
|
|
||||||
beepNTimesFor(15, 500)
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . # . . . #
|
|
||||||
. . . . . . . . . . # . . # . . . . . .
|
|
||||||
. . . . . # . # . . . . . . . . . . . .
|
|
||||||
. # . . . . # . . . . . . . . . . . . .
|
|
||||||
. # . . . . # . . . . # . . . . # . . .
|
|
||||||
`, 150)
|
|
||||||
state = "SHOCKED"
|
|
||||||
} else if (state == "SHOCKED") {
|
|
||||||
let recover = Math.random(100)
|
|
||||||
if (recover >= recoveryProbability) {
|
|
||||||
state = "RECOVERED"
|
|
||||||
} else {
|
|
||||||
state = "FAILED"
|
|
||||||
}
|
|
||||||
} else if (state == "RECOVERED") {
|
|
||||||
beepOff()
|
|
||||||
basic.pause(500)
|
|
||||||
beep()
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. # . # . . . . . . . # . # . . . . . . . # . # .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
# . . . # . . . . . # . . . # . . . . . # . . . #
|
|
||||||
. # # # . . . . . . . # # # . . . . . . . # # # .
|
|
||||||
`, 400)
|
|
||||||
state = "HEALTHY"
|
|
||||||
} else if (state == "FAILED") {
|
|
||||||
recoveryTry = recoveryTry - 1
|
|
||||||
if (recoveryTry > 0) {
|
|
||||||
state = "FLATLINE"
|
|
||||||
} else {
|
|
||||||
state = "LOST"
|
|
||||||
}
|
|
||||||
} else if (state == "PROC DONE") {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . #
|
|
||||||
. . . . . . . . . . . . . . . . . . # . . . . # .
|
|
||||||
# . . . . # . . . . # . # . . # . # . . # . # . .
|
|
||||||
. . . . . . # . . . . # . . . . # . . . . # . . .
|
|
||||||
`, 400)
|
|
||||||
score = score + pointsForProc(procNumber)
|
|
||||||
procsDone = procsDone + 1
|
|
||||||
procStartTime = -1
|
|
||||||
if (procsDone == procsToDo) {
|
|
||||||
state = "OP DONE"
|
|
||||||
} else {
|
|
||||||
procNumber = -1
|
|
||||||
state = "CHOOSE PROC"
|
|
||||||
}
|
|
||||||
} else if (state == "OP DONE") {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . # . . # . . . . . # . . . . . # . . . . . # . . # . . . . # . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . # . . # . # . # . . # . . # . . . . . # . . . . . # . . # . . . . # . . . # . . . # . . . . . . . . .
|
|
||||||
# # # # # # # . . # # # . . # . # # . . . . # # . . . . # # . # # . . . . # . . . # . . . # . . . . . . . . .
|
|
||||||
# # # # # # # # # # # # # # # . # # # # . . # # # . . . # # . . . # # . . # # # . # . # # # . . # # . . . # #
|
|
||||||
# . . . # # . . . # # . . . # . # . . . . . # . . . . . # . . . . # . . . . # . . # . # . # . . # . . . . # .
|
|
||||||
`, 400)
|
|
||||||
return score
|
|
||||||
} else if (state == "LOST") {
|
|
||||||
beepOn()
|
|
||||||
basic.showLeds(`
|
|
||||||
. # . # .
|
|
||||||
. . # . .
|
|
||||||
. # . # .
|
|
||||||
. . . . .
|
|
||||||
# # # # #
|
|
||||||
`)
|
|
||||||
basic.pause(3000)
|
|
||||||
beepOff()
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . # # # # # # . . . . # . . . . # . . . . # # . # . # . . . . # # . # . # . . . . #
|
|
||||||
# # # # # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . #
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
# . . . # # . . . # # . . . # # . . . # # . . . # # . . . # # . . . # # . . . # # . . . #
|
|
||||||
`, 400)
|
|
||||||
return score
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* if any button pressed, terminate the animation immediately
|
|
||||||
*/
|
|
||||||
function splashScreen() {
|
|
||||||
let img = images.createImage(`
|
|
||||||
. # . # . . # . # . . # . # . . # . # . . . # . . . # # . .
|
|
||||||
# # # # # # . # . # # # # # # # . # . # . # . # . . # . # .
|
|
||||||
# # # # # # . . . # # # # # # # . . . # . # . # . . # # . .
|
|
||||||
. # # # . . # . # . . # # # . . # . # . . # . # . . # . . .
|
|
||||||
. . # . . . . # . . . . # . . . . # . . . . # . . . # . . .
|
|
||||||
`)
|
|
||||||
let x = 0
|
|
||||||
while (!aWasPressed && !bWasPressed) {
|
|
||||||
img.showImage(x)
|
|
||||||
basic.pause(500)
|
|
||||||
x = x + 5
|
|
||||||
if (x >= img.width()) {
|
|
||||||
x = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test sensing and buzzing
|
|
||||||
* I/O at moment is (assuming self toning beeper)
|
|
||||||
* P0 is beeper and nose LED
|
|
||||||
* P1 is the tweezer sense wire
|
|
||||||
* P2 is possibly the nose button
|
|
||||||
* If we want amplification, might have to use piezo library
|
|
||||||
* which means using extra pins
|
|
||||||
*/
|
|
||||||
function testMode() {
|
|
||||||
while (!(buttonA())) {
|
|
||||||
if (pins.digitalReadPin(DigitalPin.P1) == 1) {
|
|
||||||
pins.digitalWritePin(DigitalPin.P0, 1)
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. . . . #
|
|
||||||
. . . # .
|
|
||||||
# . # . .
|
|
||||||
. # . . .
|
|
||||||
`)
|
|
||||||
} else {
|
|
||||||
pins.digitalWritePin(DigitalPin.P0, 0)
|
|
||||||
basic.showLeds(`
|
|
||||||
# # # # #
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SENSE TWINGE/CUT FROM TWEEZERS (10ms per sample)
|
|
||||||
* @param state TODO
|
|
||||||
*/
|
|
||||||
function getEvent(state: string): string {
|
|
||||||
if (wasTweezers) {
|
|
||||||
if (tweezerCount_ > 20) {
|
|
||||||
wasTweezers = false
|
|
||||||
tweezerCount_ = 0
|
|
||||||
return "CUT"
|
|
||||||
} else if (!isTweezers) {
|
|
||||||
wasTweezers = false
|
|
||||||
tweezerCount_ = 0
|
|
||||||
return "TWINGE"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// SENSE A OR B BUTTON PRESSES
|
|
||||||
if (state == "CHOOSE PROC") {
|
|
||||||
if (buttonA()) {
|
|
||||||
return "SCROLL"
|
|
||||||
} else if (buttonB()) {
|
|
||||||
return "SELECT"
|
|
||||||
}
|
|
||||||
} else if (state == "FLATLINE") {
|
|
||||||
if (buttonB()) {
|
|
||||||
return "SHOCK"
|
|
||||||
} else if (nose()) {
|
|
||||||
return "SHOCK"
|
|
||||||
}
|
|
||||||
} else if (state == "HEALTHY") {
|
|
||||||
if (buttonB()) {
|
|
||||||
return "DONE"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Clear any flags for unnecessary events in a given state to prevent latching
|
|
||||||
aWasPressed = false
|
|
||||||
bWasPressed = false
|
|
||||||
return "NONE"
|
|
||||||
}
|
|
||||||
|
|
||||||
function flashDigit(digit: number) {
|
|
||||||
for (let i = 0; i < 4; i++) {
|
|
||||||
showDigit(digit)
|
|
||||||
basic.pause(200)
|
|
||||||
basic.clearScreen()
|
|
||||||
basic.pause(200)
|
|
||||||
}
|
|
||||||
showDigit(digit)
|
|
||||||
basic.pause(1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a short beep sound
|
|
||||||
*/
|
|
||||||
function beep() {
|
|
||||||
beepOn()
|
|
||||||
basic.pause(200)
|
|
||||||
beepOff()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* work out score for a procedure
|
|
||||||
* @param procNumber TODO
|
|
||||||
*/
|
|
||||||
function pointsForProc(procNumber: number): number {
|
|
||||||
if (procNumber < 4) {
|
|
||||||
return 1
|
|
||||||
} else if (procNumber < 7) {
|
|
||||||
return 2
|
|
||||||
} else {
|
|
||||||
return 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* beep n times, for a total duration of m
|
|
||||||
* @param times TODO
|
|
||||||
* @param duration TODO
|
|
||||||
*/
|
|
||||||
function beepNTimesFor(times: number, duration: number) {
|
|
||||||
let halfCycle = duration / (times * 2)
|
|
||||||
for (let i = 0; i < times; i++) {
|
|
||||||
beepOn()
|
|
||||||
basic.pause(halfCycle)
|
|
||||||
beepOff()
|
|
||||||
basic.pause(halfCycle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function startIOMonitor() {
|
|
||||||
aWasPressed = false
|
|
||||||
input.onButtonPressed(Button.A, () => {
|
|
||||||
aWasPressed = true
|
|
||||||
})
|
|
||||||
bWasPressed = false
|
|
||||||
input.onButtonPressed(Button.B, () => {
|
|
||||||
bWasPressed = true
|
|
||||||
})
|
|
||||||
wasTweezers = false
|
|
||||||
isTweezers = false
|
|
||||||
tweezerCount_ = 0
|
|
||||||
control.inBackground(() => {
|
|
||||||
let buzzCount = 0
|
|
||||||
while (true) {
|
|
||||||
if (pins.digitalReadPin(DigitalPin.P0) == 1) {
|
|
||||||
wasTweezers = true
|
|
||||||
isTweezers = true
|
|
||||||
tweezerCount_ = tweezerCount_ + 1
|
|
||||||
if (buzzCount == 0) {
|
|
||||||
pins.analogWritePin(AnalogPin.P2, 512)
|
|
||||||
pins.analogSetPeriod(AnalogPin.P2, 5000)
|
|
||||||
}
|
|
||||||
buzzCount = 10
|
|
||||||
} else {
|
|
||||||
isTweezers = false
|
|
||||||
}
|
|
||||||
if (buzzCount > 0) {
|
|
||||||
buzzCount = buzzCount - 1
|
|
||||||
if (buzzCount == 0) {
|
|
||||||
pins.analogWritePin(AnalogPin.P2, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
basic.pause(10)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a single digit, with a nicer font than the standard micro:bit font
|
|
||||||
* @param digit TODO
|
|
||||||
*/
|
|
||||||
function showDigit(digit: number) {
|
|
||||||
digit = Math.clamp(0, 9, digit)
|
|
||||||
digitsImg.showImage(digit * 5)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check to see if button A was pressed recently
|
|
||||||
*/
|
|
||||||
function buttonA(): boolean {
|
|
||||||
if (aWasPressed) {
|
|
||||||
aWasPressed = false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitButtonA() {
|
|
||||||
while (!(buttonA())) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buttonB(): boolean {
|
|
||||||
if (bWasPressed) {
|
|
||||||
bWasPressed = false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitButtonB() {
|
|
||||||
while (!(buttonB())) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function beepOn() {
|
|
||||||
pins.analogWritePin(AnalogPin.P2, 512)
|
|
||||||
pins.analogSetPeriod(AnalogPin.P2, 2272)
|
|
||||||
}
|
|
||||||
|
|
||||||
function beepOff() {
|
|
||||||
pins.analogWritePin(AnalogPin.P2, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetButtons() {
|
|
||||||
aWasPressed = false
|
|
||||||
bWasPressed = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function ecg(speed: number) {
|
|
||||||
beepOn()
|
|
||||||
pins.digitalWritePin(DigitalPin.P1, 1)
|
|
||||||
basic.pause(50)
|
|
||||||
beepOff()
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . .
|
|
||||||
. . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . .
|
|
||||||
. . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . .
|
|
||||||
. . . . # . . . # # . . # # . . # # . . # # . . . # . . . . . . . . .
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
`, speed)
|
|
||||||
pins.digitalWritePin(DigitalPin.P1, 0)
|
|
||||||
basic.pause(speed * 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
function nose(): boolean {
|
|
||||||
if (wasNose) {
|
|
||||||
wasNose = false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* start period in microseconds
|
|
||||||
*/
|
|
||||||
function charging() {
|
|
||||||
let period = 2000
|
|
||||||
let dec = 500
|
|
||||||
pins.analogWritePin(AnalogPin.P2, 512)
|
|
||||||
pins.analogSetPeriod(AnalogPin.P2, period)
|
|
||||||
basic.showLeds(`
|
|
||||||
. # # . .
|
|
||||||
. . . # .
|
|
||||||
. . # . .
|
|
||||||
. . . # .
|
|
||||||
. # # . .
|
|
||||||
`)
|
|
||||||
basic.pause(500)
|
|
||||||
pins.analogSetPeriod(AnalogPin.P2, period - dec)
|
|
||||||
basic.showLeds(`
|
|
||||||
. # # . .
|
|
||||||
. . . # .
|
|
||||||
. . # . .
|
|
||||||
. # . . .
|
|
||||||
. # # # .
|
|
||||||
`)
|
|
||||||
basic.pause(500)
|
|
||||||
pins.analogSetPeriod(AnalogPin.P2, period - dec * 2)
|
|
||||||
basic.showLeds(`
|
|
||||||
. . # . .
|
|
||||||
. # # . .
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. # # # .
|
|
||||||
`)
|
|
||||||
basic.pause(500)
|
|
||||||
beepOff()
|
|
||||||
}
|
|
@ -1,178 +0,0 @@
|
|||||||
let wasShake: boolean
|
|
||||||
|
|
||||||
input.onShake(() => {
|
|
||||||
wasShake = true
|
|
||||||
})
|
|
||||||
wait_6Hours()
|
|
||||||
timeForTest()
|
|
||||||
alertnessTest()
|
|
||||||
wait_2Hours()
|
|
||||||
timeForTest()
|
|
||||||
alertnessTest()
|
|
||||||
wait_2Hours()
|
|
||||||
timeForTest()
|
|
||||||
alertnessTest()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* animate back to work
|
|
||||||
* animate take a rest
|
|
||||||
*/
|
|
||||||
function animations() { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wait 6 hours
|
|
||||||
* because this is a test program, we only wait for a short time
|
|
||||||
*/
|
|
||||||
function wait_6Hours() {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . # . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . # . . . .
|
|
||||||
. . # . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . .
|
|
||||||
. . # . . . . # . . . . # # # . . # . . . . # . . . . # . . # # # . . . . # . .
|
|
||||||
. . . . . . . . . . . . . . . . . . # . . . # . . . # . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . # . . # . . # . . . . . . . . . . . . . .
|
|
||||||
`, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wait for 2 hours
|
|
||||||
* because this is test code, we only wait a few seconds
|
|
||||||
*/
|
|
||||||
function wait_2Hours() {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . # . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . # . . . .
|
|
||||||
. . # . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . .
|
|
||||||
. . # . . . . # . . . . # # # . . # . . . . # . . . . # . . # # # . . . . # . .
|
|
||||||
. . . . . . . . . . . . . . . . . . # . . . # . . . # . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . # . . # . . # . . . . . . . . . . . . . .
|
|
||||||
`, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
function alertnessTest() {
|
|
||||||
let goodResponse = 1000
|
|
||||||
let threshold = 5
|
|
||||||
let score = 0
|
|
||||||
// Start test on button press
|
|
||||||
let x = 0
|
|
||||||
let start = images.createImage(`
|
|
||||||
. . # . . . . # . .
|
|
||||||
. . # . . . # . # .
|
|
||||||
. . # . . . . . # .
|
|
||||||
. . . . . . . # . .
|
|
||||||
. . # . . . . # . .
|
|
||||||
`)
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
start.showImage(x)
|
|
||||||
x = x + 5
|
|
||||||
if (x >= start.width()) {
|
|
||||||
x = 0
|
|
||||||
}
|
|
||||||
basic.pause(300)
|
|
||||||
}
|
|
||||||
// Wait for button(s) to be released
|
|
||||||
while (input.buttonIsPressed(Button.A) || input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
// Run 10 random cognition response tests
|
|
||||||
for (let i = 0; i < 9; i++) {
|
|
||||||
// Choose random delay and random outcome
|
|
||||||
let delay = Math.random(5) + 5
|
|
||||||
let outcome = Math.random(2)
|
|
||||||
// Draw moving dots on screen until delay expires
|
|
||||||
basic.clearScreen()
|
|
||||||
for (let j = 0; j < delay; j++) {
|
|
||||||
led.plot(j % 5, 2)
|
|
||||||
basic.pause(200)
|
|
||||||
basic.clearScreen()
|
|
||||||
}
|
|
||||||
// Show shake or button icon
|
|
||||||
if (outcome == 0) {
|
|
||||||
// Press the button!
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. # # # .
|
|
||||||
. # # # .
|
|
||||||
. # # # .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
} else {
|
|
||||||
// Shake the bit!
|
|
||||||
basic.showLeds(`
|
|
||||||
# . # . .
|
|
||||||
# . . # .
|
|
||||||
# # # # #
|
|
||||||
# . . # .
|
|
||||||
# . # . .
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
// Wait up to 3 seconds for button, shake, or timeout
|
|
||||||
wasShake = false
|
|
||||||
let timer = input.runningTime()
|
|
||||||
let timeout = 3000
|
|
||||||
while (input.runningTime() < timer + timeout) {
|
|
||||||
if (wasShake) {
|
|
||||||
break
|
|
||||||
} else if (input.buttonIsPressed(Button.B)) {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Assess the response and the response time
|
|
||||||
let response = input.runningTime() - timer
|
|
||||||
if (outcome == 0 && input.buttonIsPressed(Button.B) && response <= goodResponse) {
|
|
||||||
score = score + 1
|
|
||||||
} else if (outcome == 1 && wasShake && response <= goodResponse) {
|
|
||||||
score = score + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Show final score flashing 5 times (0..9)
|
|
||||||
for (let k = 0; k < 5; k++) {
|
|
||||||
basic.showNumber(score, 0)
|
|
||||||
basic.pause(250)
|
|
||||||
basic.clearScreen()
|
|
||||||
basic.pause(250)
|
|
||||||
}
|
|
||||||
basic.showNumber(score, 0)
|
|
||||||
basic.pause(500)
|
|
||||||
if (score < threshold) {
|
|
||||||
// Time for a break, show coffee cup animation
|
|
||||||
for (let l = 0; l < 3; l++) {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . # . . . . # . . . . . . . . . . # . . . . # . . . . . . .
|
|
||||||
. . . . . . # . . . . # . . . . . . . . . . # . . . . # . . . . . . . . . . . .
|
|
||||||
# . . # . # # . # . # . . # . # . . # . # . # # . # . . # . # . . # . # . . # .
|
|
||||||
# . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # #
|
|
||||||
# # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # .
|
|
||||||
`, 400)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// All ok, back to work, show digging animation
|
|
||||||
for (let m = 0; m < 3; m++) {
|
|
||||||
basic.showAnimation(`
|
|
||||||
# . # . . # . . . . # . . . .
|
|
||||||
. # # . . . # . # . . # . . .
|
|
||||||
# # # . . . . # # . . . # . #
|
|
||||||
. . . . . . # # # . . . . # #
|
|
||||||
. . . . . . . . . . . . # # #
|
|
||||||
`, 400)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Wait for any button press to finish test
|
|
||||||
while (!input.buttonIsPressed(Button.A) && !input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* alert the user it is time to take the test
|
|
||||||
* in a real system, this might give them 5 1 minute warnings
|
|
||||||
*/
|
|
||||||
function timeForTest() {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. # # # . . # . . . . # # . . . # # . . . . # . .
|
|
||||||
. # . . . . # . . . . . . # . . . . # . . # # . .
|
|
||||||
. . # . . . # # # . . # # . . . . # . . . . # . .
|
|
||||||
. . . # . . . # . . . . . # . . # . . . . . # . .
|
|
||||||
. # # . . . . # . . . # # . . . # # # . . # # # .
|
|
||||||
`, 700)
|
|
||||||
}
|
|
@ -1,157 +0,0 @@
|
|||||||
let maxGameTime: number
|
|
||||||
let wasShake: boolean
|
|
||||||
|
|
||||||
maxGameTime = 60000
|
|
||||||
input.onShake(() => {
|
|
||||||
wasShake = true
|
|
||||||
})
|
|
||||||
while (true) {
|
|
||||||
splashScreen()
|
|
||||||
if (input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.showAnimation(`
|
|
||||||
# # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # . . # # # # #
|
|
||||||
# # # . . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # . . # . . . . # . . . . # . . . . # . . . . # # # # # # # # # #
|
|
||||||
# # # . . # # # . . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # . . # # # . . # # # . . # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # # . . # # # . # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
`, 400)
|
|
||||||
let score = playOneGame()
|
|
||||||
flashDigit(score, 5)
|
|
||||||
waitButtonB()
|
|
||||||
basic.showAnimation(`
|
|
||||||
# # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
# # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . # . # . . . . . . . # . # . . . . . .
|
|
||||||
# # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
# # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
`, 400)
|
|
||||||
} else if (input.buttonIsPressed(Button.A)) {
|
|
||||||
calibrate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function playOneGame(): number {
|
|
||||||
let countDots = 0
|
|
||||||
let x = 2
|
|
||||||
let y = 2
|
|
||||||
let xdir = true
|
|
||||||
let canvas = images.createImage(`
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
wasShake = false
|
|
||||||
let bearing = input.compassHeading()
|
|
||||||
let startTime = input.runningTime()
|
|
||||||
while (countDots < 25 && input.runningTime() - startTime < maxGameTime) {
|
|
||||||
if (wasShake) {
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . # # # . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . # # # . . . # . . . # # # . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . # # # . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . .
|
|
||||||
. # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . . . . . .
|
|
||||||
`, 50)
|
|
||||||
let pos = Math.random(5)
|
|
||||||
if (xdir) {
|
|
||||||
if (!canvas.pixel(pos, y)) {
|
|
||||||
canvas.setPixel(pos, y, true)
|
|
||||||
countDots = countDots + 1
|
|
||||||
}
|
|
||||||
} else if (!canvas.pixel(x, pos)) {
|
|
||||||
canvas.setPixel(x, pos, true)
|
|
||||||
countDots = countDots + 1
|
|
||||||
}
|
|
||||||
wasShake = false
|
|
||||||
canvas.showImage(0)
|
|
||||||
} else if (Math.abs(input.compassHeading() - bearing) > 60) {
|
|
||||||
xdir = !xdir
|
|
||||||
bearing = input.compassHeading()
|
|
||||||
if (xdir) {
|
|
||||||
x = Math.random(5)
|
|
||||||
} else {
|
|
||||||
y = Math.random(5)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dotsToScore(countDots)
|
|
||||||
}
|
|
||||||
|
|
||||||
function splashScreen() {
|
|
||||||
let img = images.createImage(`
|
|
||||||
# # # # . # # # # . # # # # . # # # # . # # # # . # # # # . . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . # # . . # # # . # # # # . # # # # . . # # # . . . # # . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . # # # # . # # # # . # # # # . # # # # . # # # # .
|
|
||||||
# . . . # # . . . # # . . . # # . . . # # . . . # . # # # . . . # . . . # # # . . . . . . . . . . . . . . . . . . . . . # . . . . . # . . . . . # . . . . . # . . . . . # . . . # # . . # . # . # . . # # . . . # # . . . # # . . . # # . . . # . # . . # . . # . # . . . # # . . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . . . . . . . . . . . . . # # # . . . # . . . # # # . # . . . # # . . . # # . . . # # . . . #
|
|
||||||
# # # # . # # # # . # # # # . # # # # . . # # # . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # . # # # # # # # # # . # # # . . # # . . . # . . . . . . . . . . . . . . . . . . . . # # # . . . # . . . . # . . . . # . . . # # # . # # # # . # # # # . # # # # .
|
|
||||||
# . . . . # . . . . # . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . # . . . . . # . . . . . # . . . . . # . . . . . # . . . # . . . # # . . # . # . # . . # . # . . # . # . . # . # . . # . . # . # . . . # # . . . . # . . . . . # . . . # . . . # . . . # . . . # . . . . . . . . . . . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . # . . . . # . . . .
|
|
||||||
# . . . . # . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # . . . . # . . . . # # . . . # # . . . # . . . . # . . . . # . . . . # . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . # # # . # . . . .
|
|
||||||
`)
|
|
||||||
let x = 0
|
|
||||||
while (!input.buttonIsPressed(Button.A) && !input.buttonIsPressed(Button.B)) {
|
|
||||||
img.showImage(x)
|
|
||||||
basic.pause(200)
|
|
||||||
x = x + 5
|
|
||||||
if (x >= img.width()) {
|
|
||||||
x = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rotate canvas
|
|
||||||
*/
|
|
||||||
function rotateImage() { }
|
|
||||||
|
|
||||||
function flashDigit(digit: number, times: number) {
|
|
||||||
for (let i = 0; i < times; i++) {
|
|
||||||
basic.showNumber(digit, 0)
|
|
||||||
basic.pause(500)
|
|
||||||
basic.clearScreen()
|
|
||||||
basic.pause(500)
|
|
||||||
}
|
|
||||||
basic.showNumber(digit, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitButtonB() {
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function dotsToScore(dots: number): number {
|
|
||||||
if (dots == 25) {
|
|
||||||
return 9
|
|
||||||
} else if (dots >= 22) {
|
|
||||||
return 8
|
|
||||||
} else if (dots >= 19) {
|
|
||||||
return 7
|
|
||||||
} else if (dots >= 16) {
|
|
||||||
return 6
|
|
||||||
} else if (dots >= 13) {
|
|
||||||
return 5
|
|
||||||
} else if (dots >= 10) {
|
|
||||||
return 4
|
|
||||||
} else if (dots >= 7) {
|
|
||||||
return 3
|
|
||||||
} else if (dots >= 4) {
|
|
||||||
return 2
|
|
||||||
} else if (dots >= 1) {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function calibrate() {
|
|
||||||
basic.showString("CAL", 150)
|
|
||||||
if (input.compassHeading() == -4) {
|
|
||||||
input.calibrate()
|
|
||||||
}
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
let h = input.compassHeading()
|
|
||||||
basic.showNumber(h, 150)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,267 +0,0 @@
|
|||||||
let state: string
|
|
||||||
let timer: number
|
|
||||||
let gesturesRunning: boolean
|
|
||||||
let wasShake: boolean
|
|
||||||
let wasLogoUp: boolean
|
|
||||||
let wasLogoDown: boolean
|
|
||||||
let wasScreenUp: boolean
|
|
||||||
let wasScreenDown: boolean
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
splashScreen()
|
|
||||||
if (input.buttonIsPressed(Button.B)) {
|
|
||||||
// animate: add pancake
|
|
||||||
basic.showAnimation(`
|
|
||||||
# # # # # # . . . # . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . # # # . . # # # . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . # . . . # # . . . # . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . # # # . . # # # .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . # . . . #
|
|
||||||
`, 250)
|
|
||||||
runGameOnce()
|
|
||||||
// animate: pancake done
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . # # # # # . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . # . . . # # # # # # # . . . # . . . . . . . . . . . # . # . . . . . . . # . # . . . . . .
|
|
||||||
. . . . . . . . . . . # # # . # # # # # . # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
# . . . # # # # # # # . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
`, 250)
|
|
||||||
} else if (input.buttonIsPressed(Button.A)) {
|
|
||||||
testShake()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs one complete game from start to end
|
|
||||||
*/
|
|
||||||
function runGameOnce() {
|
|
||||||
let score = 0
|
|
||||||
let cooks = 0
|
|
||||||
let target_time = 0
|
|
||||||
// make sure no gestures are outstanding from last game
|
|
||||||
wasShake = false
|
|
||||||
wasLogoUp = false
|
|
||||||
wasLogoDown = false
|
|
||||||
wasScreenUp = false
|
|
||||||
wasScreenDown = false
|
|
||||||
state = "NEWSIDE"
|
|
||||||
while (true) {
|
|
||||||
// Handle any gestures that can happen at any time
|
|
||||||
let gesture = getGesture()
|
|
||||||
if (gesture == "FLOOR") {
|
|
||||||
state = "DROPPED"
|
|
||||||
}
|
|
||||||
// Run code appropriate to the present state of the game
|
|
||||||
if (state == "NEWSIDE") {
|
|
||||||
target_time = 5 + Math.random(5)
|
|
||||||
state = "COOKING"
|
|
||||||
startTimer()
|
|
||||||
} else if (state == "COOKING") {
|
|
||||||
// animate: cooking
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . # . . . . . . . . . . . . . #
|
|
||||||
# # # # # . # # # # # # # # # # # # # .
|
|
||||||
`, 100)
|
|
||||||
|
|
||||||
if (gesture == "FLIP") {
|
|
||||||
state = "FLIPPING"
|
|
||||||
} else if (getTimerSec() >= target_time) {
|
|
||||||
state = "READY"
|
|
||||||
score = score + 1
|
|
||||||
startTimer()
|
|
||||||
}
|
|
||||||
} else if (state == "READY") {
|
|
||||||
// animate: ready
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
# . . . #
|
|
||||||
. # # # .
|
|
||||||
`, 100)
|
|
||||||
if (getTimerSec() > 2) {
|
|
||||||
state = "BURNING"
|
|
||||||
score = score - 1
|
|
||||||
startTimer()
|
|
||||||
} else if (gesture == "FLIP") {
|
|
||||||
state = "FLIPPING"
|
|
||||||
}
|
|
||||||
} else if (state == "BURNING") {
|
|
||||||
// animate: burning
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . # . . . . # .
|
|
||||||
. . . . . . . . # . . # . # . . # . . .
|
|
||||||
. . . . . . # . # . . # . . . . . . . .
|
|
||||||
. . . . . . # . . . . . . . . . . . . .
|
|
||||||
# # # # # # # # # # # # # # # # # # # #
|
|
||||||
`, 100)
|
|
||||||
if (gesture == "SKY") {
|
|
||||||
state = "NEWSIDE"
|
|
||||||
} else if (getTimerSec() > 2) {
|
|
||||||
state = "BURNT"
|
|
||||||
}
|
|
||||||
} else if (state == "FLIPPING") {
|
|
||||||
// animate: flipping
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . # . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . # # # # # . # # . . . # # # . . . # # . # # # # # . . . . . . . . . .
|
|
||||||
. . . . . . . . . . # # # # # . . . . . . . . # # . # # # . # # . . . . . . . . # # # # # . . . . .
|
|
||||||
. . . . . # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # # #
|
|
||||||
# # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
`, 100)
|
|
||||||
// Prevent a spurious double-flip from happening
|
|
||||||
wasShake = false
|
|
||||||
cooks = cooks + 1
|
|
||||||
if (cooks == 5) {
|
|
||||||
state = "GAMEOVER"
|
|
||||||
} else {
|
|
||||||
state = "NEWSIDE"
|
|
||||||
}
|
|
||||||
} else if (state == "DROPPED") {
|
|
||||||
// animate: dropped
|
|
||||||
basic.showAnimation(`
|
|
||||||
# . . . # . . . . . # . . . # . . . . .
|
|
||||||
. # . # . . . . . . . # . # . . . . . .
|
|
||||||
. . # . . . . . . . . . # . . . . . . .
|
|
||||||
. # . # . . . . . . . # . # . . . . . .
|
|
||||||
# . . . # . . . . . # . . . # . . . . .
|
|
||||||
`, 250)
|
|
||||||
score = 0
|
|
||||||
state = "GAMEOVER"
|
|
||||||
} else if (state == "BURNT") {
|
|
||||||
// animate: burnt
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . # . # . . . . . . . # # # .
|
|
||||||
. . . . . . . . . . . . . . . . . # . . . . . . . . # . # . . . . . . . # # # . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . # . # . . . . . . . # # # . . . . . . . . . . .
|
|
||||||
. . . . . . # . # . . # # # . . # . # . . . . . . . # # # . . . . . . . . . . . . . . . .
|
|
||||||
# # # # # . # # # . . # # # . . # # # . . # # # . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
`, 250)
|
|
||||||
score = 0
|
|
||||||
state = "GAMEOVER"
|
|
||||||
} else if (state == "GAMEOVER") {
|
|
||||||
animateScore(score)
|
|
||||||
state = "WAITEJECT"
|
|
||||||
} else if (state == "WAITEJECT") {
|
|
||||||
if (gesture == "UPSIDEDOWN") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* show score (0..9) flashing
|
|
||||||
* @param score TODO
|
|
||||||
*/
|
|
||||||
function animateScore(score: number) {
|
|
||||||
score = Math.clamp(0, 9, score)
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
basic.showNumber(score, 0)
|
|
||||||
basic.pause(500)
|
|
||||||
basic.clearScreen()
|
|
||||||
basic.pause(500)
|
|
||||||
}
|
|
||||||
basic.showNumber(score, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: Eventually this will move into a gesture library
|
|
||||||
* It hides all the nasty detail of detecting gestures
|
|
||||||
*/
|
|
||||||
function getGesture(): string {
|
|
||||||
if (!gesturesRunning) {
|
|
||||||
input.onShake(() => {
|
|
||||||
wasShake = true
|
|
||||||
})
|
|
||||||
input.onLogoUp(() => {
|
|
||||||
wasLogoUp = true
|
|
||||||
})
|
|
||||||
input.onLogoDown(() => {
|
|
||||||
wasLogoDown = true
|
|
||||||
})
|
|
||||||
input.onScreenUp(() => {
|
|
||||||
wasScreenUp = true
|
|
||||||
})
|
|
||||||
input.onScreenDown(() => {
|
|
||||||
wasScreenDown = true
|
|
||||||
})
|
|
||||||
gesturesRunning = true
|
|
||||||
}
|
|
||||||
// work out which of a possible set of gestures has occurred:
|
|
||||||
// Button gestures and movement gestures both handled
|
|
||||||
// This is so that it is easy to also use this on the simulator too
|
|
||||||
// Generally, B is used for normal OK, A is used for abnormal RECOVERY
|
|
||||||
// (flip is a normal action, touch sky to turn off smoke alarm is recovery)
|
|
||||||
let a = input.buttonIsPressed(Button.A)
|
|
||||||
let b = input.buttonIsPressed(Button.B)
|
|
||||||
if (state == "COOKING" || state == "READY") {
|
|
||||||
if (b || wasShake) {
|
|
||||||
wasShake = false
|
|
||||||
return "FLIP"
|
|
||||||
}
|
|
||||||
} else if (state == "FLIPPING") {
|
|
||||||
if (a || wasLogoDown) {
|
|
||||||
wasLogoDown = false
|
|
||||||
return "FLOOR"
|
|
||||||
}
|
|
||||||
} else if (state == "BURNING") {
|
|
||||||
if (a || wasLogoUp) {
|
|
||||||
wasLogoUp = false
|
|
||||||
return "SKY"
|
|
||||||
}
|
|
||||||
} else if (state == "GAMEOVER" || state == "WAITEJECT") {
|
|
||||||
if (b || wasScreenDown) {
|
|
||||||
wasScreenDown = false
|
|
||||||
return "UPSIDEDOWN"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "NONE"
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* start timer by sampling runningtime and storing into starttime
|
|
||||||
*/
|
|
||||||
function startTimer() {
|
|
||||||
timer = input.runningTime()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the elapsed time from the global starttime with ref to running time
|
|
||||||
* in seconds.
|
|
||||||
*/
|
|
||||||
function getTimerSec(): number {
|
|
||||||
let t = (input.runningTime() - timer) / 1000
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show a splash screen "Perfect Pancakes >>>"
|
|
||||||
* Splash screen "PP" with little arrow pointing to the start button
|
|
||||||
*/
|
|
||||||
function splashScreen() {
|
|
||||||
let splash = images.createImage(`
|
|
||||||
# # # # . . . . . . # # # # . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
# . . . # . . . . . # . . . # # . . . . . # . . . . . # . . . . . # .
|
|
||||||
# # # # . . . . . . # # # # . . # . . . . . # . . . . . # . . . . . #
|
|
||||||
# . . . . . . . . . # . . . . # . . . . . # . . . . . # . . . . . # .
|
|
||||||
# . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
`)
|
|
||||||
// use show image (not show animation) so that button press is more responsive
|
|
||||||
let index = 0
|
|
||||||
// Any button press finishes the splash screen
|
|
||||||
while (!input.buttonIsPressed(Button.B) && !input.buttonIsPressed(Button.A)) {
|
|
||||||
splash.showImage(index * 5)
|
|
||||||
index = index + 1
|
|
||||||
if (index > splash.width() / 5) {
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
basic.pause(250)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testShake() { }
|
|
@ -1,242 +0,0 @@
|
|||||||
let sugarThreshold: number
|
|
||||||
let ketoneThreshold: number
|
|
||||||
|
|
||||||
// Important parameters
|
|
||||||
sugarThreshold = 14
|
|
||||||
ketoneThreshold = 6
|
|
||||||
while (true) {
|
|
||||||
// splash screen sugar cube (just the right sugar)
|
|
||||||
basic.showAnimation(`
|
|
||||||
# # # . . . . . . . . . . . . . . . . .
|
|
||||||
# # # . . . # # # . . . . . . . . . . .
|
|
||||||
# # # . . . # # # . . . # # # . . # # #
|
|
||||||
. . . . . . # # # . . . # # # . . # # #
|
|
||||||
. . . . . . . . . . . . # # # . . # # #
|
|
||||||
`, 400)
|
|
||||||
// ask questions and give advice
|
|
||||||
quiz()
|
|
||||||
// wait for button press before restart
|
|
||||||
waitAnyButton()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSugar(): string {
|
|
||||||
waitNoButtons()
|
|
||||||
let selection = "MID"
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
// high, low, normal?
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . # . # . . . . # . .
|
|
||||||
. # # # . # . # . . . # . # .
|
|
||||||
. # # # . # . # # # . . . # .
|
|
||||||
. # # # . # . . # . . . # . .
|
|
||||||
. . . . . # . . # . . . # . .
|
|
||||||
`, 400)
|
|
||||||
// show low, mid, or high as a bar
|
|
||||||
selection = getLowMidHigh(selection)
|
|
||||||
}
|
|
||||||
return selection
|
|
||||||
}
|
|
||||||
|
|
||||||
function getKetone(): string {
|
|
||||||
waitNoButtons()
|
|
||||||
let selection = "MID"
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
// high, low, normal?
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . # . . . # . .
|
|
||||||
# # . . . . . # . . . # . # .
|
|
||||||
# # # # # . . # # . . . . # .
|
|
||||||
# # . . # . . # . # . . # . .
|
|
||||||
. . . . . # . . # . . . # . .
|
|
||||||
`, 400)
|
|
||||||
// show low, mid, or high as a bar
|
|
||||||
selection = getLowMidHigh(selection)
|
|
||||||
}
|
|
||||||
return selection
|
|
||||||
}
|
|
||||||
|
|
||||||
function getIll(): boolean {
|
|
||||||
waitNoButtons()
|
|
||||||
let selection = false
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
// ask question 'happy or sad'
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . # . . . . # . .
|
|
||||||
. # . # . . # . # . . # . # . . # . # .
|
|
||||||
. . . . . . . . . . . . . # . . . . # .
|
|
||||||
# . . . # . # # # . . . # . . . . # . .
|
|
||||||
. # # # . # . . . # . . # . . . . # . .
|
|
||||||
`, 400)
|
|
||||||
// get answer from user
|
|
||||||
selection = getHappySad(selection)
|
|
||||||
}
|
|
||||||
// if we are happy, we are not ill
|
|
||||||
return !selection
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLowMidHigh(selection: string): string {
|
|
||||||
let timeout = 2000
|
|
||||||
let timer = input.runningTime()
|
|
||||||
while (true) {
|
|
||||||
// show the present level as a line
|
|
||||||
if (selection == "LOW") {
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
# # # # #
|
|
||||||
`)
|
|
||||||
} else if (selection == "HIGH") {
|
|
||||||
basic.showLeds(`
|
|
||||||
# # # # #
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
} else {
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
# # # # #
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
// process any user input
|
|
||||||
if (input.buttonIsPressed(Button.A)) {
|
|
||||||
// cycle round the 3 possible levels
|
|
||||||
if (selection == "LOW") {
|
|
||||||
selection = "MID"
|
|
||||||
} else if (selection == "MID") {
|
|
||||||
selection = "HIGH"
|
|
||||||
} else {
|
|
||||||
selection = "LOW"
|
|
||||||
}
|
|
||||||
// This is the 'hold repeat' time if you hold the A button
|
|
||||||
basic.pause(300)
|
|
||||||
// restart timer, 2 seconds of inactivity before return to main
|
|
||||||
timer = input.runningTime()
|
|
||||||
} else if (input.buttonIsPressed(Button.B)) {
|
|
||||||
// user is selecting so better return quickly
|
|
||||||
return selection
|
|
||||||
} else if (input.runningTime() > timer + timeout) {
|
|
||||||
// timeout, so return to main to re-prompt user
|
|
||||||
return selection
|
|
||||||
} else {
|
|
||||||
// This slows the loop down to stop the emulator being busy
|
|
||||||
// and also preserves battery life on the micro:bit
|
|
||||||
// it also affects the worst case response time
|
|
||||||
// it also affects the response time
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for all buttons to be released
|
|
||||||
* This prevents spurious selection in next question
|
|
||||||
*/
|
|
||||||
function waitNoButtons() {
|
|
||||||
while (input.buttonIsPressed(Button.A) || input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHappySad(selection: boolean): boolean {
|
|
||||||
let timeout = 2000
|
|
||||||
let timer = input.runningTime()
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
// Show present selection
|
|
||||||
if (selection) {
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. # . # .
|
|
||||||
. . . . .
|
|
||||||
# . . . #
|
|
||||||
. # # # .
|
|
||||||
`)
|
|
||||||
} else {
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. # . # .
|
|
||||||
. . . . .
|
|
||||||
. # # # .
|
|
||||||
# . . . #
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
// Wait for any change in the selection
|
|
||||||
if (input.buttonIsPressed(Button.A)) {
|
|
||||||
selection = !selection
|
|
||||||
// This is the repeat time if button A held down
|
|
||||||
basic.pause(500)
|
|
||||||
timer = input.runningTime()
|
|
||||||
} else if (input.runningTime() > timer + timeout) {
|
|
||||||
return selection
|
|
||||||
} else {
|
|
||||||
// Preserve battery life on micro:bit and prevent emulator being busy
|
|
||||||
// This is also the response time to a button press
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return selection
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Button A changes value, Button B selects value
|
|
||||||
*/
|
|
||||||
function quiz() {
|
|
||||||
let sugar = getSugar()
|
|
||||||
if (sugar != "HIGH") {
|
|
||||||
// All is ok (tick)
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . .
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . #
|
|
||||||
. . . . . . . . . . . . . . . . . . # . . . . # .
|
|
||||||
# . . . . # . . . . # . # . . # . # . . # . # . .
|
|
||||||
. . . . . . # . . . . # . . . . # . . . . # . . .
|
|
||||||
`, 400)
|
|
||||||
} else {
|
|
||||||
// Button A changes value, Button B selects value
|
|
||||||
let ketone = getKetone()
|
|
||||||
if (ketone != "HIGH") {
|
|
||||||
// Button A changes value, Button B selects value
|
|
||||||
let ill = getIll()
|
|
||||||
if (!ill) {
|
|
||||||
// Time to rest (jump into bed)
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . # # . . . . # . . . . # . . . . . . # . . . . . .
|
|
||||||
. . . . # . . . . # # # . . # . # . . # . . # . # . . . . #
|
|
||||||
. . . . # . . . . # . . . . # # # . . # # # . . # # # # # #
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
# . . . # # . . . # # . . . # # . . . # # . . . # # . . . #
|
|
||||||
`, 400)
|
|
||||||
} else {
|
|
||||||
// Test more often (clock shows 2 hour interval)
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . # . . . . . . . . . . . . . . . . . . # # . . . . . . . . # # . . . . . . . . # # . .
|
|
||||||
. . # . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . # . . . . . . . . . # .
|
|
||||||
. . # . . . . # # # . . # . . # # # . . . . # . . . . . . . . . # . . . . . . . . . # . .
|
|
||||||
. . . . . . . . . . . . # . . . . . . . . # . . . . . . . . . # . . . . . . . . . # . . .
|
|
||||||
. . . . . . . . . . . . # . . . . . . . . # # # . . . . . . . # # # . . . . . . . # # # .
|
|
||||||
`, 400)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Get some help (call the diabetes care team on the phone)
|
|
||||||
basic.showAnimation(`
|
|
||||||
. . . . . . . . . . # # # # # # # . . . # # . . . # # . . . # # . . . # # # . . # # . # . # # . . #
|
|
||||||
. . . . . # # # # # # . . . # # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . .
|
|
||||||
# # # # # # . . . # . . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . .
|
|
||||||
# . # . # . . # . . . . # . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . . # . . . .
|
|
||||||
. # # # . . # # # . . # # # . # # . . . # # . . # # # . # . # # # . . # # . . . # # . . . # # . . .
|
|
||||||
`, 400)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitAnyButton() {
|
|
||||||
while (!input.buttonIsPressed(Button.A) && !input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,488 +0,0 @@
|
|||||||
let AWasPressed: boolean
|
|
||||||
let BWasPressed: boolean
|
|
||||||
let wasShake: boolean
|
|
||||||
let dots025: Image
|
|
||||||
|
|
||||||
dots025 = images.createImage(`
|
|
||||||
. . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # #
|
|
||||||
`)
|
|
||||||
let tests = "DABPXYZSCT"
|
|
||||||
let test = 0
|
|
||||||
let prevTest = -1
|
|
||||||
startIOMonitor()
|
|
||||||
while (true) {
|
|
||||||
let testLetter = tests[test]
|
|
||||||
let autoRun = false
|
|
||||||
if (testLetter == "D" || testLetter == "A" || testLetter == "B") {
|
|
||||||
autoRun = true
|
|
||||||
}
|
|
||||||
if (!(test == prevTest)) {
|
|
||||||
basic.showString(tests[test], 200)
|
|
||||||
prevTest = test
|
|
||||||
}
|
|
||||||
if (AWasPressed || autoRun) {
|
|
||||||
AWasPressed = false
|
|
||||||
if (testLetter == "D") {
|
|
||||||
testDisplay()
|
|
||||||
test = test + 1
|
|
||||||
} else if (testLetter == "A") {
|
|
||||||
testButtonA()
|
|
||||||
test = test + 1
|
|
||||||
} else if (testLetter == "B") {
|
|
||||||
testButtonB()
|
|
||||||
test = test + 1
|
|
||||||
} else if (testLetter == "P") {
|
|
||||||
testPads()
|
|
||||||
} else if (testLetter == "X") {
|
|
||||||
testTiltX()
|
|
||||||
} else if (testLetter == "Y") {
|
|
||||||
testTiltY()
|
|
||||||
} else if (testLetter == "Z") {
|
|
||||||
testTiltZ()
|
|
||||||
} else if (testLetter == "S") {
|
|
||||||
testShake()
|
|
||||||
} else if (testLetter == "C") {
|
|
||||||
testCompass()
|
|
||||||
} else if (testLetter == "T") {
|
|
||||||
testTemperature()
|
|
||||||
} else {
|
|
||||||
// end of tests
|
|
||||||
basic.showLeds(`
|
|
||||||
. . . . .
|
|
||||||
. . . . #
|
|
||||||
. . . # .
|
|
||||||
# . # . .
|
|
||||||
. # . . .
|
|
||||||
`, 400)
|
|
||||||
}
|
|
||||||
prevTest = -1
|
|
||||||
AWasPressed = false
|
|
||||||
BWasPressed = false
|
|
||||||
} else if (BWasPressed) {
|
|
||||||
BWasPressed = false
|
|
||||||
if (test < tests.length - 1) {
|
|
||||||
test = test + 1
|
|
||||||
} else {
|
|
||||||
test = 3
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* flash all LEDs 5 times
|
|
||||||
*/
|
|
||||||
function testDisplay() {
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
basic.plotLeds(`
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
`)
|
|
||||||
basic.pause(200)
|
|
||||||
basic.clearScreen()
|
|
||||||
basic.pause(200)
|
|
||||||
}
|
|
||||||
// cycle all LEDs from 1 to 25
|
|
||||||
basic.showAnimation(`
|
|
||||||
# . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . # # . . . # # # . . # # # # . # # # # #
|
|
||||||
`, 400)
|
|
||||||
}
|
|
||||||
|
|
||||||
function testButtonA() {
|
|
||||||
basic.plotLeds(`
|
|
||||||
. . # . .
|
|
||||||
. # . # .
|
|
||||||
. # # # .
|
|
||||||
. # . # .
|
|
||||||
. # . # .
|
|
||||||
`)
|
|
||||||
// wait for A pressed
|
|
||||||
while (!input.buttonIsPressed(Button.A)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
basic.plotLeds(`
|
|
||||||
. # . . .
|
|
||||||
# . # . .
|
|
||||||
# # # . .
|
|
||||||
# . # . .
|
|
||||||
# . # . .
|
|
||||||
`)
|
|
||||||
// wait for A released
|
|
||||||
while (input.buttonIsPressed(Button.A)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
basic.plotLeds(`
|
|
||||||
. . # . .
|
|
||||||
. # . # .
|
|
||||||
. # # # .
|
|
||||||
. # . # .
|
|
||||||
. # . # .
|
|
||||||
`)
|
|
||||||
basic.pause(1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
function testTiltX() {
|
|
||||||
basic.clearScreen()
|
|
||||||
let prevx = 0
|
|
||||||
while (!AWasPressed && !BWasPressed) {
|
|
||||||
basic.pause(100)
|
|
||||||
let x = input.acceleration(Dimension.X)
|
|
||||||
let x2 = x / 512 + 2
|
|
||||||
let x3 = Math.clamp(0, 4, x2)
|
|
||||||
// sticky trace
|
|
||||||
led.plot(x3, 0)
|
|
||||||
// middle line is actual/live
|
|
||||||
if (x3 != prevx) {
|
|
||||||
led.unplot(prevx, 2)
|
|
||||||
prevx = x3
|
|
||||||
}
|
|
||||||
led.plot(x3, 2)
|
|
||||||
// bottom line is -4G, -2G, 1G, +2G, +4G
|
|
||||||
if (x <= -2048) {
|
|
||||||
led.plot(0, 4)
|
|
||||||
} else if (x <= -1024) {
|
|
||||||
led.plot(1, 4)
|
|
||||||
} else if (x <= 1024) {
|
|
||||||
led.plot(2, 4)
|
|
||||||
} else if (x <= 2048) {
|
|
||||||
led.plot(3, 4)
|
|
||||||
} else {
|
|
||||||
led.plot(4, 4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testShake() {
|
|
||||||
wasShake = false
|
|
||||||
basic.plotLeds(`
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . # . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
while (!AWasPressed && !BWasPressed) {
|
|
||||||
if (wasShake) {
|
|
||||||
wasShake = false
|
|
||||||
basic.plotLeds(`
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
# # # # #
|
|
||||||
`)
|
|
||||||
basic.pause(500)
|
|
||||||
basic.plotLeds(`
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . # . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
} else {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testCompass() {
|
|
||||||
if (input.compassHeading() < 0) {
|
|
||||||
input.calibrate()
|
|
||||||
}
|
|
||||||
basic.clearScreen()
|
|
||||||
while (!AWasPressed && !BWasPressed) {
|
|
||||||
let d = input.compassHeading()
|
|
||||||
d = d / 22
|
|
||||||
d = Math.clamp(0, 15, d)
|
|
||||||
d = (d + 2) % 16
|
|
||||||
if (d < 4) {
|
|
||||||
led.plot(d, 0)
|
|
||||||
} else if (d < 8) {
|
|
||||||
led.plot(4, d - 4)
|
|
||||||
} else if (d < 12) {
|
|
||||||
led.plot(4 - d - 8, 4)
|
|
||||||
} else {
|
|
||||||
led.plot(0, 4 - d - 12)
|
|
||||||
}
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testPads() {
|
|
||||||
let TESTSPEED = 500
|
|
||||||
AWasPressed = false
|
|
||||||
BWasPressed = false
|
|
||||||
// Make sure all pins are inputs, before test starts
|
|
||||||
let p0 = pins.digitalReadPin(DigitalPin.P0)
|
|
||||||
let p1 = pins.digitalReadPin(DigitalPin.P1)
|
|
||||||
let p2 = pins.digitalReadPin(DigitalPin.P2)
|
|
||||||
let ok0 = 0
|
|
||||||
let ok1 = 0
|
|
||||||
let ok2 = 0
|
|
||||||
while (!AWasPressed && !BWasPressed) {
|
|
||||||
basic.clearScreen()
|
|
||||||
// ## P0 out low, read from P1 and P2
|
|
||||||
ok0 = 0
|
|
||||||
pins.digitalWritePin(DigitalPin.P0, 0)
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
p1 = pins.digitalReadPin(DigitalPin.P1)
|
|
||||||
p2 = pins.digitalReadPin(DigitalPin.P2)
|
|
||||||
if (p1 == 0) {
|
|
||||||
led.plot(0, 0)
|
|
||||||
ok0 = ok0 + 1
|
|
||||||
}
|
|
||||||
if (p2 == 0) {
|
|
||||||
led.plot(1, 0)
|
|
||||||
ok0 = ok0 + 1
|
|
||||||
}
|
|
||||||
// ## P0 out high, read from P1 and P2
|
|
||||||
pins.digitalWritePin(DigitalPin.P0, 1)
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
p1 = pins.digitalReadPin(DigitalPin.P1)
|
|
||||||
p2 = pins.digitalReadPin(DigitalPin.P2)
|
|
||||||
if (p1 == 1) {
|
|
||||||
led.plot(2, 0)
|
|
||||||
ok0 = ok0 + 1
|
|
||||||
}
|
|
||||||
if (p2 == 1) {
|
|
||||||
led.plot(3, 0)
|
|
||||||
ok0 = ok0 + 1
|
|
||||||
}
|
|
||||||
// set back to an input
|
|
||||||
p0 = pins.digitalReadPin(DigitalPin.P0)
|
|
||||||
// ## P1 out low, read from P0 and P2
|
|
||||||
ok1 = 0
|
|
||||||
pins.digitalWritePin(DigitalPin.P1, 0)
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
p0 = pins.digitalReadPin(DigitalPin.P0)
|
|
||||||
p2 = pins.digitalReadPin(DigitalPin.P2)
|
|
||||||
if (p0 == 0) {
|
|
||||||
led.plot(0, 1)
|
|
||||||
ok1 = ok1 + 1
|
|
||||||
}
|
|
||||||
if (p2 == 0) {
|
|
||||||
led.plot(1, 1)
|
|
||||||
ok1 = ok1 + 1
|
|
||||||
}
|
|
||||||
// ## P1 out high, read from P0 and P2
|
|
||||||
pins.digitalWritePin(DigitalPin.P1, 1)
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
p0 = pins.digitalReadPin(DigitalPin.P0)
|
|
||||||
p2 = pins.digitalReadPin(DigitalPin.P2)
|
|
||||||
if (p0 == 1) {
|
|
||||||
led.plot(2, 1)
|
|
||||||
ok1 = ok1 + 1
|
|
||||||
}
|
|
||||||
if (p2 == 1) {
|
|
||||||
led.plot(3, 1)
|
|
||||||
ok1 = ok1 + 1
|
|
||||||
}
|
|
||||||
// set back to an input
|
|
||||||
p0 = pins.digitalReadPin(DigitalPin.P1)
|
|
||||||
// ## P2 out low, read from P0 and P1
|
|
||||||
ok2 = 0
|
|
||||||
pins.digitalWritePin(DigitalPin.P2, 0)
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
p0 = pins.digitalReadPin(DigitalPin.P0)
|
|
||||||
p1 = pins.digitalReadPin(DigitalPin.P1)
|
|
||||||
if (p0 == 0) {
|
|
||||||
led.plot(0, 2)
|
|
||||||
ok2 = ok2 + 1
|
|
||||||
}
|
|
||||||
if (p1 == 0) {
|
|
||||||
led.plot(1, 2)
|
|
||||||
ok2 = ok2 + 1
|
|
||||||
}
|
|
||||||
// ## P2 out high, read from P0 and P1
|
|
||||||
pins.digitalWritePin(DigitalPin.P2, 1)
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
p0 = pins.digitalReadPin(DigitalPin.P0)
|
|
||||||
p1 = pins.digitalReadPin(DigitalPin.P1)
|
|
||||||
if (p0 == 1) {
|
|
||||||
led.plot(2, 2)
|
|
||||||
ok2 = ok2 + 1
|
|
||||||
}
|
|
||||||
if (p1 == 1) {
|
|
||||||
led.plot(3, 2)
|
|
||||||
ok2 = ok2 + 1
|
|
||||||
}
|
|
||||||
p2 = pins.digitalReadPin(DigitalPin.P2)
|
|
||||||
// ## Assess final test status
|
|
||||||
if (ok0 == 4) {
|
|
||||||
led.plot(4, 0)
|
|
||||||
}
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
if (ok1 == 4) {
|
|
||||||
led.plot(4, 1)
|
|
||||||
}
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
if (ok2 == 4) {
|
|
||||||
led.plot(4, 2)
|
|
||||||
}
|
|
||||||
basic.pause(TESTSPEED)
|
|
||||||
if (ok0 + ok1 + ok2 == 12) {
|
|
||||||
// all tests passed
|
|
||||||
led.plot(4, 4)
|
|
||||||
}
|
|
||||||
// ## Test cycle finished
|
|
||||||
basic.pause(1000)
|
|
||||||
}
|
|
||||||
// intentionally don't clear A and B flags, so main loop can process them.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* - show number of dots on screen (0..25) to represent temperature in celcius
|
|
||||||
*/
|
|
||||||
function testTemperature() {
|
|
||||||
while (!AWasPressed && !BWasPressed) {
|
|
||||||
let temp = input.temperature() - 10
|
|
||||||
temp = Math.clamp(0, 25, temp)
|
|
||||||
dots025.plotFrame(temp)
|
|
||||||
basic.pause(500)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testButtonB() {
|
|
||||||
basic.plotLeds(`
|
|
||||||
. # # . .
|
|
||||||
. # . # .
|
|
||||||
. # # . .
|
|
||||||
. # . # .
|
|
||||||
. # # . .
|
|
||||||
`)
|
|
||||||
// wait for B pressed
|
|
||||||
while (!input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
basic.plotLeds(`
|
|
||||||
. . # # .
|
|
||||||
. . # . #
|
|
||||||
. . # # .
|
|
||||||
. . # . #
|
|
||||||
. . # # .
|
|
||||||
`)
|
|
||||||
// wait for B released
|
|
||||||
while (input.buttonIsPressed(Button.B)) {
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
basic.plotLeds(`
|
|
||||||
. # # . .
|
|
||||||
. # . # .
|
|
||||||
. # # . .
|
|
||||||
. # . # .
|
|
||||||
. # # . .
|
|
||||||
`)
|
|
||||||
basic.pause(1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
function testTiltY() {
|
|
||||||
basic.clearScreen()
|
|
||||||
let prevy = 0
|
|
||||||
while (!AWasPressed && !BWasPressed) {
|
|
||||||
basic.pause(100)
|
|
||||||
let y = input.acceleration(Dimension.Y)
|
|
||||||
let y2 = y / 512 + 2
|
|
||||||
let y3 = Math.clamp(0, 4, y2)
|
|
||||||
// sticky trace
|
|
||||||
led.plot(0, y3)
|
|
||||||
// middle line is actual/live
|
|
||||||
if (y3 != prevy) {
|
|
||||||
led.unplot(2, prevy)
|
|
||||||
prevy = y3
|
|
||||||
}
|
|
||||||
led.plot(2, y3)
|
|
||||||
// bottom line is -4G, -2G, 1G, +2G, +4G
|
|
||||||
if (y <= -2048) {
|
|
||||||
led.plot(4, 0)
|
|
||||||
} else if (y <= -1024) {
|
|
||||||
led.plot(4, 1)
|
|
||||||
} else if (y <= 1024) {
|
|
||||||
led.plot(4, 2)
|
|
||||||
} else if (y <= 2048) {
|
|
||||||
led.plot(4, 3)
|
|
||||||
} else {
|
|
||||||
led.plot(4, 4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testTiltZ() {
|
|
||||||
basic.clearScreen()
|
|
||||||
while (!AWasPressed && !BWasPressed) {
|
|
||||||
let z = input.acceleration(Dimension.Z)
|
|
||||||
if (z < -2000) {
|
|
||||||
basic.plotLeds(`
|
|
||||||
# . . . #
|
|
||||||
# . . . #
|
|
||||||
# . . . #
|
|
||||||
# . . . #
|
|
||||||
# . . . #
|
|
||||||
`)
|
|
||||||
} else if (z <= -1030) {
|
|
||||||
basic.plotLeds(`
|
|
||||||
. # . # .
|
|
||||||
. # . # .
|
|
||||||
. # . # .
|
|
||||||
. # . # .
|
|
||||||
. # . # .
|
|
||||||
`)
|
|
||||||
} else if (z <= 1000) {
|
|
||||||
basic.plotLeds(`
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
. . # . .
|
|
||||||
`)
|
|
||||||
} else if (z <= 1030) {
|
|
||||||
basic.plotLeds(`
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
# # # # #
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
} else if (z <= 2000) {
|
|
||||||
basic.plotLeds(`
|
|
||||||
. . . . .
|
|
||||||
# # # # #
|
|
||||||
. . . . .
|
|
||||||
# # # # #
|
|
||||||
. . . . .
|
|
||||||
`)
|
|
||||||
} else {
|
|
||||||
basic.plotLeds(`
|
|
||||||
# # # # #
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
. . . . .
|
|
||||||
# # # # #
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
basic.pause(100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function startIOMonitor() {
|
|
||||||
input.onButtonPressed(Button.A, () => {
|
|
||||||
AWasPressed = true
|
|
||||||
})
|
|
||||||
input.onButtonPressed(Button.B, () => {
|
|
||||||
BWasPressed = true
|
|
||||||
})
|
|
||||||
input.onShake(() => {
|
|
||||||
wasShake = true
|
|
||||||
})
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user