Compare commits

..

2 commits

Author SHA1 Message Date
d37c6a5cc5
WIP sessions
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2019-09-13 17:56:05 +02:00
5daa94b9ad
Refactor draft options 2019-09-13 17:55:41 +02:00
2 changed files with 114 additions and 6 deletions

View file

@ -1,16 +1,87 @@
import { PackBuilder, Cube, DraftOptions } from "."; import { PackBuilder, Cube, DraftOptions } from ".";
import EventEmitter from "eventemitter3";
import { Card } from "@/mlpccg";
export class Session { export class Session {
private options: DraftOptions; private options: DraftOptions;
private factory: PackBuilder; private factory: PackBuilder;
private pod: SessionPlayer[];
private players: string[];
private pending: number[];
constructor(options: DraftOptions, factory: PackBuilder) { constructor(options: DraftOptions, factory: PackBuilder) {
this.options = options; this.options = options;
this.factory = factory; this.factory = factory;
this.players = [];
this.pending = [];
this.pod = new Array(options.players).fill(0).map((x, i) => {
const player = new SessionPlayer();
player.on("pick", this.picked.bind(this, i));
return player;
});
}
public start() {
// Figure out how many players there are vs spots to be filled
const spots = this.options.players;
const players = this.players.length;
if (players > spots) {
throw new Error("too many players in the pod");
}
if (players < 1) {
throw new Error("not enough players");
}
// Place players in the pod
switch (this.options.spacing) {
case "evenly":
const playerRatio = spots / players;
let i = 0;
for (const player of this.players) {
const pos = Math.floor(playerRatio * i);
this.pod[pos].name = name;
i += 1;
}
break;
case "randomly":
for (const player of this.players) {
while (true) {
const idx = Math.floor(Math.random() * spots);
if (!this.pod[idx].name) {
this.pod[idx].name = player;
break;
}
}
}
break;
}
//TODO
}
public get order(): string[] {
return this.pod.map(p => p.name || "bot");
}
private picked(playerIndex: number, card: string) {
if (!this.pending.includes(playerIndex)) {
// Uh oh.
throw new Error(
`unexpected pick: player #${playerIndex} already picked their card`
);
}
const idx = this.pending.indexOf(playerIndex);
this.pending.splice(idx, 1);
// Check if everyone picked their card
if (this.pending.length < 1) {
//TODO
//NEXT PACK
}
} }
static async create(options: DraftOptions): Promise<Session> { static async create(options: DraftOptions): Promise<Session> {
switch (options.type) { switch (options.source) {
case "set": { case "set": {
const factory = await PackBuilder.fromSet(options.set); const factory = await PackBuilder.fromSet(options.set);
return new Session(options, factory); return new Session(options, factory);
@ -24,6 +95,24 @@ export class Session {
} }
case "i8pcube": case "i8pcube":
throw new Error("not implemented"); throw new Error("not implemented");
default:
throw new Error("Unknown draft source");
} }
} }
} }
export class SessionPlayer extends EventEmitter {
public name?: string;
public currentPack?: Card[];
public next?: SessionPlayer;
public pick(card: string) {
if (!this.currentPack) {
throw new Error("no pack to pick from");
}
if (!this.currentPack.find(c => c.ID == card)) {
throw new Error("card not in available picks");
}
this.emit("pick", card);
}
}

View file

@ -20,27 +20,46 @@ export interface AlternateProvider {
} }
export interface SetDraftOptions { export interface SetDraftOptions {
type: "set"; source: "set";
set: string; set: string;
} }
export interface BlockDraftOptions { export interface BlockDraftOptions {
type: "block"; source: "block";
block: string; block: string;
} }
export interface CubeDraftOptions { export interface CubeDraftOptions {
type: "cube"; source: "cube";
url: string; url: string;
} }
export interface I8PCubeDraftOptions { export interface I8PCubeDraftOptions {
type: "i8pcube"; source: "i8pcube";
url: string; url: string;
} }
export type DraftOptions = export interface LimitedBoosterDraft {
type: "booster-draft";
packs: number;
}
export interface LimitedSealedDraft {
type: "sealed";
packs: number;
}
export type LimitedGameType = LimitedBoosterDraft | LimitedSealedDraft;
export type DraftType =
| SetDraftOptions | SetDraftOptions
| BlockDraftOptions | BlockDraftOptions
| CubeDraftOptions | CubeDraftOptions
| I8PCubeDraftOptions; | I8PCubeDraftOptions;
export interface SessionOptions {
players: number;
spacing: "evenly" | "randomly";
}
export type DraftOptions = SessionOptions & LimitedGameType & DraftType;