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:
Chase Mortensen 2019-04-12 17:13:20 -07:00 committed by GitHub
parent 61aae94d8b
commit 24c42cc3e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -69,8 +69,6 @@ As a result, it will not convert back to blocks.
### ~ ### ~
https://makecode.microbit.org/_gymCJCWPbiDu
## JavaScript code ## JavaScript code
```typescript ```typescript
@ -128,6 +126,16 @@ enum HealthState {
Dead Dead
} }
enum MessageKind {
PairRequest,
PairConfirmation,
HealthSet,
HealthValue,
InitialInfect,
TransmitVirus,
GameState
}
const GameIcons = { const GameIcons = {
Pairing: IconNames.Ghost, Pairing: IconNames.Ghost,
Paired: IconNames.Happy, Paired: IconNames.Happy,
@ -137,6 +145,52 @@ const GameIcons = {
Healthy: IconNames.Happy 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"; const playerIcons = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
class Player { class Player {
id: number; id: number;
@ -280,70 +334,76 @@ input.onButtonPressed(Button.AB, () => {
}) })
radio.setGroup(42); radio.setGroup(42);
radio.setTransmitSerialNumber(true) radio.onReceivedBuffer(function (receivedBuffer: Buffer) {
radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, serial: id }) => { const incomingMessage = new Message(receivedBuffer);
const signal = radio.receivedPacket(RadioPacketProperty.SignalStrength);
if (master) { if (master) {
if (receivedString == "pair") { switch (incomingMessage.kind) {
// register player case MessageKind.PairRequest:
let n = players.length; // register player
let p = player(id); let n = players.length;
// show player number if changed player(incomingMessage.fromSerialNumber);
if (n != players.length) { // show player number if changed
led.stopAnimation(); if (n != players.length) {
basic.showNumber(players.length); 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;
} }
break; break;
case GameState.Running: case MessageKind.HealthValue:
// broadcast infection status let p = player(incomingMessage.fromSerialNumber);
if (health == HealthState.Healthy && receivedString == "transmit") { p.health = incomingMessage.value;
serial.writeLine(`signal: ${signal}`); // check if all infected
if (signal > RSSI && if (allDead())
Math.randomRange(0, 100) > TRANSMISSIONPROB) { gameOver();
infectedBy = receivedNumber; break;
infectedTime = input.runningTime(); }
health = HealthState.Incubating; } 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); game.addScore(1);
} }
break; break;
@ -353,20 +413,27 @@ radio.onDataPacketReceived(({ time, receivedNumber, receivedString, signal, seri
// main game loop // main game loop
basic.forever(() => { basic.forever(() => {
let message: Message;
if (master) { if (master) {
switch (state) { switch (state) {
case GameState.Pairing: case GameState.Pairing:
// tell each player they are registered // tell each player they are registered
for (const p of players) { for (const p of players) {
radio.sendValue("paired", p.id); message = new Message();
radio.sendValue("i" + p.id, p.icon); message.kind = MessageKind.PairConfirmation;
message.value = p.icon;
message.toSerialNumber = p.id;
message.send();
} }
serial.writeLine(`pairing ${players.length} players`); serial.writeLine(`pairing ${players.length} players`);
basic.pause(500); basic.pause(500);
break; break;
case GameState.Infecting: case GameState.Infecting:
if (patientZero.health == HealthState.Healthy) { 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); basic.pause(100);
} else { } else {
serial.writeLine(`patient ${patientZero.id} infected`); serial.writeLine(`patient ${patientZero.id} infected`);
@ -377,7 +444,11 @@ basic.forever(() => {
break; break;
case GameState.Running: case GameState.Running:
for (const p of players) { 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; break;
case GameState.Over: case GameState.Over:
@ -385,18 +456,33 @@ basic.forever(() => {
patientZero.show(); patientZero.show();
break; 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 } else { // player loop
switch (state) { switch (state) {
case GameState.Pairing: case GameState.Pairing:
// broadcast player id // broadcast player id
if (playerIcon < 0) if (playerIcon < 0) {
radio.sendValue("pair", control.deviceSerialNumber()); message = new Message();
else if (infectedBy > -1) message.kind = MessageKind.PairRequest;
radio.sendValue("health", health); 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; break;
case GameState.Infecting: case GameState.Infecting:
radio.sendValue("health", health); message = new Message();
message.kind = MessageKind.HealthValue;
message.fromSerialNumber = control.deviceSerialNumber();
message.value = health;
message.send();
break; break;
case GameState.Running: case GameState.Running:
// update health status // update health status
@ -405,9 +491,18 @@ basic.forever(() => {
else if (health != HealthState.Healthy && input.runningTime() - infectedTime > INCUBATION) else if (health != HealthState.Healthy && input.runningTime() - infectedTime > INCUBATION)
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", playerIcon); message = new Message();
radio.sendValue("health", health); 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; break;
} }
// show current animation // show current animation