-
Notifications
You must be signed in to change notification settings - Fork 9
/
bots.mts
109 lines (95 loc) · 3.82 KB
/
bots.mts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import {WebSocket} from 'ws'
import * as common from './common.mjs';
import type {Player} from './common.mjs'
const BOT_FPS = 60;
interface Bot {
ws: WebSocket,
me: Player | undefined,
goalX: number,
goalY: number,
timeoutBeforeTurn: undefined | number,
}
function createBot(): Bot {
const bot: Bot = {
ws: new WebSocket(`ws://localhost:${common.SERVER_PORT}/`),
me: undefined,
goalX: common.WORLD_WIDTH*0.5,
goalY: common.WORLD_HEIGHT*0.5,
timeoutBeforeTurn: undefined,
};
bot.ws.binaryType = 'arraybuffer';
bot.ws.addEventListener("message", (event) => {
if (!(event.data instanceof ArrayBuffer)) {
return;
}
const view = new DataView(event.data);
if (bot.me === undefined) {
if (common.HelloStruct.verify(view)) {
bot.me = {
id: common.HelloStruct.id.read(view),
x: common.HelloStruct.x.read(view),
y: common.HelloStruct.y.read(view),
moving: 0,
hue: common.HelloStruct.hue.read(view)/256*360,
}
turn();
setTimeout(tick, 1000/BOT_FPS);
console.log(`Connected as player ${bot.me.id}`);
} else {
console.error("Received bogus-amogus message from server. Incorrect `Hello` message.", view)
bot.ws.close();
}
} else {
if (common.PlayersMovingHeaderStruct.verify(view)) {
const count = common.PlayersMovingHeaderStruct.count(view);
for (let i = 0; i < count; ++i) {
const playerView = new DataView(event.data, common.PlayersMovingHeaderStruct.size + i*common.PlayerStruct.size, common.PlayerStruct.size);
const id = common.PlayerStruct.id.read(playerView);
if (id === bot.me.id) {
bot.me.moving = common.PlayerStruct.moving.read(playerView);
bot.me.x = common.PlayerStruct.x.read(playerView);
bot.me.y = common.PlayerStruct.y.read(playerView);
}
}
}
}
})
function turn() {
if (bot.me !== undefined) {
const view = new DataView(new ArrayBuffer(common.AmmaMovingStruct.size));
common.AmmaMovingStruct.kind.write(view, common.MessageKind.AmmaMoving);
// Full stop
for (let direction = 0; direction < common.Direction.Count; ++direction) {
if ((bot.me.moving>>direction)&1) {
common.AmmaMovingStruct.direction.write(view, direction);
common.AmmaMovingStruct.start.write(view, 0);
bot.ws.send(view);
}
}
// New direction
const direction = Math.floor(Math.random()*common.Direction.Count);
bot.timeoutBeforeTurn = Math.random()*common.WORLD_WIDTH*0.5/common.PLAYER_SPEED;
// Sync
common.AmmaMovingStruct.direction.write(view, direction);
common.AmmaMovingStruct.start.write(view, 1);
bot.ws.send(view);
}
}
let previousTimestamp = 0;
function tick() {
const timestamp = performance.now();
const deltaTime = (timestamp - previousTimestamp)/1000;
previousTimestamp = timestamp;
if (bot.timeoutBeforeTurn !== undefined) {
bot.timeoutBeforeTurn -= deltaTime;
if (bot.timeoutBeforeTurn <= 0) turn();
}
if (bot.me !== undefined) {
common.updatePlayer(bot.me, deltaTime)
}
setTimeout(tick, Math.max(0, 1000/BOT_FPS - timestamp));
}
return bot
}
let bots: Array<Bot> = []
for (let i = 0; i < 200; ++i) bots.push(createBot())