updated infection
This commit is contained in:
parent
d6ead4fad4
commit
da9b180e17
@ -20,20 +20,33 @@ If any player survives the outbreak, the game is won. Otherwise try again!
|
|||||||
|
|
||||||
### How to play
|
### How to play
|
||||||
|
|
||||||
Press A+B to enter master mode (1 per game).
|
Press `A+B` to enter master mode (1 per game).
|
||||||
|
|
||||||
Wait for players to be paired. The number of paired player will display on screen.
|
Wait for players to be paired. The number of paired player will display on screen.
|
||||||
An icon will appear on player's screen.
|
A letter will appear on the player's screen, this letter is the player's identity.
|
||||||
|
|
||||||
Press A+B to start the infection game. The master will pick a random player as patient zero.
|
Once all your players are registered, press `A+B` to start the infection game.
|
||||||
|
The game will pick a random player as **patient zero**.
|
||||||
|
|
||||||
A player will transmit the disease if close enough (RSSI) and with a certain probability (TRANSMISSIONPROB).
|
A player will transmit the disease if close enough (`RSSI`) and with a certain probability (`TRANSMISSIONPROB`).
|
||||||
During the incudation phase (INCUBATION), the player does not show any sign of illness (happy face).
|
During the incudation phase (`INCUBATION`), the player does not show any sign of illness (happy face).
|
||||||
After that phase, the sad face shows up.
|
After that phase, the player gets sick and shows a sad face on the screen. After the sick face, the player dies and a skull shows up.
|
||||||
|
|
||||||
Player control:
|
Once the game is over, the @boardname@ will show the player id (A,B,C...), health and
|
||||||
* ``A`` button: show identity icon
|
who infected him. The master @boardname@ will show the identity of patient zero.
|
||||||
* ``B`` button: show current infection status
|
|
||||||
|
Icons used in the game:
|
||||||
|
|
||||||
|
* Pairing: IconNames.Ghost
|
||||||
|
* Paired: IconNames.Happy
|
||||||
|
* Dead: IconNames.Skull
|
||||||
|
* Sick: IconNames.Sad
|
||||||
|
* Incubating: IconNames.Confused
|
||||||
|
* Healthy: IconNames.Happy
|
||||||
|
|
||||||
|
https://pxt.microbit.org/_gymCJCWPbiDu
|
||||||
|
|
||||||
|
### JavaScript code
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
/**
|
/**
|
||||||
@ -54,19 +67,26 @@ Player control:
|
|||||||
* During the incudation phase (INCUBATION), the player does not show any sign
|
* During the incudation phase (INCUBATION), the player does not show any sign
|
||||||
* of illness. After that phase, the sad face shows up.
|
* of illness. After that phase, the sad face shows up.
|
||||||
*
|
*
|
||||||
* Player control:
|
* The game will automatically stop once all players are dead or healthy. The master can
|
||||||
* A button: show identity icon
|
* also press A+B again to stop the game.
|
||||||
* B button: show current infection status
|
*
|
||||||
* Master control:
|
* Once the game is over, the micro:bit will show the player id (A,B,C...), health and
|
||||||
* A button: show patient zero identity + number of players
|
* who infected him.
|
||||||
* Sad face = infected
|
*
|
||||||
* Happy face = not infected
|
* Icons used in the game:
|
||||||
|
*
|
||||||
|
* Pairing: IconNames.Ghost
|
||||||
|
* Paired: IconNames.Happy
|
||||||
|
* Dead: IconNames.Skull
|
||||||
|
* Sick: IconNames.Sad
|
||||||
|
* Incubating: IconNames.Confused
|
||||||
|
* Healthy: IconNames.Happy
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const INCUBATION = 20000; // time before showing symptoms
|
const INCUBATION = 20000; // time before showing symptoms
|
||||||
const DEATH = 40000; // time before dying off the disease
|
const DEATH = 40000; // time before dying off the disease
|
||||||
const RSSI = -48; // db
|
const RSSI = -45; // db
|
||||||
const TRANSMISSIONPROB = 80; // %
|
const TRANSMISSIONPROB = 40; // % probability to transfer disease
|
||||||
|
|
||||||
enum GameState {
|
enum GameState {
|
||||||
Stopped,
|
Stopped,
|
||||||
@ -82,23 +102,40 @@ enum HealthState {
|
|||||||
Dead
|
Dead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GameIcons = {
|
||||||
|
Pairing: IconNames.Ghost,
|
||||||
|
Paired: IconNames.Happy,
|
||||||
|
Dead: IconNames.Skull,
|
||||||
|
Sick: IconNames.Sad,
|
||||||
|
Incubating: IconNames.Confused,
|
||||||
|
Healthy: IconNames.Happy
|
||||||
|
}
|
||||||
|
|
||||||
|
const playerIcons = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
class Player {
|
class Player {
|
||||||
id: number;
|
id: number;
|
||||||
icon: number;
|
icon: number;
|
||||||
health: HealthState;
|
health: HealthState;
|
||||||
|
show() {
|
||||||
|
basic.showString(playerIcons[this.icon]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// common state
|
||||||
let state = GameState.Stopped;
|
let state = GameState.Stopped;
|
||||||
|
|
||||||
|
// master state
|
||||||
let master = false;
|
let master = false;
|
||||||
let patientZero: Player;
|
let patientZero: Player;
|
||||||
|
const players: Player[] = [];
|
||||||
|
|
||||||
|
// player state
|
||||||
let paired = false;
|
let paired = false;
|
||||||
let infectedBy = 0; // who infected (icon id)
|
let infectedBy = -1; // who infected (playerIcon)
|
||||||
let infectedTime = 0; // local time when infection happened
|
let infectedTime = 0; // local time when infection happened
|
||||||
let icon = 0; // player icon and identity
|
let playerIcon = -1; // player icon and identity
|
||||||
let health = HealthState.Healthy;
|
let health = HealthState.Healthy;
|
||||||
|
|
||||||
const players: Player[] = [];
|
|
||||||
// get a player instance (creates one as needed)
|
// get a player instance (creates one as needed)
|
||||||
function player(id: number): Player {
|
function player(id: number): Player {
|
||||||
for (const p of players)
|
for (const p of players)
|
||||||
@ -107,12 +144,8 @@ function player(id: number): Player {
|
|||||||
// add player to game
|
// add player to game
|
||||||
let p = new Player();
|
let p = new Player();
|
||||||
p.id = id;
|
p.id = id;
|
||||||
p.icon = players.length ? players[players.length - 1].icon + 1 : 2;
|
p.icon = (players.length + 1) % playerIcons.length;
|
||||||
p.health = HealthState.Healthy;
|
p.health = HealthState.Healthy;
|
||||||
// don't use sad, happy
|
|
||||||
if (p.icon == IconNames.Happy) p.icon += 2;
|
|
||||||
if (p.icon == IconNames.Asleep) p.icon++;
|
|
||||||
if (p.icon == IconNames.Skull) p.icon++;
|
|
||||||
players.push(p);
|
players.push(p);
|
||||||
serial.writeLine(`player ==> ${p.id}`)
|
serial.writeLine(`player ==> ${p.id}`)
|
||||||
|
|
||||||
@ -127,43 +160,65 @@ function allDead(): boolean {
|
|||||||
|
|
||||||
function gameOver() {
|
function gameOver() {
|
||||||
state = GameState.Over;
|
state = GameState.Over;
|
||||||
basic.showIcon(patientZero.icon);
|
if (patientZero)
|
||||||
|
patientZero.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
function gameFace() {
|
function gameFace() {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case GameState.Stopped:
|
case GameState.Stopped:
|
||||||
|
basic.showIcon(GameIcons.Pairing);
|
||||||
|
break;
|
||||||
case GameState.Pairing:
|
case GameState.Pairing:
|
||||||
basic.showIcon(paired ? IconNames.Happy : IconNames.Ghost);
|
if (playerIcon > -1)
|
||||||
|
basic.showString(playerIcons[playerIcon]);
|
||||||
|
else
|
||||||
|
basic.showIcon(paired ? GameIcons.Paired : GameIcons.Pairing, 1);
|
||||||
break;
|
break;
|
||||||
case GameState.Running:
|
case GameState.Running:
|
||||||
switch (health) {
|
switch (health) {
|
||||||
case HealthState.Dead:
|
case HealthState.Dead:
|
||||||
basic.showIcon(IconNames.Skull);
|
basic.showIcon(GameIcons.Dead, 1);
|
||||||
break;
|
break;
|
||||||
case HealthState.Sick:
|
case HealthState.Sick:
|
||||||
basic.showIcon(IconNames.Sad);
|
basic.showIcon(GameIcons.Sick, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
basic.showIcon(IconNames.Happy);
|
basic.showIcon(GameIcons.Healthy, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GameState.Over:
|
case GameState.Over:
|
||||||
|
// show id
|
||||||
|
basic.showString(playerIcons[playerIcon]);
|
||||||
|
basic.pause(2000);
|
||||||
|
// show health
|
||||||
switch (health) {
|
switch (health) {
|
||||||
case HealthState.Dead:
|
case HealthState.Dead:
|
||||||
basic.showIcon(IconNames.Skull);
|
basic.showIcon(GameIcons.Dead, 2000);
|
||||||
break;
|
break;
|
||||||
case HealthState.Sick:
|
case HealthState.Sick:
|
||||||
basic.showIcon(IconNames.Sad);
|
basic.showIcon(GameIcons.Sick, 2000);
|
||||||
break;
|
break;
|
||||||
case HealthState.Incubating:
|
case HealthState.Incubating:
|
||||||
basic.showIcon(IconNames.Asleep);
|
basic.showIcon(GameIcons.Incubating, 2000);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
basic.showIcon(IconNames.Happy);
|
basic.showIcon(GameIcons.Healthy, 2000);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// show how infected
|
||||||
|
if (infectedBy > -1) {
|
||||||
|
basic.showString(" INFECTED BY");
|
||||||
|
basic.showString(playerIcons[infectedBy]);
|
||||||
|
basic.pause(2000);
|
||||||
|
} else {
|
||||||
|
basic.showString(" PATIENT ZERO");
|
||||||
|
basic.pause(2000);
|
||||||
|
}
|
||||||
|
// show score
|
||||||
|
game.showScore();
|
||||||
|
basic.pause(1000);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,10 +232,14 @@ input.onButtonPressed(Button.AB, () => {
|
|||||||
state = GameState.Pairing;
|
state = GameState.Pairing;
|
||||||
serial.writeLine("registered as master");
|
serial.writeLine("registered as master");
|
||||||
radio.setTransmitPower(7); // beef up master signal
|
radio.setTransmitPower(7); // beef up master signal
|
||||||
basic.showString("M");
|
basic.showString("0");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!master) return; // master only beyond this
|
||||||
|
|
||||||
// launch game
|
// launch game
|
||||||
else if (state == GameState.Pairing && master) {
|
if (state == GameState.Pairing) {
|
||||||
// pick 1 player and infect him
|
// pick 1 player and infect him
|
||||||
patientZero = players[Math.random(players.length)];
|
patientZero = players[Math.random(players.length)];
|
||||||
while (patientZero.health == HealthState.Healthy) {
|
while (patientZero.health == HealthState.Healthy) {
|
||||||
@ -193,45 +252,13 @@ input.onButtonPressed(Button.AB, () => {
|
|||||||
serial.writeLine(`game started ${players.length} players`);
|
serial.writeLine(`game started ${players.length} players`);
|
||||||
|
|
||||||
// show startup
|
// show startup
|
||||||
basic.showString("R");
|
basic.showIcon(GameIcons.Dead);
|
||||||
} // end game
|
} // end game
|
||||||
else if (state == GameState.Running && master) {
|
else if (state == GameState.Running) {
|
||||||
gameOver();
|
gameOver();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// display your icon
|
|
||||||
input.onButtonPressed(Button.A, () => {
|
|
||||||
led.stopAnimation()
|
|
||||||
if (master) {
|
|
||||||
if (patientZero)
|
|
||||||
basic.showIcon(patientZero.icon);
|
|
||||||
basic.showNumber(players.length);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
basic.showIcon(icon);
|
|
||||||
gameFace();
|
|
||||||
game.showScore();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// display who infected you
|
|
||||||
input.onButtonPressed(Button.B, () => {
|
|
||||||
if (master) {
|
|
||||||
let c = 0;
|
|
||||||
for (const p of players)
|
|
||||||
if (p.health == HealthState.Dead) c++;
|
|
||||||
basic.showNumber(c);
|
|
||||||
} else {
|
|
||||||
led.stopAnimation()
|
|
||||||
if (infectedBy)
|
|
||||||
basic.showIcon(infectedBy);
|
|
||||||
else
|
|
||||||
basic.showIcon(IconNames.Happy)
|
|
||||||
gameFace();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
radio.setGroup(42);
|
radio.setGroup(42);
|
||||||
radio.setTransmitSerialNumber(true)
|
radio.setTransmitSerialNumber(true)
|
||||||
radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, serial: id }) => {
|
radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, serial: id }) => {
|
||||||
@ -256,20 +283,12 @@ radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, seri
|
|||||||
} else {
|
} else {
|
||||||
if (receivedString == "state") {
|
if (receivedString == "state") {
|
||||||
// update game state
|
// update game state
|
||||||
let oldState = state;
|
|
||||||
state = receivedNumber as GameState;
|
state = receivedNumber as GameState;
|
||||||
if (oldState != state) {
|
} else if (infectedBy < 0 &&
|
||||||
switch (state) {
|
|
||||||
case GameState.Pairing:
|
|
||||||
basic.showString("P");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!infectedBy &&
|
|
||||||
receivedString == "infect"
|
receivedString == "infect"
|
||||||
&& receivedNumber == control.deviceSerialNumber()) {
|
&& receivedNumber == control.deviceSerialNumber()) {
|
||||||
// infected by master
|
// infected by master
|
||||||
infectedBy = 1; // infected my master
|
infectedBy = 0; // infected my master
|
||||||
infectedTime = input.runningTime();
|
infectedTime = input.runningTime();
|
||||||
health = HealthState.Incubating;
|
health = HealthState.Incubating;
|
||||||
serial.writeLine(`infected ${control.deviceSerialNumber()}`);
|
serial.writeLine(`infected ${control.deviceSerialNumber()}`);
|
||||||
@ -287,12 +306,10 @@ radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, seri
|
|||||||
// paired!
|
// paired!
|
||||||
serial.writeLine(`player paired ==> ${control.deviceSerialNumber()}`)
|
serial.writeLine(`player paired ==> ${control.deviceSerialNumber()}`)
|
||||||
paired = true;
|
paired = true;
|
||||||
basic.showString("R");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (paired && receivedString == "i" + control.deviceSerialNumber().toString()) {
|
else if (paired && receivedString == "i" + control.deviceSerialNumber().toString()) {
|
||||||
icon = receivedNumber;
|
playerIcon = receivedNumber;
|
||||||
basic.showIcon(icon);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GameState.Running:
|
case GameState.Running:
|
||||||
@ -305,7 +322,8 @@ radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, seri
|
|||||||
infectedTime = input.runningTime();
|
infectedTime = input.runningTime();
|
||||||
health = HealthState.Incubating;
|
health = HealthState.Incubating;
|
||||||
}
|
}
|
||||||
} else if (receivedString == "health" && signal > RSSI) {
|
} else if (health != HealthState.Dead
|
||||||
|
&& receivedString == "health" && signal > RSSI) {
|
||||||
game.addScore(1);
|
game.addScore(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -331,15 +349,19 @@ basic.forever(() => {
|
|||||||
radio.sendValue("h" + p.id, p.health);
|
radio.sendValue("h" + p.id, p.health);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GameState.Over:
|
||||||
|
if (patientZero)
|
||||||
|
patientZero.show();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
radio.sendValue("state", state); // keep broadcasting the game state
|
radio.sendValue("state", state); // keep broadcasting the game state
|
||||||
} else { // player loop
|
} else { // player loop
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case GameState.Pairing:
|
case GameState.Pairing:
|
||||||
// broadcast player id
|
// broadcast player id
|
||||||
if (!icon)
|
if (playerIcon < 0)
|
||||||
radio.sendValue("pair", control.deviceSerialNumber());
|
radio.sendValue("pair", control.deviceSerialNumber());
|
||||||
else if (infectedBy)
|
else if (infectedBy > -1)
|
||||||
radio.sendValue("health", health);
|
radio.sendValue("health", health);
|
||||||
break;
|
break;
|
||||||
case GameState.Running:
|
case GameState.Running:
|
||||||
@ -350,17 +372,15 @@ basic.forever(() => {
|
|||||||
health = HealthState.Sick;
|
health = HealthState.Sick;
|
||||||
// transmit disease
|
// transmit disease
|
||||||
if (health == HealthState.Incubating || health == HealthState.Sick)
|
if (health == HealthState.Incubating || health == HealthState.Sick)
|
||||||
radio.sendValue("transmit", icon);
|
radio.sendValue("transmit", playerIcon);
|
||||||
radio.sendValue("health", health);
|
radio.sendValue("health", health);
|
||||||
gameFace();
|
|
||||||
break;
|
|
||||||
case GameState.Over:
|
|
||||||
// show infection state
|
|
||||||
gameFace();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// show current animation
|
||||||
|
gameFace();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
basic.showIcon(IconNames.Ghost);
|
|
||||||
|
basic.showIcon(GameIcons.Pairing)
|
||||||
```
|
```
|
Loading…
x
Reference in New Issue
Block a user