Skip to content

Commit

Permalink
feat: implement mock gameplay look and lotta helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
golota60 committed May 14, 2022
1 parent 3da7e3c commit 6da7016
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 20 deletions.
17 changes: 16 additions & 1 deletion ideas.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,19 @@
- save profiles and saves overall with serialization and stuff
- load saves via args with process.argv
- release process should be fleshed out prolly
- suspend(ctrl + z )/unsuspend(fg)
- suspend(ctrl + z )/unsuspend(fg)
- debug mode?(with debug flag)
- extensions/plugins? - liek a json with all the things u can buy and how they work
- replacable infrastructure names
- help on delete click
- should the game be time-based or tick based? go with tick for now, this allows us for speeding up the game easily
- app name/theme? maybe multiple themes that can be selected via a flag?
- hackerclicker? with infra based around computers or hacking - this can work as an mvp

potential upgrades

- click upgrades

- one click worth more

- infrastructure
9 changes: 9 additions & 0 deletions src/helpers/gameplay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface GameState {
mode: 'main' | 'shop';
}

export const initGameState: GameState = {
mode: 'main',
};

const changeGameState = (gameState: GameState) => {};
4 changes: 0 additions & 4 deletions src/helpers/input.ts

This file was deleted.

79 changes: 79 additions & 0 deletions src/helpers/io.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
export const handleGracefulExit = () => {
console.log('\nInterrupt signal detected! Closing gracefully...');
process.exit();
};

/**
* Add spaces and returns provided word with specified length
* @param {string} string
* @param {number} lengthToMatch
*
* @returns {string}
*/
const addSpacesToMatchLength = (string: string, lengthToMatch: number) => {
if (string.length >= lengthToMatch) return string;
const lengthDiff = lengthToMatch - string.length;
return `${string}${new Array(lengthDiff).fill(' ').join('')}`;
};

/**
* Taken almost literally from:
* https://github.com/golota60/yayfetch/blob/c64b3c83b56d94189203c148934ca23d9919da4f/src/helpers/helpers.ts#L188
*
* Used to equalize to the longest arg in an array by adding spaces, like this
* @param {string[]} stringArr[] - array of strings to equalize
* @param {number} lineOffset - the number of additional spaces at the end of strings
*
* @returns {string[]}
*
* @example
* [ [
* 'Michelangelo', 'Michelangelo',
* 'Michael', => 'Michael ',
* 'Tony' 'Tony ',
* ] ]
*
*/
export const equalizeStringArray = (
stringArr: Array<string>,
lineOffset = 0
) => {
const longestArgLength = stringArr.reduce((acc, curr) => {
const length = curr.length;
return length > acc ? length : acc;
}, 0);
return stringArr.map((line) => {
if (line.length < longestArgLength + lineOffset) {
return addSpacesToMatchLength(line, longestArgLength + lineOffset);
}
return line;
});
};

/**
* Get an object to pretty print an object(0/1 level deep)
*
* @param {object} obj - object to return ready to be pretty printed
* @param {string} keyToLog - the key of the value to be pretty printed. If not provided will attempt to use value itself as a string.
*
* @returns {string}
*/
export const getPrettyPrintableObject = (
obj: Record<string, Record<string, any> | string>, // obj: {key: {keyToLog: val}}
keyToLog?: string
) => {
const normalizedKeys = equalizeStringArray(Object.keys(obj), 1);
const normalizedValues = equalizeStringArray(
Object.values(obj).map((e) =>
keyToLog && typeof e !== 'string' ? e[keyToLog] : e
) as Array<string>
);

// stitch those badboys together
let stitched = '';
for (let i = 0; i < normalizedKeys.length; i++) {
stitched = `${stitched}
${[normalizedKeys[i]]}: ${normalizedValues[i]}`;
}
return stitched;
};
52 changes: 52 additions & 0 deletions src/helpers/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//TODO: convert those to funs which load save states when that is implemented

// click upgrades
export const initialAbilities = {
'nano-skill': {
value: 0,
desc: 'Your nano editor skills',
},
'emacs-skill': {
value: 0,
desc: 'Your emacs editor skills',
},
'vim-skill': {
value: 0,
desc: 'Your vim editor skills',
},
};

// infrastructure upgrades(money over time)
export const initialInfra = {
hackers: {
value: 0,
desc: 'Other hackers working for you',
cost: 20,
// resolver: (money: number) => {

// }
},
'debian-linux-instances': {
value: 0,
desc: 'Your Debian linux instances',
cost: 100,
},
botnets: {
value: 0,
desc: 'Botnets you control',
cost: 200,
},
'arch-linux-instances': {
value: 0,
desc: 'Your Arch linux instances(you use arch btw)',
cost: 500,
},
};

//you
export const player = {
abilities: initialAbilities,
infrastructure: initialInfra,
moneyPerTick: 0, //todo: resove overlap with abilities
moneyPerClick: 0, //todo: resove overlap with infra
};
61 changes: 46 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,71 @@
import process from 'process';
import readline from 'readline';
import logUpdate from 'log-update';
import { handleGracefulExit } from './helpers/input';
import { getPrettyPrintableObject, handleGracefulExit } from './helpers/io.js';
import { initialInfra } from './helpers/setup.js';
import { initGameState } from './helpers/gameplay.js';

const mainKeyName = 'space';
const shopButton = 's';
//todo: load this when implementing saving
let gameState = initGameState;

console.log('app ready');
let stdin = process.stdin;
readline.emitKeypressEvents(stdin);
stdin.setRawMode(true);
stdin.resume();
// stdin.setEncoding('utf-8');
stdin.setEncoding('utf-8');

console.log(`The game is on! Click "${mainKeyName}" to start earning bobux\n`);

let money = 0;
let currKey: string;
let debug: Record<string, any>;
stdin.on('keypress', function (key, a) {
const { sequence, name, ctrl, meta, shift } = a;
currKey = name;
debug = a;

const ctrlC = '\x03';
const ctrlX = '\x18';
const ctrlZ = '\x1A';
if (name === mainKeyName) {
money += 1;
}
if (name === shopButton) {
gameState = { ...gameState, mode: 'shop' };
}

if (gameState.mode === 'shop') {
if (name === 'x') gameState = { ...gameState, mode: 'main' };
}

if (sequence === ctrlC) {
handleGracefulExit();
}

console.log(key, a);
});

const frames = ['-', '\\', '|', '/'];
let index = 0;

setInterval(() => {
const frame = frames[(index = ++index % frames.length)];

logUpdate(
`
♥♥
${frame} unicorns ${frame}
♥♥
`
Your infra: ${Object.entries(initialInfra).map(
([key, value]) => `${key}: ${value.value}`
)}
You pressed ${currKey} and you've got ${money} bobux
To open the shop, click the ${shopButton} button
${
gameState.mode === 'shop' &&
`
Here's the things you can buy:
${getPrettyPrintableObject(initialInfra, 'cost')}
Press 'x' to leave the shop
`
}
${JSON.stringify(debug)}`
);
}, 16);
}, 60);

0 comments on commit 6da7016

Please sign in to comment.