Skip to content

Instantly share code, notes, and snippets.

@mambax
Created April 12, 2020 15:51
Show Gist options
  • Save mambax/6f244ac2140dbf030b32123c4e31f4ae to your computer and use it in GitHub Desktop.
Save mambax/6f244ac2140dbf030b32123c4e31f4ae to your computer and use it in GitHub Desktop.
import { Command } from '@colyseus/command';
import { Schema, type } from '@colyseus/schema/lib';
import debug0 from 'debug';
import { nanoid } from 'nanoid';
import { OnPlayColoredCardCommand } from '../../../server/src/frontiq/frontiq.commands';
import { FrontiqPlayer } from './frontiq.player';
import { FrontiqState } from './frontiq.state';
const debug = debug0('frontiq:card');
export enum ColorType {
RED = 'RED',
BLUE = 'BLUE',
GREEN = 'GREEN',
YELLOW = 'YELLOW'
}
export enum ColoredCardType {
SECOND_CHANCE = 'SECOND_CHANCE',
GIFT = 'GIFT',
SKIP = 'SKIP',
EXCHANGE = 'EXCHANGE'
}
export enum SpecialCardType {
FANTASTIC = 'FANTASTIC',
FANTASTIC_FOUR = 'FANTASTIC_FOUR',
EQUALITY = 'EQUALITY',
COUNTERATTACK = 'COUNTERATTACK',
NICE_TRY = 'NICE_TRY',
FUCK_YOU = 'FUCK_YOU'
}
export enum CardType {
COLOR = 'COLOR',
BLACK = 'BLACK',
COLOR_SPECIAL = 'COLOR_SPECIAL',
SPECIAL = 'SPECIAL'
}
export abstract class FrontiqCard extends Schema {
@type('string')
cardType: CardType;
@type('number')
scoreValue: number;
@type('string')
uid: string;
@type('boolean')
canBeExchanged: boolean;
@type('boolean')
isIntermediate: boolean;
constructor(cT: CardType, scoreValue: number) {
super();
this.cardType = cT;
this.uid = nanoid(8);
this.scoreValue = scoreValue;
this.canBeExchanged = true;
this.isIntermediate = false;
}
abstract generatePlay(sessionId: string, playingCard: FrontiqCard, state: FrontiqState): Command[];
}
export class ColorCard extends FrontiqCard {
@type('string')
color: ColorType
@type('number')
value: number;
constructor(color: ColorType, value: number) {
super(CardType.COLOR, value);
this.color = color;
this.value = value;
}
generatePlay(sessionId: string, playingCard: ColorCard, state: FrontiqState): Command[] {
const topCard: FrontiqCard = state.playedCards[state.playedCards.length - 1];
const player: FrontiqPlayer = state.players[sessionId];
debug(`Player ${sessionId} is trying to play\n${JSON.stringify(playingCard)}\non to\n${JSON.stringify(topCard)}`)
if (this.isValid(playingCard, topCard)) {
return [new OnPlayColoredCardCommand().setPayload({
sessionId,
player,
playedCard: this
})];
} else {
return [];
}
}
private isValid(playingCard: ColorCard, topCard: FrontiqCard) {
switch (topCard.cardType) {
case CardType.COLOR:
const colorCard = topCard as ColorCard;
if (playingCard.color === colorCard.color || playingCard.value === colorCard.value) {
debug(`VALID: Top card ${colorCard.color} / ${colorCard.value} matches playing card!`);
return true;
}
break;
case CardType.COLOR_SPECIAL:
const colorSpecialCard = topCard as ColorSpecialCard;
if (playingCard.color === colorSpecialCard.color) {
debug(`VALID: Top card ${colorSpecialCard.color} / ${colorSpecialCard.behaviour} matches playing card!`);
return true;
}
break;
case CardType.BLACK:
const blackCard = topCard as BlackCard;
if (playingCard.value === blackCard.value) {
debug(`VALID: Black card ${blackCard.value} matches playing card!`);
return true;
}
break;
case CardType.SPECIAL:
/* Here we need some serious state checking */
return true;
default:
debug(`Major fail, card type was not found ${topCard.cardType}.`);
}
debug(`NOT VALID: Can not play\n${JSON.stringify(playingCard)}\non to\n${JSON.stringify(topCard)}`)
return false;
}
}
export class ColorSpecialCard extends FrontiqCard {
@type('string')
color: string;
@type('string')
behaviour: ColoredCardType;
constructor(color: ColorType, behaviour: ColoredCardType) {
super(CardType.COLOR_SPECIAL, 7);
this.behaviour = behaviour;
this.color = color;
}
generatePlay(sessionId: string, playingCard: ColorSpecialCard, state: FrontiqState): Command[] {
// TODO: implementation missing
debug(`Implementation missing ColoredSpecialCard!`);
return [];
}
}
export class BlackCard extends FrontiqCard {
@type('number')
value: number;
constructor(value: number) {
super(CardType.BLACK, value);
this.value = value;
}
generatePlay(sessionId: string, playingCard: FrontiqCard, state: FrontiqState): Command[] {
// TODO: implementation missing
debug(`Implementation missing BlackCard!`);
return [];
}
}
export class SpecialCard extends FrontiqCard {
@type('string')
specialCardType: SpecialCardType;
constructor(cardType: SpecialCardType) {
super(CardType.SPECIAL, 7);
this.specialCardType = cardType;
if (cardType === SpecialCardType.FUCK_YOU) {
this.scoreValue = 42;
this.canBeExchanged = false;
}
if (cardType === SpecialCardType.COUNTERATTACK || cardType === SpecialCardType.NICE_TRY) {
this.isIntermediate = true;
}
}
generatePlay(sessionId: string, playingCard: FrontiqCard, state: FrontiqState): Command[] {
// TODO: implementation missing
debug(`Implementation missing SpecialCard!`);
return [];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment