Compare commits
2 commits
5688e499fc
...
d37c6a5cc5
Author | SHA1 | Date | |
---|---|---|---|
d37c6a5cc5 | |||
5daa94b9ad |
2 changed files with 114 additions and 6 deletions
|
@ -1,16 +1,87 @@
|
|||
import { PackBuilder, Cube, DraftOptions } from ".";
|
||||
import EventEmitter from "eventemitter3";
|
||||
import { Card } from "@/mlpccg";
|
||||
|
||||
export class Session {
|
||||
private options: DraftOptions;
|
||||
private factory: PackBuilder;
|
||||
private pod: SessionPlayer[];
|
||||
private players: string[];
|
||||
private pending: number[];
|
||||
|
||||
constructor(options: DraftOptions, factory: PackBuilder) {
|
||||
this.options = options;
|
||||
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> {
|
||||
switch (options.type) {
|
||||
switch (options.source) {
|
||||
case "set": {
|
||||
const factory = await PackBuilder.fromSet(options.set);
|
||||
return new Session(options, factory);
|
||||
|
@ -24,6 +95,24 @@ export class Session {
|
|||
}
|
||||
case "i8pcube":
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,27 +20,46 @@ export interface AlternateProvider {
|
|||
}
|
||||
|
||||
export interface SetDraftOptions {
|
||||
type: "set";
|
||||
source: "set";
|
||||
set: string;
|
||||
}
|
||||
|
||||
export interface BlockDraftOptions {
|
||||
type: "block";
|
||||
source: "block";
|
||||
block: string;
|
||||
}
|
||||
|
||||
export interface CubeDraftOptions {
|
||||
type: "cube";
|
||||
source: "cube";
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface I8PCubeDraftOptions {
|
||||
type: "i8pcube";
|
||||
source: "i8pcube";
|
||||
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
|
||||
| BlockDraftOptions
|
||||
| CubeDraftOptions
|
||||
| I8PCubeDraftOptions;
|
||||
|
||||
export interface SessionOptions {
|
||||
players: number;
|
||||
spacing: "evenly" | "randomly";
|
||||
}
|
||||
|
||||
export type DraftOptions = SessionOptions & LimitedGameType & DraftType;
|
||||
|
|
Loading…
Reference in a new issue