Skip to content

Instantly share code, notes, and snippets.

@tdzl2003
Last active November 30, 2021 03:31
Show Gist options
  • Save tdzl2003/bc272749099e53e224b9d83658dc75bd to your computer and use it in GitHub Desktop.
Save tdzl2003/bc272749099e53e224b9d83658dc75bd to your computer and use it in GitHub Desktop.
Build some distributed game simulation system.
import { action, Actor, state, World } from "./defines";
function wmc1616(state0: number, state1: number) {
state0 = 18030 * (state0 & 0xffff) + (state0 >> 16);
state1 = 30903 * (state1 & 0xffff) + (state1 >> 16);
return [
((((state0 & 0xffff) << 16) + (state1 & 0xffff)) >>> 0) / 2 ** 32,
state0,
state1,
];
}
class Board extends Actor {
@state
private playerA: Player | null = null;
@state
private playerB: Player | null = null;
@state
private aMove: number | null = null;
@state
private bMove: number | null = null;
@action
join(player: Player) {
if (!this.playerA) {
this.playerA = player;
player.joined(this);
return;
}
if (!this.playerB) {
this.playerB = player;
player.joined(this);
this.start();
return;
}
}
@action
start() {
this.aMove = null;
this.bMove = null;
this.playerA?.think();
this.playerB?.think();
}
@action
move(from: Player, move: number) {
if (from === this.playerA) {
this.aMove = move;
}
if (from === this.playerB) {
this.bMove = move;
}
if (this.aMove && this.bMove) {
this.compare();
}
}
@action
compare() {
if (!this.aMove || !this.bMove) {
return;
}
const r = (this.aMove - this.bMove + 3) % 3;
switch (r) {
case 0: {
console.log("Draw");
break;
}
case 1: {
console.log("A win");
break;
}
case 2: {
console.log("B win");
break;
}
}
this.start();
}
}
class Player extends Actor {
@state
private state0 = 1;
@state
private state1 = 2;
@state
private moved = false;
@state
private board: Board | null = null;
@action
joined(board: Board) {
this.board = board;
}
@action
think() {
if (this.board && !this.moved) {
const [res, n0, n1] = wmc1616(this.state0, this.state1);
this.state0 = n0;
this.state1 = n1;
this.board.move(this, Math.floor(3 * res));
}
}
}
class MyWorld extends World {
init() {
const board = Board.create(this);
const playerA = Player.create(this);
const playerB = Player.create(this);
board.join(playerA);
board.join(playerB);
}
}
function wmc1616(state0: number, state1: number) {
state0 = 18030 * (state0 & 0xffff) + (state0 >> 16);
state1 = 30903 * (state1 & 0xffff) + (state1 >> 16);
return [
((((state0 & 0xffff) << 16) + (state1 & 0xffff)) >>> 0) / 2 ** 32,
state0,
state1,
];
}
interface Board extends Actor {
director: "Board";
playerA?: Player;
playerB?: Player;
aMove?: number;
bMove?: number;
}
interface Player extends Actor {
director: "Player";
state0: number;
state1: number;
moved: boolean;
board?: Board;
}
@director
class BoardDirector extends Director<Board> {
join(board: Board, player: Player) {
if (!board.playerA) {
board.playerA = player;
scheduleAction(player, "joined", board.id);
return;
}
if (!board.playerB) {
board.playerB = player;
scheduleAction(player, "joined", board.id);
scheduleAction(board, "start");
return;
}
}
start(board: Board) {
board.aMove = undefined;
board.bMove = undefined;
if (board.playerA && board.playerB) {
scheduleAction(board.playerA, "think");
scheduleAction(board.playerB, "think");
}
}
move(board: Board, from: Player, move: number) {
if (from === board.playerA) {
board.aMove = move;
}
if (from === board.playerB) {
board.bMove = move;
}
if (board.aMove && board.bMove) {
scheduleAction(board, "compare");
}
}
compare(board: Board) {
if (!board.aMove || !board.bMove) {
return;
}
const r = (board.aMove - board.bMove + 3) % 3;
switch (r) {
case 0: {
console.log("Draw");
break;
}
case 1: {
console.log("A win");
break;
}
case 2: {
console.log("B win");
break;
}
}
scheduleAction(board, "start");
}
}
class PlayerDirector extends Director<Player> {
joined(player: Player, board: Board) {
player.board = board;
}
think(player: Player) {
if (player.board && !player.moved) {
const [res, n0, n1] = wmc1616(player.state0, player.state1);
player.state0 = n0;
player.state1 = n1;
scheduleAction(player.board, "move", player, (this, Math.floor(3 * res)));
}
}
}
@tdzl2003
Copy link
Author

希望采用类似这种代码范式编写业务代码,实际的action可以分散在包括客户端在内的所有节点上执行,从而在未来支持极度复杂和大开销的Actor逻辑(如状态机+决策树、复杂的几何运算等) 乘以海量的Actor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment