@codejoy/terminal-pet
Version:
A virtual pet that lives in your terminal and grows with your coding activity
353 lines (309 loc) ⢠8.03 kB
JavaScript
const chalk = require('chalk');
const boxen = require('boxen');
class PetDisplay {
static getPetArt(type, mood) {
const pets = {
cat: {
happy: `
/\\_/\\
( ^.^ )
> ^ < `,
sad: `
/\\_/\\
( ;.; )
> v < `,
hungry: `
/\\_/\\
( o.o )
> ~ < `,
tired: `
/\\_/\\
( -.-)zzz
> ^ < `,
sick: `
/\\_/\\
( x.x )
> ~ < `,
ecstatic: `
/\\_/\\
( ^o^ )
> ^ < `,
dead: `
/\\_/\\
( x.x )
> - <
RIP `,
neutral: `
/\\_/\\
( -.- )
> ^ < `
},
dog: {
happy: `
__
o-''|\_\_\_\_
\\_/ )
(_(_/-(_/ `,
sad: `
__
o-''|\_\_\_\_
\\_\\ )
(_(_/-(_/ `,
hungry: `
__
O-''|\_\_\_\_
\\_/ )
(_(_/-(_/ `,
tired: `
__
--''|\_\_\_\_
\\_/ )zzz
(_(_/-(_/ `,
sick: `
__
x-''|\_\_\_\_
\\_/ )
(_(_/-(_/ `,
ecstatic: `
__
O-''|\_\_\_\_
\\_O )
(_(_/-(_/ `,
dead: `
__
x-''|\_\_\_\_
\\_/ )
(_(_/-(_/
RIP `,
neutral: `
__
o-''|\_\_\_\_
\\_/ )
(_(_/-(_/ `
},
dragon: {
happy: `
/| /|
( :v: )
|(_)|
~~~|_|~~~ `,
sad: `
/| /|
( :(: )
|(_)|
~~~|_|~~~ `,
hungry: `
/| /|
( :O: )
|(_)|
~~~|_|~~~ `,
tired: `
/| /|
( :-: )zzz
|(_)|
~~~|_|~~~ `,
sick: `
/| /|
( :x: )
|(_)|
~~~|_|~~~ `,
ecstatic: `
/| /|
( :D: )
|(_)|
~~~|_|~~~ `,
dead: `
/| /|
( :x: )
|(_)|
~~~|_|~~~
RIP `,
neutral: `
/| /|
( :-: )
|(_)|
~~~|_|~~~ `
}
};
return pets[type] && pets[type][mood] ? pets[type][mood] : pets.cat.neutral;
}
static getMoodColor(mood) {
const colors = {
happy: 'green',
sad: 'blue',
hungry: 'yellow',
tired: 'gray',
sick: 'red',
ecstatic: 'magenta',
dead: 'black',
neutral: 'white'
};
return colors[mood] || 'white';
}
static getMoodEmoji(mood) {
const emojis = {
happy: 'š',
sad: 'š¢',
hungry: 'š½ļø',
tired: 'š“',
sick: 'š¤',
ecstatic: 'š¤©',
dead: 'š',
neutral: 'š'
};
return emojis[mood] || 'š';
}
static displayPet(pet) {
const art = this.getPetArt(pet.type, pet.mood);
const color = this.getMoodColor(pet.mood);
const emoji = this.getMoodEmoji(pet.mood);
const coloredArt = chalk[color](art);
const statusBars = pet.getStatusBar();
const info = pet.getInfo();
const status = `
${chalk.bold.cyan(pet.name)} the ${pet.type} ${emoji}
${chalk.gray('Level:')} ${chalk.yellow(pet.level)} ${chalk.gray('Age:')} ${chalk.yellow(pet.age)} days
${chalk.gray('Mood:')} ${chalk[color](pet.mood)} ${chalk.gray('Streak:')} ${chalk.green(pet.streak)} days
${chalk.red('Health:')} ${statusBars.health}
${chalk.yellow('Happiness:')} ${statusBars.happiness}
${chalk.blue('Hunger:')} ${statusBars.hunger}
${chalk.green('Energy:')} ${statusBars.energy}
${chalk.gray('Experience:')} ${pet.experience}/${pet.level * 100}
${chalk.gray('Total Commits:')} ${pet.totalCommits}
${chalk.gray('Max Streak:')} ${pet.maxStreak} days
`;
const petDisplay = coloredArt + '\n' + status;
return boxen(petDisplay, {
padding: 1,
margin: 1,
borderStyle: 'round',
borderColor: color
});
}
static displayStats(pet) {
const stats = pet.stats;
const achievements = pet.achievements;
const statsDisplay = `
${chalk.bold.cyan('š Coding Stats')}
${chalk.gray('Lines of Code:')} ${chalk.green(stats.linesOfCode)}
${chalk.gray('Bugs Fixed:')} ${chalk.red(stats.bugsFixed)}
${chalk.gray('Features Added:')} ${chalk.blue(stats.featuresAdded)}
${chalk.gray('Refactorings:')} ${chalk.yellow(stats.refactorings)}
${chalk.bold.cyan('š Achievements')} (${achievements.length})
${this.formatAchievements(achievements)}
`;
return boxen(statsDisplay, {
padding: 1,
margin: 1,
borderStyle: 'double',
borderColor: 'cyan'
});
}
static formatAchievements(achievements) {
const achievementNames = {
first_commit: 'š First Commit',
century: 'šÆ Century Club (100 commits)',
week_streak: 'š„ Week Warrior (7 day streak)',
month_streak: 'š Month Master (30 day streak)',
double_digits: 'š Double Digits (Level 10)',
half_century: 'šļø Half Century (Level 50)',
well_fed: 'š Well Fed',
pure_joy: 'š Pure Joy'
};
if (achievements.length === 0) {
return chalk.gray(' No achievements yet. Keep coding!');
}
return achievements
.map(achievement => ` ${achievementNames[achievement] || achievement}`)
.join('\n');
}
static displayHelp() {
const help = `
${chalk.bold.cyan('š¾ Terminal Pet Commands')}
${chalk.yellow('pet status')} - View your pet's current status
${chalk.yellow('pet feed')} - Feed your hungry pet
${chalk.yellow('pet play')} - Play with your pet (requires energy)
${chalk.yellow('pet sleep')} - Let your pet rest and recover
${chalk.yellow('pet stats')} - View detailed stats and achievements
${chalk.yellow('pet adopt')} - Adopt a new pet (resets current pet)
${chalk.yellow('pet help')} - Show this help message
${chalk.bold.green('š” Tips:')}
⢠Your pet grows stronger with every git commit!
⢠Keep your pet fed and happy for the best experience
⢠Maintain a coding streak to unlock achievements
⢠Different commit messages give different bonuses
⢠Your pet will get hungry and tired over time
${chalk.bold.red('ā ļø Warning:')}
If you don't take care of your pet, it might get sick or even die!
`;
return boxen(help, {
padding: 1,
margin: 1,
borderStyle: 'round',
borderColor: 'green'
});
}
static displayMessage(message, type = 'info') {
const colors = {
success: 'green',
error: 'red',
warning: 'yellow',
info: 'blue'
};
const icons = {
success: 'ā
',
error: 'ā',
warning: 'ā ļø',
info: 'ā¹ļø'
};
const color = colors[type] || 'white';
const icon = icons[type] || 'ā¹ļø';
return chalk[color](`${icon} ${message}`);
}
static displayLevelUp(pet) {
const celebration = `
š LEVEL UP! š
${chalk.bold.yellow(pet.name)} is now level ${chalk.bold.green(pet.level)}!
${chalk.green('⨠Your pet feels amazing!')}
${chalk.green('ā¤ļø Health fully restored!')}
${chalk.green('š Happiness increased!')}
`;
return boxen(celebration, {
padding: 1,
margin: 1,
borderStyle: 'double',
borderColor: 'yellow'
});
}
static displayNewAchievements(achievements) {
if (achievements.length === 0) return '';
const celebration = `
š NEW ACHIEVEMENT${achievements.length > 1 ? 'S' : ''}! š
${this.formatAchievements(achievements)}
`;
return boxen(celebration, {
padding: 1,
margin: 1,
borderStyle: 'double',
borderColor: 'magenta'
});
}
static displayAdoption(petTypes) {
const types = petTypes.map((type, index) =>
`${chalk.yellow(index + 1)}. ${chalk.green(type)} ${this.getPetArt(type, 'happy').split('\n')[1] || 'š¾'}`
).join('\n');
const adoption = `
${chalk.bold.cyan('š Pet Adoption Center')}
Choose your new companion:
${types}
${chalk.gray('Each pet type has unique personality traits!')}
`;
return boxen(adoption, {
padding: 1,
margin: 1,
borderStyle: 'round',
borderColor: 'cyan'
});
}
}
module.exports = PetDisplay;