diff --git a/assembly/dice.ts b/assembly/dice.ts index 9229af9..9dcdc98 100644 --- a/assembly/dice.ts +++ b/assembly/dice.ts @@ -2,7 +2,7 @@ import {JSONEncoder} from "../node_modules/assemblyscript-json/assembly/encoder" import {ErrorResponse, GetBalanceResponse, JoinResponse, Response, RollResponse} from "./response"; const PLAYERS_MAX_COUNT: i32 = 1024; -const SEED: u64 = 12345678; +const SEED: u64 = 123456; // the account balance of new players const INIT_ACCOUNT_BALANCE: u64 = 100; // if win, player receives bet_amount * PAYOUT_RATE money @@ -20,7 +20,7 @@ export class GameManager { NativeMath.seedRandom(SEED); } - join(): Response { + join(): string { // delete the oldest player, if maximum players reach if (this.playerIds.length >= PLAYERS_MAX_COUNT) { let lastPlayer = this.playerIds.pop(); @@ -34,42 +34,51 @@ export class GameManager { this.registeredPlayers += 1; - return response; + return response.serialize(); } - roll(playerId: u64, betPlacement: u8, betSize: u32): Response { + roll(playerId: u64, betPlacement: u8, betSize: u64): string { if (betPlacement > DICE_LINE_COUNT) { - return new ErrorResponse("Incorrect placement, please choose number from 1 to 6") + let error = new ErrorResponse("Incorrect placement, please choose number from 1 to 6"); + return error.serialize(); } if (!this.playerBalance.has(playerId)) { - return new ErrorResponse("There is no player with such id: " + playerId.toString()) + let error = new ErrorResponse("There is no player with such id: " + playerId.toString()); + return error.serialize(); } - let balance = this.playerBalance.get(playerId); + let balance: u64 = this.playerBalance.get(playerId); if (betSize > balance) { - return new ErrorResponse(`Player hasn't enough money: player's current balance is ${balance.toString()} while the bet is ${betSize.toString()}`) + let error = new ErrorResponse(`Player hasn't enough money: player's current balance is ${balance.toString()} while the bet is ${betSize.toString()}`); + return error.serialize(); } - let outcome = ((NativeMath.random() * 1000000000) % DICE_LINE_COUNT - 1) as u8; + let outcome = ((NativeMath.random() * 10000000) % DICE_LINE_COUNT + 1) as u8; - if (betPlacement === outcome) { - balance = balance + (betSize * PAYOUT_RATE); + let newBalance: u64 = 0; + + if (betPlacement == outcome) { + newBalance = balance + (betSize * PAYOUT_RATE); } else { - balance = balance - betSize; + newBalance = balance - betSize; } - this.playerBalance.set(playerId, balance); + this.playerBalance.delete(playerId); + this.playerBalance.set(playerId, newBalance); - return new RollResponse(outcome, balance); + let response = new RollResponse(outcome, newBalance); + return response.serialize(); } - getBalance(playerId: u64): Response { + getBalance(playerId: u64): string { if (!this.playerBalance.has(playerId)) { - return new ErrorResponse("There is no player with id: " + playerId.toString()); + let error = new ErrorResponse("There is no player with id: " + playerId.toString()); + return error.serialize(); } - return new GetBalanceResponse(this.playerBalance.get(playerId)); + let response = new GetBalanceResponse(this.playerBalance.get(playerId)); + return response.serialize(); } } diff --git a/assembly/game_handler.ts b/assembly/game_handler.ts index b8ae99b..1a39c97 100644 --- a/assembly/game_handler.ts +++ b/assembly/game_handler.ts @@ -1,4 +1,4 @@ -import {decode, GetBalanceRequest, JoinRequest, Request, RollRequest, UnknownRequest} from "./request"; +import {Action, decode, GetBalanceRequest, Request, RollRequest, UnknownRequest} from "./request"; import {ErrorResponse} from "./response"; import {GameManager} from "./dice"; @@ -9,19 +9,20 @@ export function handler(requestBytes: Uint8Array): string { let request: Request = decode(requestBytes); - if (request.action === "Join") { - return gameManager.join().serialize(); - } else if (request.action === "Roll") { + if (request.action == Action.Join) { + return gameManager.join(); + } else if (request.action == Action.Roll) { let r = request as RollRequest; - return gameManager.roll(r.playerId, r.betPlacement, r.betSize).serialize(); - } else if (request.action === "GetBalance") { + return gameManager.roll(r.playerId, r.betPlacement, r.betSize); + } else if (request.action == Action.GetBalance) { let r = request as GetBalanceRequest; - return gameManager.getBalance(r.playerId).serialize(); - } else if (request.action === "unknown") { + return gameManager.getBalance(r.playerId); + } else if (request.action == Action.Unknown) { let r = request as UnknownRequest; - return (new ErrorResponse(r.message)).serialize(); + let error = new ErrorResponse(r.message); + return error.serialize(); } - let response = new ErrorResponse("Unereachable: " + request.action); + let response = new ErrorResponse("Unereachable."); return response.serialize(); } diff --git a/assembly/request.ts b/assembly/request.ts index 6a36c47..0eef72b 100644 --- a/assembly/request.ts +++ b/assembly/request.ts @@ -1,7 +1,15 @@ import {JSONDecoder, JSONHandler} from "../node_modules/assemblyscript-json/assembly/decoder"; +export enum Action { + Roll = 1, + Join = 2, + GetBalance = 3, + Unknown = 4, + Error = 5 +} + export abstract class Request { - public action: string = ""; + public action: Action = null; } export class UnknownRequest extends Request { @@ -9,7 +17,7 @@ export class UnknownRequest extends Request { constructor(message: string) { super(); - this.action = "unknown"; + this.action = Action.Unknown; this.message = message; } @@ -17,7 +25,7 @@ export class UnknownRequest extends Request { export class JoinRequest extends Request { constructor() { super(); - this.action = "Join"; + this.action = Action.Join; } } export class RollRequest extends Request { @@ -29,7 +37,7 @@ export class RollRequest extends Request { this.playerId = playerId; this.betPlacement = betPlacement; this.betSize = betSize; - this.action = "Roll"; + this.action = Action.Roll; } } export class GetBalanceRequest extends Request { @@ -37,7 +45,7 @@ export class GetBalanceRequest extends Request { constructor(playerId: u64) { super(); this.playerId = playerId; - this.action = "GetBalance"; + this.action = Action.GetBalance; } } @@ -53,11 +61,11 @@ export function decode(bytes: Uint8Array): Request { return new UnknownRequest("'action' field is not specified.") } - if (action === "Join") { + if (action == "Join") { return new JoinRequest(); - } else if (action === "Roll") { + } else if (action == "Roll") { return new RollRequest(jsonHandler.playerId, jsonHandler.betPlacement, jsonHandler.betSize) - } else if (action === "GetBalance") { + } else if (action == "GetBalance") { return new GetBalanceRequest(jsonHandler.playerId) } else { return new UnknownRequest("There is no request with action: " + action); @@ -74,7 +82,7 @@ class RequestJSONEventsHandler extends JSONHandler { public playerBalance: u64; setString(name: string, value: string): void { - if (name === "action") { + if (name == "action") { this.action = value; } // json scheme is not strict, so we won't throw an error on excess fields @@ -82,15 +90,15 @@ class RequestJSONEventsHandler extends JSONHandler { setInteger(name: string, value: i64): void { - if (name == "playerId") { + if (name == "player_id") { this.playerId = value as u64; - } else if (name === "betPlacement") { + } else if (name == "bet_placement") { this.betPlacement = value as u8; - } else if (name === "betSize") { + } else if (name == "bet_size") { this.betSize = value as u32; - } else if (name === "outcome") { + } else if (name == "outcome") { this.outcome = value as u8; - } else if (name === "playerBalance") { + } else if (name == "player_balance") { this.playerBalance = value as u64; } diff --git a/assembly/response.ts b/assembly/response.ts index 3a67496..e2e83bd 100644 --- a/assembly/response.ts +++ b/assembly/response.ts @@ -35,8 +35,8 @@ export class RollResponse extends Response { serialize(): string { let encoder = new JSONEncoder(); encoder.setString("action", "Roll"); - encoder.setInteger("outcome", this.outcome as i32); - encoder.setInteger("playerBalance", this.playerBalance as i32); + encoder.setInteger("outcome", this.outcome as i64); + encoder.setInteger("player_balance", this.playerBalance as i64); return encoder.toString(); } diff --git a/tests/assembly/roundtrip.spec.as.ts b/tests/assembly/roundtrip.spec.as.ts index af40a99..61b3a4e 100644 --- a/tests/assembly/roundtrip.spec.as.ts +++ b/tests/assembly/roundtrip.spec.as.ts @@ -8,7 +8,11 @@ declare function logF64(val: f64): void; export class SomeTest { static shouldHandleEmptyObject(): bool { - return this.roundripTest("{\"test\": \"heloooooooooooooooooo\"}"); + this.roundripTest("{\"action\": \"Join\"}"); + this.roundripTest("{\"action\": \"Roll\", \"player_id\": 0, \"bet_placement\": 1, \"bet_size\": 10}"); + this.roundripTest("{\"action\": \"Roll\", \"player_id\": 0, \"bet_placement\": 1, \"bet_size\": 10}"); + this.roundripTest("{\"action\": \"Roll\", \"player_id\": 0, \"bet_placement\": 1, \"bet_size\": 10}"); + return this.roundripTest("{\"action\": \"Roll\", \"player_id\": 1, \"bet_placement\": 1, \"bet_size\": 10}"); } private static roundripTest(jsonString: string): bool {