Fixes for infection game (#2003)
* Fixes for infection game * Updated infection game to use message class * fixed whitespace * Changes to Message class
This commit is contained in:
parent
61aae94d8b
commit
24c42cc3e8
@ -69,8 +69,6 @@ As a result, it will not convert back to blocks.
|
||||
|
||||
### ~
|
||||
|
||||
https://makecode.microbit.org/_gymCJCWPbiDu
|
||||
|
||||
## JavaScript code
|
||||
|
||||
```typescript
|
||||
@ -128,6 +126,16 @@ enum HealthState {
|
||||
Dead
|
||||
}
|
||||
|
||||
enum MessageKind {
|
||||
PairRequest,
|
||||
PairConfirmation,
|
||||
HealthSet,
|
||||
HealthValue,
|
||||
InitialInfect,
|
||||
TransmitVirus,
|
||||
GameState
|
||||
}
|
||||
|
||||
const GameIcons = {
|
||||
Pairing: IconNames.Ghost,
|
||||
Paired: IconNames.Happy,
|
||||
@ -137,6 +145,52 @@ const GameIcons = {
|
||||
Healthy: IconNames.Happy
|
||||
}
|
||||
|
||||
class Message {
|
||||
|
||||
private _data: Buffer;
|
||||
|
||||
constructor(input?: Buffer) {
|
||||
this._data = input || control.createBuffer(13);
|
||||
}
|
||||
|
||||
get kind(): number {
|
||||
return this._data.getNumber(NumberFormat.Int8LE, 0);
|
||||
}
|
||||
|
||||
set kind(x: number) {
|
||||
this._data.setNumber(NumberFormat.Int8LE, 0, x);
|
||||
}
|
||||
|
||||
get fromSerialNumber(): number {
|
||||
return this._data.getNumber(NumberFormat.Int32LE, 1);
|
||||
}
|
||||
|
||||
set fromSerialNumber(x: number) {
|
||||
this._data.setNumber(NumberFormat.Int32LE, 1, x);
|
||||
}
|
||||
|
||||
get value(): number {
|
||||
return this._data.getNumber(NumberFormat.Int32LE, 5);
|
||||
}
|
||||
|
||||
set value(x: number) {
|
||||
this._data.setNumber(NumberFormat.Int32LE, 5, x);
|
||||
}
|
||||
|
||||
get toSerialNumber(): number {
|
||||
return this._data.getNumber(NumberFormat.Int32LE, 9);
|
||||
}
|
||||
|
||||
set toSerialNumber(x: number) {
|
||||
this._data.setNumber(NumberFormat.Int32LE, 9, x);
|
||||
}
|
||||
|
||||
send() {
|
||||
radio.sendBuffer(this._data);
|
||||
basic.pause(250);
|
||||
}
|
||||
}
|
||||
|
||||
const playerIcons = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
class Player {
|
||||
id: number;
|
||||
@ -280,70 +334,76 @@ input.onButtonPressed(Button.AB, () => {
|
||||
})
|
||||
|
||||
radio.setGroup(42);
|
||||
radio.setTransmitSerialNumber(true)
|
||||
radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, serial: id }) => {
|
||||
radio.onReceivedBuffer(function (receivedBuffer: Buffer) {
|
||||
const incomingMessage = new Message(receivedBuffer);
|
||||
const signal = radio.receivedPacket(RadioPacketProperty.SignalStrength);
|
||||
if (master) {
|
||||
if (receivedString == "pair") {
|
||||
// register player
|
||||
let n = players.length;
|
||||
let p = player(id);
|
||||
// show player number if changed
|
||||
if (n != players.length) {
|
||||
led.stopAnimation();
|
||||
basic.showNumber(players.length);
|
||||
}
|
||||
}
|
||||
else if (receivedString == "health") {
|
||||
let p = player(id);
|
||||
p.health = receivedNumber;
|
||||
// check if all infected
|
||||
if (allDead())
|
||||
gameOver();
|
||||
}
|
||||
} else {
|
||||
if (receivedString == "state") {
|
||||
// update game state
|
||||
state = receivedNumber as GameState;
|
||||
} else if (infectedBy < 0 &&
|
||||
receivedString == "infect"
|
||||
&& receivedNumber == control.deviceSerialNumber()) {
|
||||
// infected by master
|
||||
infectedBy = 0; // infected my master
|
||||
infectedTime = input.runningTime();
|
||||
health = HealthState.Incubating;
|
||||
serial.writeLine(`infected ${control.deviceSerialNumber()}`);
|
||||
}
|
||||
if (receivedString == "h" + control.deviceSerialNumber().toString() &&
|
||||
health < receivedNumber) {
|
||||
health = receivedNumber;
|
||||
}
|
||||
switch (state) {
|
||||
case GameState.Pairing:
|
||||
// medium range in pairing mode
|
||||
if (!paired &&
|
||||
receivedString == "paired"
|
||||
&& receivedNumber == control.deviceSerialNumber()) {
|
||||
// paired!
|
||||
serial.writeLine(`player paired ==> ${control.deviceSerialNumber()}`)
|
||||
paired = true;
|
||||
return;
|
||||
}
|
||||
else if (paired && receivedString == "i" + control.deviceSerialNumber().toString()) {
|
||||
playerIcon = receivedNumber;
|
||||
switch (incomingMessage.kind) {
|
||||
case MessageKind.PairRequest:
|
||||
// register player
|
||||
let n = players.length;
|
||||
player(incomingMessage.fromSerialNumber);
|
||||
// show player number if changed
|
||||
if (n != players.length) {
|
||||
basic.showNumber(players.length);
|
||||
}
|
||||
break;
|
||||
case GameState.Running:
|
||||
// broadcast infection status
|
||||
if (health == HealthState.Healthy && receivedString == "transmit") {
|
||||
serial.writeLine(`signal: ${signal}`);
|
||||
if (signal > RSSI &&
|
||||
Math.randomRange(0, 100) > TRANSMISSIONPROB) {
|
||||
infectedBy = receivedNumber;
|
||||
infectedTime = input.runningTime();
|
||||
health = HealthState.Incubating;
|
||||
case MessageKind.HealthValue:
|
||||
let p = player(incomingMessage.fromSerialNumber);
|
||||
p.health = incomingMessage.value;
|
||||
// check if all infected
|
||||
if (allDead())
|
||||
gameOver();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (incomingMessage.kind) {
|
||||
case MessageKind.GameState:
|
||||
// update game state
|
||||
state = incomingMessage.value as GameState;
|
||||
break;
|
||||
case MessageKind.InitialInfect:
|
||||
if (infectedBy < 0 &&
|
||||
incomingMessage.toSerialNumber == control.deviceSerialNumber()) {
|
||||
// infected by master
|
||||
infectedBy = 0; // infected my master
|
||||
infectedTime = input.runningTime();
|
||||
health = HealthState.Incubating;
|
||||
serial.writeLine(`infected ${control.deviceSerialNumber()}`);
|
||||
}
|
||||
break;
|
||||
case MessageKind.HealthSet:
|
||||
if (incomingMessage.toSerialNumber == control.deviceSerialNumber()) {
|
||||
const newHealth = incomingMessage.value;
|
||||
if (health < newHealth) {
|
||||
health = newHealth;
|
||||
}
|
||||
} else if (health != HealthState.Dead
|
||||
&& receivedString == "health" && signal > RSSI) {
|
||||
}
|
||||
break;
|
||||
case MessageKind.PairConfirmation:
|
||||
if (!paired && state == GameState.Pairing &&
|
||||
incomingMessage.toSerialNumber == control.deviceSerialNumber()) {
|
||||
// paired!
|
||||
serial.writeLine(`player paired ==> ${control.deviceSerialNumber()}`)
|
||||
playerIcon = incomingMessage.value;
|
||||
paired = true;
|
||||
}
|
||||
break;
|
||||
case MessageKind.TransmitVirus:
|
||||
if (state == GameState.Running) {
|
||||
if (health == HealthState.Healthy) {
|
||||
serial.writeLine(`signal: ${signal}`);
|
||||
if (signal > RSSI &&
|
||||
Math.randomRange(0, 100) > TRANSMISSIONPROB) {
|
||||
infectedBy = incomingMessage.value;
|
||||
infectedTime = input.runningTime();
|
||||
health = HealthState.Incubating;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MessageKind.HealthValue:
|
||||
if (health != HealthState.Dead && signal > RSSI) {
|
||||
game.addScore(1);
|
||||
}
|
||||
break;
|
||||
@ -353,20 +413,27 @@ radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, seri
|
||||
|
||||
// main game loop
|
||||
basic.forever(() => {
|
||||
let message: Message;
|
||||
if (master) {
|
||||
switch (state) {
|
||||
case GameState.Pairing:
|
||||
// tell each player they are registered
|
||||
for (const p of players) {
|
||||
radio.sendValue("paired", p.id);
|
||||
radio.sendValue("i" + p.id, p.icon);
|
||||
message = new Message();
|
||||
message.kind = MessageKind.PairConfirmation;
|
||||
message.value = p.icon;
|
||||
message.toSerialNumber = p.id;
|
||||
message.send();
|
||||
}
|
||||
serial.writeLine(`pairing ${players.length} players`);
|
||||
basic.pause(500);
|
||||
break;
|
||||
case GameState.Infecting:
|
||||
if (patientZero.health == HealthState.Healthy) {
|
||||
radio.sendValue("infect", patientZero.id);
|
||||
message = new Message();
|
||||
message.kind = MessageKind.InitialInfect;
|
||||
message.toSerialNumber = patientZero.id;
|
||||
message.send();
|
||||
basic.pause(100);
|
||||
} else {
|
||||
serial.writeLine(`patient ${patientZero.id} infected`);
|
||||
@ -377,7 +444,11 @@ basic.forever(() => {
|
||||
break;
|
||||
case GameState.Running:
|
||||
for (const p of players) {
|
||||
radio.sendValue("h" + p.id, p.health);
|
||||
message = new Message();
|
||||
message.kind = MessageKind.HealthSet;
|
||||
message.value = p.health;
|
||||
message.toSerialNumber = p.id;
|
||||
message.send();
|
||||
}
|
||||
break;
|
||||
case GameState.Over:
|
||||
@ -385,18 +456,33 @@ basic.forever(() => {
|
||||
patientZero.show();
|
||||
break;
|
||||
}
|
||||
radio.sendValue("state", state); // keep broadcasting the game state
|
||||
message = new Message()
|
||||
message.kind = MessageKind.GameState;
|
||||
message.value = state;
|
||||
message.send();
|
||||
} else { // player loop
|
||||
switch (state) {
|
||||
case GameState.Pairing:
|
||||
// broadcast player id
|
||||
if (playerIcon < 0)
|
||||
radio.sendValue("pair", control.deviceSerialNumber());
|
||||
else if (infectedBy > -1)
|
||||
radio.sendValue("health", health);
|
||||
if (playerIcon < 0) {
|
||||
message = new Message();
|
||||
message.kind = MessageKind.PairRequest;
|
||||
message.fromSerialNumber = control.deviceSerialNumber();
|
||||
message.send();
|
||||
} else if (infectedBy > -1) {
|
||||
message = new Message();
|
||||
message.kind = MessageKind.HealthValue;
|
||||
message.fromSerialNumber = control.deviceSerialNumber();
|
||||
message.value = health;
|
||||
message.send();
|
||||
}
|
||||
break;
|
||||
case GameState.Infecting:
|
||||
radio.sendValue("health", health);
|
||||
message = new Message();
|
||||
message.kind = MessageKind.HealthValue;
|
||||
message.fromSerialNumber = control.deviceSerialNumber();
|
||||
message.value = health;
|
||||
message.send();
|
||||
break;
|
||||
case GameState.Running:
|
||||
// update health status
|
||||
@ -405,9 +491,18 @@ basic.forever(() => {
|
||||
else if (health != HealthState.Healthy && input.runningTime() - infectedTime > INCUBATION)
|
||||
health = HealthState.Sick;
|
||||
// transmit disease
|
||||
if (health == HealthState.Incubating || health == HealthState.Sick)
|
||||
radio.sendValue("transmit", playerIcon);
|
||||
radio.sendValue("health", health);
|
||||
if (health == HealthState.Incubating || health == HealthState.Sick) {
|
||||
message = new Message();
|
||||
message.kind = MessageKind.TransmitVirus;
|
||||
message.fromSerialNumber = control.deviceSerialNumber();
|
||||
message.value = playerIcon;
|
||||
message.send();
|
||||
}
|
||||
message = new Message();
|
||||
message.kind = MessageKind.HealthValue;
|
||||
message.fromSerialNumber = control.deviceSerialNumber();
|
||||
message.value = health;
|
||||
message.send();
|
||||
break;
|
||||
}
|
||||
// show current animation
|
||||
|
Loading…
Reference in New Issue
Block a user