Compare commits

...

6 Commits

Author SHA1 Message Date
lee2sman 256b79e01b mid-process integrating blessed library 2021-03-14 01:41:45 -05:00
lee2sman 76c8b6077d test programs along the way 2021-03-14 01:41:26 -05:00
lee2sman 0d2922e9c0 update devlog.md 2021-03-14 01:41:13 -05:00
lee2sman fe9b49da76 update RESOURCES.md 2021-03-14 01:41:04 -05:00
lee2sman e02cfaf2f9 update TODO.md 2021-03-14 01:40:55 -05:00
lee2sman ba905e1443 fixed basic execution order of terrain generator 2021-03-13 00:40:23 -05:00
15 changed files with 685 additions and 69 deletions

View File

@ -1,5 +1,7 @@
# Resources
[Toward Qualitative Procedural Generation - PDF](https://web.archive.org/web/20170610155631/http://www.ccgworkshop.org:80/2016/Johnson.pdf)
[emoji-toolkit emoji font](https://github.com/joypixels/emoji-toolkit)
[useful unicode for roguelikes](https://github.com/globalcitizen/zomia/blob/master/USEFUL-UNICODE.md)

20
TODO.md
View File

@ -1,22 +1,13 @@
# TODO
## Bugs
- [ ] i'm creating terrain but it's being overwritten (?) by old terrain file. fix.
## Roadmap
- [ ] instead of creating . for generic terrain, do like createItems and have it save array of objects which terrain symbol and x, y location instead. (buildings, plants, tombs, etc)
- [o] add more procedurally-generated things
- [X] tombstones
- [X] books
- [ ] signs?
- [ ] art?
- [ ] curses-like screendraw system
- [X] curses-like screendraw system
- [ ] ability to pray / sing / meditate / wonder / think / dance?
- [o]
- [X] fixed number of moves limit before you *fall asleep*
- [ ] background of tiles becomes gray (twilight), then black (nightfall) before you fall asleep?
- [ ] create, save and load all monsters,
- [ ] create, save and load terrain positions
- [X] generate descriptions for items that i'm happy with
- [ ] ability to drop items
- [ ] programmable robot pet? - (you feed it logo commands to retrieve things?)
- [o] check collision with item, read out message
@ -25,12 +16,19 @@
- [ ] help system
## Completed
- [X] generate descriptions for items that i'm happy with
- [X] inventory file to save inventory
- [X] save date and check for today's date (if so, you cannot move, but can you do something else?)
- [X] load items from disk
- [X] what's the game mechanic / concept? should be one clear concept
- [X] save item positions,
- [X] add more procedurally-generated things
- [X] tombstones
- [X] books
- [X] create, save and load terrain positions
- [X] save player position,
## CLOSED Issues
- [X] i'm creating terrain but it's being overwritten (?) by old terrain file. fix.
- [X] not all emoji are same width so different size players cause map row to get off of lined up grid

View File

@ -4,6 +4,59 @@ lee2sman
# Devlog
## Day 7
Hard to believe it's my last day. Looking forward to finishing and having something playable!
With some sleep and brunch in me, I feel refreshed. First step, I do some initial tests, creating little example files with blessed and seems to render out okay. I test out loading in a file and render to screen. Great, now I can integrate this back into my main program.
I decided I was ready to try replacing emojis with unicode from the Useful Unicode page. I tried changing out each of my arrays of terrain or items or buildings, etc and creating ones of unicode instead of emjois. I finished this and tested and....crap... still doesn't align. I went through my code looking for errant emoji, and then realized I was using east asian extra wide latin characters and they seemed to be causing this mis-alignment, so I switched those out. I can't say I love the aesthetic of the unicode exactly either. I guess would have been better to change fonts perhaps.
Strangely, the smiley player character seems too wide, though it doesn't throw off the grid. One of the houses (hut) seems to as well. I'll switch those out.
Okay, starting to integrate screen rendering via blessed. There are a number of bugs and I can't figure out a simple reset and redraw screen. Their example code and documentation leaves a lot to be desired. This program is overkill compared to curses! Anyway, let's see if I can wrap this up. I'm in the home stretch. Almost gave up a little while ago. Not even kidding. I thought I'd just abandon and say I failed to complete and try to get it done later, but no, I want to finish this. I've put in so many hours so far and I want people to try this out. Now that i'm getting the program to recognize directional keypresses in a gameloop i'm feeling a bit better, but still need to get a better handle on how the screen refresh -> draw works so I can wrap this up. Taking a little break to come back at it fresh.
Making a bookmark here to say if I can build a simple example blessed file that can identify the 4 cardinal direction keypresses with arrow keys and to move a little @ symbol around the screen, I should publish that (and possibly do a pull-request). I'd be doing quite a service for future node.js/roguelikers!
## Day 6
Did no work all day. It's now 11:55pm and I'm starting. LOL.
Well, my generator still makes me laugh...
```
🏛️: Great Pickle Camp
⛺: Embarrassed Cake Watering Hole
⛺: Fragile Actor Village
⛺: Nasty Company Village
🏚️: Toothsome Caption Camp
⛺: Typical Purpose Hideout
⛺: Cynical Credit House
⛺: Tranquil Knife Shack
```
First thing, fix the terrain generator. Ugh. Will report back. Goal is to get this working and switch to blessed (curses-like bindings) tonight.
Fixed terrain generator. Didn't take me that long.
Next step, looked into using blessed. I looked at some examples and played around with them. I tried changing colors of text, writing text to different lines, etc. That all went fine. Then I tried to load in a blank dungeon file and draw lines to the screen with blessed. That went okay. Then I tried to load in emojis. Darn, that didn't work. Emojis came out as ???? question marks. Time to abandon that.
[Useful Unicode](https://github.com/globalcitizen/zomia/blob/master/USEFUL-UNICODE.md/)
Ok, so next I tested loading an external savefile with unicode text as terrain. That seemed to render okay. I tried it in gnome-terminal, st and tilda terminal emulators and all seemed okay at loading all of these unicode, in monospaced.
Test unicode text:
```
...▒....྿྿྿....
...▙.......྿྿྿.
.┼..྿...☭ .....
...●/..፨....ᛍ..
```
Next step is to build blessed into my full program file. Not looking forward to this. Probably should have done this from the beginning. I should still think about if I want this to have the program run as the "message of the day" when booting up a terminal. That was my original idea at least.
## Day 5
Started at 11:30 and worked a few hours. Added random places/names, used a project-name-generator to get some honestly great (funny, silly) place-names generated.

262
dotd.js
View File

@ -3,6 +3,7 @@ const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const argv = yargs(hideBin(process.argv)).argv
const Charlatan = require('charlatan');
const blessed = require('blessed');
const fs = require("fs");
const generator = require("project-name-generator");
@ -18,8 +19,13 @@ const placesFile = ".places.txt";
const terrainFile = ".terrain.txt";
//globals
const width = 20;
const height = 5;
//blessed-specific, to write to screen
let screen, box;
let gameTitle = "Embarassed Cake Watering Hole";
// game vars
const width = 50;
const height = 8;
const movesInADay = 24;
let dungeon;
let roomItems = [];
@ -48,10 +54,10 @@ let parseArgs = () => {
createItems();
createBooks();
createPlaces();
createGraves();
createGraves();
} else {
loadDungeon();
loadTerrain();
//loadDungeon();
loadItems();
loadPlaces();
loadPlayer();
@ -151,7 +157,7 @@ let movePlayer = () => {
}
}
} else { //you are asleep
console.log("you've drifted off asleep for the night and will wake tomorrow refreshed.");
console.log("You've drifted off asleep for the night and will wake tomorrow refreshed.");
//player.avatar = '😴'
}
}
@ -203,20 +209,17 @@ let grab = () => {
let createDungeon = () => {
dungeon = Array.from(Array(height), () => new Array(width))
for (let y = 0; y < height; y++){
for (let x = 0; x < width; x++){
dungeon[y][x] = ".";
}
}
}
//---------------CREATE PLAYER ----------------------------------
let createPlayer = () => {
const avatars = ['👳','👶','🧛','🕵','👲','🧕','👵','👧','🧔','👸','🤠','']
//const avatars = ['👳','👶','🧛','🕵','👲','🧕','👵','👧','🧔','👸','🤠','']
//const avatars = ['☺','☺'];
let chooseAvatar = Math.floor(Math.random() * avatars.length);
//let chooseAvatar = Math.floor(Math.random() * avatars.length);
player.avatar = avatars[chooseAvatar];
//player.avatar = avatars[chooseAvatar];
player.avatar = '@';
player.life = movesInADay;
@ -239,7 +242,9 @@ let createItems = () => {
let currentItemsInRoom = [];
for (let i = 0; i < numToSpawn; i++){
const items = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,.:;!?"'`^~ ̄_&#%+-*=<>()[]{}⦅⦆|¦/\¬$£¢₩¥".split("");
//east asian wide unicode
//const items = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,.:;!?"'`^~ ̄_&#%+-*=<>()[]{}⦅⦆|¦/\¬$£¢₩¥".split("");
const items = "123456789ABCDEFHIJKLMNOPQRSTUVWXYZabcdefghijklmonqrsntuvwxyz,.:!?\"'`^~_&#%+-*=<>(){}/\$".split("");
//make sure it wasn't chosen previously in this board
do {
@ -279,7 +284,8 @@ let createBooks = () => {
let numToSpawn = Math.round(Math.random() * 2)
for (let i = 0; i < numToSpawn; i++){
const items = ["📗","📕","📘","📙","📒","📓","📔"];
//const items = ["📗","📕","📘","📙","📒","📓","📔"];
const items = ['⎅','⏍','◫'];
whichItem = Math.floor(Math.random()*items.length);
@ -337,7 +343,8 @@ let createPlaces = () => {
for (let i = 0; i < numToSpawn; i++){
const buildings = ['🏛️','⛺','🏚️','⛩️','🗿']
//const buildings = ['🏛️','⛺','🏚️','⛩️','🗿']
const buildings = ['⌂','⏏','☖','☗']
const placeTypes = ['Village','Village','Village','House','House','Market','Market','Market','Crossroads','Place','Outpost','Trading Post','House','Shack','Meeting Place','Saloon','Watering Hole','Stall','Hideout','Cart','Camp','Camp','Camp','Camp','','','','Zone of Ill Repute']
let whichBuilding = buildings[Math.floor(Math.random()*3)];
@ -370,6 +377,8 @@ let createGraves = () => {
let name = Charlatan.Name.name();
let gravestones = ['✝','✟','☨','✞'];
let whichGravestone = choose(gravestones);
let prefix = ["Here lies","RIP","","","","Resting place of ","Beloved"]
let reason = ["Made an enemy","Wasn't afraid to be","Tried","Died while","Passed while performing","Tried out","Dissapeared investingating","Wandered off while looking for","Last seen","Loved","Adored","A lifelong fan of","Our favorite at","The best at","Always in our hearts","Keep","Always be","Always","Just","Tried","Couldn't stop","Only ever found","Died","Passed while","Couldn't stop","Forgot to try","Never stopped","We'll always think of you when we're","It's not the same"]
@ -378,7 +387,8 @@ let createGraves = () => {
places.push(
{
"name": epitaph,
"symbol": "⚰️",
// "symbol": "⚰️",
"symbol": whichGravestone,
"position":
{
"x":Math.floor(Math.random()*width),
@ -388,45 +398,8 @@ let createGraves = () => {
)
}
//-----------------PEOPLE----------------------------------------
let people =
[
{
"name": "wizard",
"emoji": "🧙",
"life": 3
},
{
"name": "woman",
"emoji": "🧝",
"life": 3
},
{
"name": "man",
"emoji": "🧔",
"life": 3
},
{
"name": "woman",
"emoji": "👵",
"life": 3
},
{
"name": "man",
"emoji": "👴",
"life": 3
},
{
"name": "person",
"emoji": "🧓",
"life": 3
}
]
//----------------create zone---------------
/*
let landscapes = ['🏔️','🌿','🌱','🌾','🌻','🌵']
let plants = ['🌹','🌺','🌻','🌼','🌷','🎋']
@ -434,6 +407,7 @@ let plants = ['🌹','🌺','🌻','🌼','🌷','🎋']
let shrines = ['⛩️','🗿']
let emojiitems = ['🍄','🌰','🦴','🧵','🧶','👓','🕶','🥽','👞','👟','🥾','🥿','👑','💼']
*/
let debug = () => {
//console.log(dungeon)
@ -453,8 +427,11 @@ let dungeonToStrings = () => {
let createTerrain = () => {
let forestTerrain = ['🎄', '🌳','🌲']
let plants = ['🌹','🌺','🌻','🌼','🌷','🎋','🍄','🌰','🌿','🌱','🌾','🏔️']
let forestTerrain = ['ᚠ','ᚡ','ᚴ','ᚵ','ᚶ','ᛉ','ᛘ','ᛠ'];
//let forestTerrain = ['🎄', '🌳','🌲']
let plants = ['ሥ','ሥ','ቂ','ቁ','ቄ','ቃ','ቅ','ቆ','ቇ','ቈ','ቊ','ቋ','ቌ','ቍ','ቜ','ቝ']
//let plants = ['🌹','🌺','🌻','🌼','🌷','🎋','🍄','🌰','🌿','🌱','🌾','🏔️']
//
for (let y = 0; y < height; y++){
for (let x = 0; x < width; x++){
@ -485,6 +462,18 @@ let createTerrain = () => {
let dungeonWithItemsToStrings = () => {
//start with dots
for (let y = 0; y < height; y++){
for (let x = 0; x < width; x++){
dungeon[y][x] = ".";
}
}
//specify terrain locations
for (let i = 0; i < terrain.length; i++){
dungeon[terrain[i].position.y][terrain[i].position.x] = terrain[i].symbol;
}
//specify item locations
for (let i = 0; i < roomItems.length; i++){
dungeon[roomItems[i].position.y][roomItems[i].position.x] = roomItems[i].symbol;
@ -561,7 +550,140 @@ let checkDay = () => {
}
}
//----------------------------SET UP BLESSED----------------------
let initBlessed = () => {
screen = blessed.screen({
smartCSR: true
});
screen.title = gameTitle;
// Create a box perfectly centered horizontally and vertically.
box = blessed.box({
top: 'center',
left: 'center',
width: '50%',
height: '50%',
content: "Welcome to "+gameTitle,
tags: true,
border: {
type: 'line'
},
style: {
fg: 'white',
bg: 'cyan',
border: {
fg: '#f0f0f0'
},
hover: {
bg: 'green'
}
}
});
// Append our box to the screen.
screen.append(box);
screen.key(['escape', 'q', 'C-c'], function(ch, key) {
return process.exit(0);
});
screen.key(['right', 'l'], function(ch, key) {
console.log('moved right');
player.position.x++;
loop();
});
screen.key(['left', 'h'], function(ch, key) {
console.log('moved left');
player.position.x--;
loop();
});
screen.key(['down', 'j'], function(ch, key) {
console.log('moved down');
player.position.y++;
loop();
});
screen.key(['up', 'k'], function(ch, key) {
player.position.y--;
console.log('moved up');
loop();
});
screen.render();
}
let keyHandler = () => {
// If box is focused, handle `enter`/`return` and give us some more content.
//
console.log('box.content: '+box.content);
//box.setContent('hello {red-fg}{green-bg}world{/}');
box.key('enter', function(ch, key) { //writes to screen, focus needed
for (let i = 0; i < dungeon.length; i++){
box.setLine(i, dungeon[i].join(''));
}
});
//box.content = "test test"; //writes to screen, no focus needed
screen.render();
}
let drawToBox = () => {
//start with dots
for (let y = 0; y < height; y++){
for (let x = 0; x < width; x++){
dungeon[y][x] = ".";
}
}
//specify terrain locations
for (let i = 0; i < terrain.length; i++){
dungeon[terrain[i].position.y][terrain[i].position.x] = terrain[i].symbol;
}
//specify item locations
for (let i = 0; i < roomItems.length; i++){
dungeon[roomItems[i].position.y][roomItems[i].position.x] = roomItems[i].symbol;
}
//specify places location
for (let i = 0; i < places.length; i++){
dungeon[places[i].position.y][places[i].position.x] = places[i].symbol;
}
//specify player location
dungeon[player.position.y][player.position.x] = player.avatar;
let dungeonStr = "";
for (let i = 0; i < height; i++){
dungeonStr+=(dungeon[i].join("")+"\n");
}
//return dungeonStr;
//
box.setContent(dungeonStr);
/*
for (let i = 0; i < dungeon.length; i++){
box.setLine(i, dungeonStr[i]);
}
*/
}
//--------------------------MAIN GAME LOOP-------------------------
let main = () => {
//----INIT
initBlessed();
checkDay();
parseArgs();
@ -572,8 +694,32 @@ let main = () => {
let dungeonWithItems = dungeonWithItemsToStrings();
drawDungeon(dungeonWithItems);
//keyHandler();
//debug();
//debug();
}
let loop = () => {
//
//Probably need to reload these things as you move
loadDungeon();
loadTerrain();
loadItems();
loadPlaces();
loadPlayer();
loadInventory();
grab();
movePlayer();
checkCollision();
//blessed
//
screen.realloc();
drawToBox();
screen.render();
}
main()

0
test/application.log Normal file
View File

71
test/basic-blessed.js Normal file
View File

@ -0,0 +1,71 @@
var blessed = require('blessed');
// Create a screen object.
var screen = blessed.screen({
smartCSR: true
});
screen.title = 'my window title';
// Create a box perfectly centered horizontally and vertically.
var box = blessed.box({
top: 'center',
left: 'center',
width: '50%',
height: '50%',
content: 'Hello {bold}world{/bold}!',
tags: true,
border: {
type: 'line'
},
style: {
fg: 'white',
bg: 'magenta',
border: {
fg: '#f0f0f0'
},
hover: {
bg: 'green'
}
}
});
// Append our box to the screen.
screen.append(box);
// Add a png icon to the box
var icon = blessed.image({
parent: box,
top: 0,
left: 0,
type: 'overlay',
width: 'shrink',
height: 'shrink',
file: __dirname + '/my-program-icon.png',
search: false
});
// If our box is clicked, change the content.
box.on('click', function(data) {
box.setContent('{center}Some different {red-fg}content{/red-fg}.{/center}');
screen.render();
});
// If box is focused, handle `enter`/`return` and give us some more content.
box.key('enter', function(ch, key) {
box.setContent('{right}Even different {black-fg}content{/black-fg}.{/right}\n');
box.setLine(1, 'bar');
box.insertLine(1, 'foo');
screen.render();
});
// Quit on Escape, q, or Control-C.
screen.key(['escape', 'q', 'C-c'], function(ch, key) {
return process.exit(0);
});
// Focus our element.
box.focus();
// Render the screen.
screen.render();

View File

@ -0,0 +1,67 @@
//source: https://recodes.co/being-blessed/
// Require the Blessed API.
var Blessed = require('blessed');
// Initialize the screen widget.
var screen = Blessed.screen({
// Example of optional settings:
smartCSR: true,
useBCE: true,
cursor: {
artificial: true,
blink: true,
shape: 'underline'
},
log: `${__dirname}/application.log`,
debug: true,
dockBorders: true
});
// Specify the title of the application.
screen.title = 'La pizza de Don Cangrejo.';
// Creating a textarea on the bottom of the screen.
var input = Blessed.textarea({
bottom: 0,
height: 3,
inputOnFocus: true,
padding: {
top: 1,
left: 2
},
style: {
fg: '#787878',
bg: '#454545',
focus: {
fg: '#f6f6f6',
bg: '#353535'
}
}
});
// Append the widget to the screen.
screen.append(input);
// Render the screen.
screen.render();
// Quit on `q`, or `Control-C` when the focus is on the screen.
screen.key(['q', 'C-c'], function(ch, key) {
process.exit(0);
});
// Focus on `escape` or `i` when focus is on the screen.
screen.key(['escape', 'i'], function() {
// Set the focus on the input.
input.focus();
});
// If box is focused, handle `Control+s`.
input.key('C-s', function(ch, key) {
var message = this.getValue();
// Send the message somehow.
this.clearValue();
screen.render();
});

19
test/create-graves.js Normal file
View File

@ -0,0 +1,19 @@
const fs = require('fs');
const Charlatan = require('charlatan');
let createGraves = () => {
//ingest verbs
verbs = fs.readFileSync("../.verbs.txt").toString().split("\n");
let name = Charlatan.Name.name();
let prefix = ["Here lies","RIP","","","","Resting place of ","Beloved"]
let reason = ["Made an enemy","Wasn't afraid to be","Tried","Died while","Passed while performing","Tried out","Dissapeared investingating","Wandered off while looking for","Last seen","Loved","Adored","A lifelong fan of","Our favorite at","The best at","Always in our hearts","Keep","Always be","Always","Just","Tried","Couldn't stop","Only ever found","Died","Passed while","Couldn't stop","Forgot to try","Never stopped","We'll always think of you when we're","It's not the same"]
let epitaph = prefix[Math.floor(Math.random() * prefix.length)] + " " + name +"\n"+reason[Math.floor(Math.random() * reason.length)]+" " + verbs[Math.floor(Math.random()*verbs.length)] + ".";
console.log(epitaph);
}
createGraves();

31
test/create-town.js Normal file
View File

@ -0,0 +1,31 @@
const generator = require("project-name-generator");
let createPlace = () => {
let numToSpawn = Math.round(Math.random() * 3) + 3
for (let i = 0; i < numToSpawn; i++){
const buildings = ['🏛️','⛺','🏚️','⛩️','🗿']
const placeTypes = ['Village','Village','Village','House','House','Market','Market','Market','Crossroads','Place','Outpost','Trading Post','House','Shack','Meeting Place','Saloon','Watering Hole','Stall','Hideout','Cart','Camp','Camp','Camp','Camp','','','','Zone of Ill Repute']
let whichBuilding = buildings[Math.floor(Math.random()*3)];
let loc = generator.generate().spaced;
let suffix = placeTypes[Math.floor(Math.random() * placeTypes.length)];
let locName = capitalize(loc + ' ' + suffix);
console.log(whichBuilding + ": "+locName)
}
}
let capitalize = (str) => {
let arr = str.split(' ');
for(let i = 0; i < arr.length; i++ ) {
arr[i] = arr[i].replace(arr[i].charAt(0), arr[i].charAt(0).toUpperCase());
}
return arr.join(' ');
}
createPlace();

77
test/example-blessed.js Normal file
View File

@ -0,0 +1,77 @@
/**
* Example Program for Blessed
* Copyright (c) 2013, Christopher Jeffrey (MIT License).
* https://github.com/chjj/blessed
*/
var blessed = require('blessed')
, program = blessed.program();
process.title = 'blessed';
program.on('keypress', function(ch, key) {
if (key.name === 'q') {
program.clear();
program.disableMouse();
program.showCursor();
program.normalBuffer();
process.exit(0);
}
});
program.on('mouse', function(data) {
if (data.action === 'mouseup') return;
program.move(1, program.rows);
program.eraseInLine('right');
if (data.action === 'wheelup') {
program.write('Mouse wheel up at: ' + data.x + ', ' + data.y);
} else if (data.action === 'wheeldown') {
program.write('Mouse wheel down at: ' + data.x + ', ' + data.y);
} else if (data.action === 'mousedown' && data.button === 'left') {
program.write('Left button down at: ' + data.x + ', ' + data.y);
} else if (data.action === 'mousedown' && data.button === 'right') {
program.write('Right button down at: ' + data.x + ', ' + data.y);
} else {
program.write('Mouse at: ' + data.x + ', ' + data.y);
}
program.move(data.x, data.y);
program.bg('red');
program.write(' ');
program.bg('!red');
});
program.on('focus', function() {
program.move(1, program.rows);
program.write('Gained focus.');
});
program.on('blur', function() {
program.move(1, program.rows);
program.write('Lost focus.');
});
program.alternateBuffer();
program.enableMouse();
program.hideCursor();
program.clear();
program.move(1, 1);
program.bg('black');
program.write('Hello world', 'blue fg');
program.setx((program.cols / 2 | 0) - 4);
program.down(5);
program.write('Hi again!');
program.bg('!black');
program.feed();
program.getCursor(function(err, data) {
if (!err) {
program.write('Cursor is at: ' + data.x + ', ' + data.y + '.');
program.feed();
}
program.charset('SCLD');
program.write('abcdefghijklmnopqrstuvwxyz0123456789');
program.charset('US');
program.setx(1);
});

View File

@ -0,0 +1,4 @@
const Charlatan = require('charlatan');
let name = Charlatan.Name.name();
console.log(name);

20
test/example-generate.js Normal file
View File

@ -0,0 +1,20 @@
const generator = require("project-name-generator");
let firstSubject = generator.generate().spaced;
let secondSubject = generator.generate({ words: 2, alliterative: true }).spaced;
let pre = ["My Year of","A Guide To","Simply","A Cook's Guide to","The Book of","A tale of","To","A","The","The","The","One","Beginning","My","A Manual of","",""];
let connector = [" of"," for"," for"," with"," and"," on",":",": on"," OR"];
let choose = arr => arr[Math.floor(Math.random()*arr.length)];
let book;
if (Math.random()<0.4){
book = choose(pre) + " " + firstSubject + choose(connector) + " " + secondSubject;
} else if (Math.random()<0.5){
book = choose(pre) + " " + firstSubject;
} else {
book = choose(pre) + " " + secondSubject;
}
console.log(book);

BIN
test/my-program-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,88 @@
var fs = require('fs');
var blessed = require('blessed');
let dungeon;
const descriptionsFile = "../.nonKittenItems.txt";
let itemDescriptions = fs.readFileSync(descriptionsFile).toString().split("\n");
let loadDungeon = () => {
const dungeonInput = fs.readFileSync(".dungeonfile.txt",'utf8')
dungeon = dungeonInput.split("\n");
}
loadDungeon();
// Create a screen object.
var screen = blessed.screen({
smartCSR: true
});
screen.title = 'my window title';
// Create a box perfectly centered horizontally and vertically.
var box = blessed.box({
top: 'center',
left: 'center',
width: '50%',
height: '50%',
content: dungeon[0],
tags: true,
border: {
type: 'line'
},
style: {
fg: 'cyan',
bg: 'white',
border: {
fg: '#f0f0f0'
},
hover: {
bg: 'green'
}
}
});
// Append our box to the screen.
screen.append(box);
// Add a png icon to the box
var icon = blessed.image({
parent: box,
top: 0,
left: 0,
type: 'overlay',
width: 'shrink',
height: 'shrink',
file: __dirname + '/my-program-icon.png',
search: false
});
// If our box is clicked, change the content.
box.on('click', function(data) {
screen.render();
});
// If box is focused, handle `enter`/`return` and give us some more content.
box.key('enter', function(ch, key) {
for (let i = 0; i < dungeon.length; i++){
box.setLine(i, dungeon[i]);
}
screen.render();
});
// Quit on Escape, q, or Control-C.
screen.key(['escape', 'q', 'C-c'], function(ch, key) {
return process.exit(0);
});
// Focus our element.
box.focus();
// Render the screen.
screen.render();

40
test/test-blessed.js Normal file
View File

@ -0,0 +1,40 @@
var blessed = require('blessed')
, program = blessed.program();
process.title = 'blessed';
program.on('keypress', function(ch, key) {
if (key.name === 'q') {
program.clear();
program.disableMouse();
program.showCursor();
program.normalBuffer();
process.exit(0);
}
});
program.alternateBuffer();
//program.enableMouse();
program.hideCursor();
program.clear();
program.move(1, 1);
program.bg('#0000ff');
program.write('Hello world', 'blue fg');
program.setx((program.cols / 2 | 0) - 4);
program.down(5);
program.write('Hi again!');
program.bg('!black');
program.feed();
program.getCursor(function(err, data) {
if (!err) {
program.write('Cursor is at: ' + data.x + ', ' + data.y + '.');
program.feed();
}
program.charset('SCLD');
program.write('abcdefghijklmnopqrstuvwxyz0123456789');
program.charset('US');
program.setx(1);
});