Skip to content

Instantly share code, notes, and snippets.

@zudsniper
Created November 22, 2022 11:45
Show Gist options
  • Save zudsniper/dc3a13fb71c6189688f69ab6734c5bd4 to your computer and use it in GitHub Desktop.
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

trashdemo.ts

ABSOLUTELY NOT worth reading


I should've stopped writing this 4.5 hours into writing it. I learned some but... at what cost? (sleep)

/* -------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();
}
}
/* -------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
}
/* -------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}]);
/* -------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