I should've stopped writing this 4.5 hours into writing it. I learned some but... at what cost? (sleep)
Created
November 22, 2022 11:45
-
-
Save zudsniper/dc3a13fb71c6189688f69ab6734c5bd4 to your computer and use it in GitHub Desktop.
I accidentally started writing example code and it just... went off the rails. This isn't for anything but it took 5 hours so here I guess
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* -------gaming.ts-------- */ | |
/* author: zudsniper@github */ | |
const {IActiveGamer, IDonatorPerks} = require('./gamingInterfaces'); | |
export public enum GameClass { //Numeric enums initialize at 1! keep that in mind. | |
SCOUT = "scout", | |
SOLDIER = "soldier", | |
PYRO = "pyro", | |
DEMOMAN = "demo", | |
HEAVYWEAPONS = "heavy", | |
ENGINEER = "engi", | |
MEDIC = "medic", | |
SNIPER = "sniper", | |
SPY = "spy", | |
NONE = "spectator or smthn" | |
} | |
/** | |
* Helpful reverse-mapping function for string enums (autogenerated for numeric enums >:C) | |
* https://stackoverflow.com/a/48945109/5768559 | |
*/ | |
export let reverseGameClass = new Map<string, GameClass>(); | |
Object.keys(GameClass).forEach((mode: GameClass) => { | |
const modeValue: string = GameClass[<any>mode]; | |
reverseClass.set(modeValue, mode); | |
}); | |
export class ClassProperties extends Map<string, string | number> { | |
private gameClasses: Set<GameClass>; | |
private propList: Record<string, string | number>[]; | |
constructor(clss: gameClass) { | |
setClass(clss); | |
propList = []; | |
// propActions = []; | |
} | |
constructor(...gameClasses: gameClass[]) { | |
setClasses(gameClasses); | |
propList = []; | |
// propActions = []; | |
} | |
/** | |
* this is called a convenience function -- it's unnecessary, but makes the code clearer and is helpful when its called for. | |
*/ | |
setClass(clss: GameClass) { | |
gameClasses = new Set<GameClass>(); | |
gameClasses.add(clss); | |
} | |
setClasses(...classes: GameClass[]) { | |
gameClasses = setClasses(classes); | |
} | |
setClasses(classes: GameClass[]) { | |
gameClasses = new Set<GameClass>(classes); | |
} | |
//setPropList(propList: Record<string, string | number>[]); | |
//setPropList(mainPropVal: Record<string, string | number>, ...morePropVals: Record<string, string | number>[]); | |
addClass(clss: GameClass) { | |
gameClasses.add(clss); | |
} | |
removeClass(clss: GameClass) { | |
gameClasses.delete(clss); | |
} | |
isClassValid(clss: GameClass): boolean { | |
return gameClasses.has(clss); | |
} | |
setProp(propAndVal: Record<string, string | number>) { | |
propList.add(propAndVal); | |
} | |
unsetProp(propAndVal: Record<string, string | number>) { | |
propList.delete(propAndVal); | |
} | |
/** | |
* Reload the map object which this is class is an abstraction of with the current propList. | |
*/ | |
public reload() { | |
setParamMap(); | |
} | |
private setParamMap() { | |
propList.forEach( | |
(obj: Record<string, string | number>) => { | |
set(<string>obj.key, (obj.val typeof string) ? <string>obj.val : <number>obj.val); // this is how u cast in typescript... cool | |
}); | |
} | |
} | |
export class Score { | |
private name: string; | |
private kills: number; | |
private deaths: number; | |
protected perks!: IDonatorPerks; // ask about this '!' or i wont tell you what it does (hint: its boring!) | |
constructor(name: string, k: number, d: number) { | |
this.name = name; | |
kills = k; | |
deaths = d; | |
} | |
/** | |
* Return the kill death ratio for this score, and set the variables accordingly. To the nearest thousanth | |
* Returns AFTER new values are set. | |
*/ | |
public getKDR(kills: number, deaths: number): number { | |
this.kills = kills; | |
this.deaths = deaths; | |
return getKDR(); | |
} | |
/** | |
* Return the kill death ratio for this score, to the nearest thousanth. | |
*/ | |
public getKDR(): number { | |
return (kills / deaths).toFixed(3); | |
} | |
/* getters & setters, tostring, and overrides */ | |
public getName(): string { | |
return name; | |
} | |
public getKills(): number { | |
return kills; | |
} | |
public getDeaths(): number { | |
return deaths; | |
} | |
public getPerks(): IDonatorPerks { | |
return perks; | |
} | |
public setName(name: string) { | |
this.name = name; | |
} | |
public setKills(kills: number) { | |
this.kills = kills; | |
} | |
public setDeaths(deaths: number) { | |
this.deaths = deaths; | |
} | |
public setDonationPerks(perks: IDonatorPerks) { | |
this.perks = perks; | |
} | |
public addKills(addedkills: number) { | |
this.kills += addedkills; | |
} | |
public addDeaths(addedDeaths: number) { | |
this.deaths += addedDeaths; | |
} | |
public toString(): string { | |
const donoMsg: string = (perks) ? "Donator! thank you C:\n\n" : ""; | |
return donoMsg + "Score\n kills: " + kills + "\n deaths: " + deaths + "\nKDR: " + getKDR(); | |
} | |
} | |
export class MedicScore extends Score { | |
private ubers; | |
private healing; | |
constructor(name: string, kills: number, deaths: number) { | |
super(name, kills, deaths); | |
this.ubers = 0; | |
this.healing = 0; | |
} | |
constructor(name: string, kills: number, deaths: number, ubers: number, healing: number) { | |
super(name, kills, deaths); //call my parent class constructor to define these values | |
this.ubers = ubers; //define my new ones myself | |
this.healing = healing; | |
} | |
/* getters & setters, tostring, and overrides */ | |
public getHeals(): number { | |
return healing; | |
} | |
public getUbers(): number { | |
return ubers; | |
} | |
public setHeals(healing: number) { | |
this.healing = healing; | |
} | |
public setUbers(ubers: number) { | |
this.ubers = ubers; | |
} | |
public toString(): string { | |
const donoMsg: string = (perks) ? "Donator! thank you C:\n\n" : ""; // you can only access `perks` in this context because it is of access type protected. | |
// This time we DON'T just call our super.toString() & add because we want to modify the order things are output. | |
return donoMsg + name + "\n kills: " + kills + "\n deaths: " + deaths + "\n heals: " + healing + "\n ubers: " + ubers + "\nKDR: " + getKDR(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* -------gamingInterfaces.ts-------- */ | |
/* author: zudsniper@github *sigh* */ | |
export public interface IActiveGamer { //public is implied here & unnecessary (and it is also unnecessary throughout this document) | |
isGaming(): boolean; | |
} | |
export interface IDonatorPerks { //many optional parameters | |
tier: number; | |
perk?: { | |
above: IDonatorPerks, // lol this probably makes so much sense | |
below: IDonatorPerks | |
}, | |
prefix?: { | |
text: string, | |
colorHex: string | |
}, | |
priorityConnect?: boolean; | |
joinPriority?: number; | |
// ... more function headers, BUT NOT IMPLEMENTATIONS | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* -------runner.ts-------- */ | |
/* author: zudsniper@github */ | |
// this is CommonJS syntax, which uses the 'require' keyword. | |
const {IDonatorPerks} = require('./gamingInterfaces'); | |
const {GameClass, reverseGameClass, ClassProperties, Score, MedicScore} = require('./gaming'); | |
const {TF2Gamer} = require('./tf2gamer'); | |
let players: TF2Gamer[] = []; | |
players.add(new TF2Gamer("zod", 0, 69, GameClass.PYRO)); | |
players.add(new TF2Gamer("meh", 99999, 0, GameClass.MEDIC, [{healing: 4}, {ubers: 10291}]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* -------tf2gamer.ts-------- */ | |
/* author: zudsniper@github */ | |
// this is EJS (import) syntax for modules | |
import {IActiveGamer} from './gamingInterfaces'; | |
import * from './gaming'; | |
let CLASSES_WITH_EXTRA_PARAMS: Set<GameClass> = new Set<GameClass>(); | |
CLASSES_WITH_EXTRA_PARAMS.add(GameClass.MEDIC); | |
export class TF2Gamer implements IActiveGamer { | |
private score: Score; | |
private clss: GameClass; | |
private properties: ClassProperties; | |
private failure: boolean; | |
constructor(name: string, kills: number, deaths: number) { | |
this.score = new Score(name, kills, deaths); | |
this.clss = GameClass.NONE; | |
this.failure = true; | |
this.properties = null; //this is ok | |
} | |
constructor(name: string, kills: number, deaths: number, clss: GameClass | string, ...classVarParams: Record<string, string | number>[]) { | |
if(!(clss typeof GameClass)) { | |
this.clss = reverseGameClass.get(clss); | |
} else { | |
this.clss = clss; | |
} | |
if(!clss) { | |
this.clss = GameClass.NONE; | |
} | |
if(classVarParams !== undefined && classVarParams.length() > 0 && CLASSES_WITH_EXTRA_PARAMS.has(this.clss)) { | |
this.properties = new ClassProperties(clss); | |
classVarParams.forEach( (param: Record<string, string | number>) => { | |
this.properties.setProp(param); | |
}); | |
this.properties.reload(); | |
} | |
this.score = new Score(name, kills, deaths); | |
this.failure = true; | |
// TODO: THIS IS A SHITTY HARDCODE BUT I CANT ANYMORE THIS IS SUPPOSED TO BE AN EXAMPLE WTF | |
if(GameClass === GameClass.MEDIC) { | |
this.score = new MedicScore(name, kills, deaths); | |
score.setHealing(properties.get('healing')); | |
score.setUbers(properties.get('ubers')); | |
} | |
} | |
constructor(name: string, kills: number, deaths: number, props: ClassProperties) { | |
let extraParamMap = undefined; //don't load unless we have to | |
if(!(clss typeof GameClass)) { | |
this.clss = reverseGameClass.get(clss); | |
} else { | |
this.clss = clss; | |
} | |
if(!clss) { | |
this.clss = GameClass.NONE; | |
} | |
this.properties = props; | |
this.score = new Score(name, kills, deaths); | |
this.failure = true; | |
} | |
/* getters & setters, tostring, and overrides */ | |
override isGaming(): boolean { | |
return score.getKDR() > 1; | |
} | |
/* private (internal) helper functions */ | |
// @deprecated, never used | |
private getExtraParamMap(arr: Record<string, string | number>[]): Map<string, string | number> { | |
return arr.reduce((mapAccumulator, obj) => { | |
mapAccumulator.set(obj.key, obj.val); | |
return mapAccumulator; | |
}, new Map<string, string | number>()); | |
} | |
/* TODO: finish this with the appropriate getter & setters (for practice if you want, im not your professor) */ | |
public isFailure(): boolean { | |
return true; //no need to check anything really | |
} | |
public getScore(): Score { //DO NOT INCLUDE a setter for this -- it is intended to be created within the instantiation process via a constructor. | |
return score; | |
} | |
public getName(): string { //no need to store name value again if we're storing it with our Score object | |
return score.getName(); | |
} | |
// ... | |
// ... | |
public toString(): string { | |
return "?????"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment