This repository has been archived by the owner on Nov 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
impl.ts
115 lines (103 loc) · 3.06 KB
/
impl.ts
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
110
111
112
113
114
115
import { find, findIndex, map, propEq, } from 'ramda';
import { Methods, Context } from "./.hathora/methods";
import { Response } from "../api/base";
import {
EngineUser,
EngineState,
UserId,
IInitializeRequest,
IJoinRequest,
IMoveRequest,
EngineSol,
} from "../api/types";
import {
reducer, initialState, GameState
} from 'dark-forest-game';
import { Sol } from 'dark-forest-game/dist/types';
type InternalUser = {
id: UserId
name: string
picture: string
color: string
}
type InternalState = {
users: InternalUser[]
game: GameState
}
const colors = [
'#fbb4ae',
'#b3cde3',
'#ccebc5',
'#decbe4',
'#fed9a6',
'#ffffcc',
'#e5d8bd',
'#fddaec',
]
export class Impl implements Methods<InternalState> {
initialize(ctx: Context, request: IInitializeRequest): InternalState {
return {
users: [],
game: initialState
}
}
join(state: InternalState, userId: UserId, ctx: Context, request: IJoinRequest): Response {
const { picture, name } = request
const foundPlayerIndex = findIndex(propEq(userId, 'id'), state.users)
if(foundPlayerIndex !== -1)
return Response.error(`Already joined as player ${foundPlayerIndex}`);
if(state.users.length === 12)
return Response.error(`Already have maximum ${state.users.length} players`);
state.users.push({ id: userId, name, picture, color: colors[state.users.length] })
return Response.ok()
}
move(state: InternalState, userId: UserId, ctx: Context, request: IMoveRequest): Response {
const player = findIndex( (u) => u.id === userId, state.users)
if(player === -1) {
return Response.error('User is not a player of this game.')
}
const params = [ `${ctx.time}`, `${player}`, ...request.command.split(/\s+/) ]
const nextGame = reducer(params)(state.game)
if(nextGame === undefined) {
return Response.error(`ERROR ${params.join(' ')}`)
}
state.game = nextGame
return Response.ok()
}
getUserState(state: InternalState, userId: UserId): EngineState {
const users: EngineUser[] = map<InternalUser, EngineUser>(
(iu: InternalUser): EngineUser => {
const foundIndex = findIndex(u => u.id === userId, state.users)
return {
...iu,
index: foundIndex !== -1 ? foundIndex : undefined
}
}
,state.users)
const me = find(u => u.id === userId, users)
return {
users,
me,
sols: map<Sol, EngineSol>(
(sol: Sol) => {
if(me && me?.index === sol.owner) return sol
return {
owner: sol.owner,
path: []
}
},
state.game.sols
),
transits: state.game.transits.filter(
(transit) => me && me?.index === state?.game?.sols?.[transit.source]?.owner
),
}
}
onTick(state: InternalState, ctx: Context, timeDelta: number): void {
if(state.game === initialState) return
if(state.users.length === 0) return
const params = [`${ctx.time}`, '0', 'TICK']
const nextGame = reducer(params)(state.game)
if(nextGame !== undefined) state.game = nextGame
}
}