1

I'm working on a dungeon crawler in node.js. I wanted an elegant way to keep track of what endings a user has. I was thinking it would be nice if i could have an array of each of the endings and then just set an item to true if that ending is achieved. This would make it easy to go through the list and print the achieved endings then calculate the percentage of completion.

My attempt at doing this:

var end1 = true
var end2 = true
var end3 = false
var end4 = true
var end5 = false

var endings = [end1, end2, end3, end4, end5]

function listEndings() {
  console.log("You have found these endings:")
  var total = 0

  for (let i = 0; i < endings.length; i++) {
    if (endings[i] = true) {
      console.log(String(endings[i]))
      total = total + 1
    }
  }

  console.log(`\nIn total you have ${total}/${endings.length + 1} endings. (${(total/(endings.length + 1))*100}%)`)
}

The output I would like

You have found these endings:
end1
end2
end4

In total you have 3/5 endings. (60%)

Is is possible to use a method like this? Is there another method you would recommend?

Thank you very much for the help!

DecPK
  • 24,537
  • 6
  • 26
  • 42
  • i would push the endings to a seconds array like archivedArr.push(endings[3]) etc. than you dont need a 'big' for loop at the end. and don't need the true false stuff – Strella Sep 17 '21 at 02:02
  • or just store them in a single value for ex no ending 00000, all endings 11111, end3 00100 ... – Strella Sep 17 '21 at 02:08
  • 1
    `(endings[i] = true` is assignment not comparison. For comparison use `===`. – DecPK Sep 17 '21 at 02:20

3 Answers3

0

I think it's better to store the values as an array storing the endings the player has already found:

let endingsFound = []
const totalEndings = 5
//(as a side note, better use let than var)

console.log('Endings found')
//suppose we find endings three and four
endingsFound.push(3)
endingsFound.push(4)

endingsFound.forEach((end) => console.log(`Ending ${end}`))

console.log(`In total you have found ${endingsFound.length +1}/${totalEndings}`);

if you're still determined to store it as an array of booleans, then use the following function:

const indices = arr.reduce(
    (out, bool, index) => bool ? out.concat(index) : out, 
    []
  )

as was presented here to get to an array of the endings found and then do the same.

0

It would be easy and straightforward to use object instead of an array and use Object.entries to loop over the key and value to get the desired result.

var end1 = true;
var end2 = true;
var end3 = false;
var end4 = true;
var end5 = false;

var endings = { end1, end2, end3, end4, end5 };

function listEndings() {
  let count = 0, entries = Object.entries(endings);
  
  console.log("You have found these endings:");
  for (let [k, v] of entries) {
    if (v) {
      console.log(`${k}`);
      ++count;
    }
  }

  console.log(
    `In total you have ${count}/${entries.length} endings. (${
      (count * 100) / entries.length
    }%)`
  );
}

listEndings();
DecPK
  • 24,537
  • 6
  • 26
  • 42
0

in this case, declare array variable that the contain is object. so, your data is flexible. you can add data anytime if some condition you'll need.

use the filter and map funtion to create output like that

var endings = [
{"no": 1,"bool": true},
{"no": 2,"bool": true},
{"no": 3,"bool": false},
{"no": 4,"bool": true},
{"no": 5,"bool": false},
{"no": 6,"bool": true},
{"no": 7,"bool": false}
]

var result = endings.filter((a)=>a.bool==true)
var resultMsg = result.map((a)=> `end${a.no}\n`)
var resultVal = parseInt((result.length/endings.length)*100)

console.log(`You have found these endings:\n ${resultMsg}`)
console.log(`\nIn total you have ${result.length}/${endings.length} endings. (${resultVal}%)`)