inkle / inkle/ink

Accessing "N" value in a LIST & Picking a Random "DoctorsInSurgery" from only those currently (IN)

Open
#389 6 comments 1 reaction 0 assignees View on GitHub
Dominant language
C#
Stars
4.9k
Forks
540
PR merge metrics
No merged PRs in 30d

Description

~~I'd like to request that we make LIST_ENTRY_N() a standard command for the language. It would be very useful to be able to get specific (IN) values in a LIST. Beyond the first & last (Min/Max).~~

----------------------------

Thanks to _joningold_,

**WARNING:** It is advised to not use this with LISTS which have values from multiple sources.

```
//essentially does listVariable[n]
=== function LIST_ENTRY_N(list, n) ===
{ list:
~ temp entry = LIST_MIN(list) //Get the LIST_MIN. This is the first entry in the LIST.
{ n <= 0:
~ return entry //If you are finally at listVariable[n], then return the entry.
- else:
~ return LIST_ENTRY_N(list - entry, n - 1) //Remove the LIST_MIN entry & iterate again.
}
- else:
~ return () // if you run out return empty list //There is nothing left. Return empty list.
}

=== function LIST_RANDOM_IN(list) ===
~temp randomElement = LIST_ENTRY_N(list, RANDOM(0, LIST_COUNT(list)))
~return randomElement
```

-------------------------------
From the example:
```LIST DoctorsInSurgery = (Adams), Bernard, Cartwright, (Denver), Eamonn ```
```LIST_MIN(DoctorsInSurgery)``` would give you (Adams).
```LIST_COUNT(DoctorsInSurgery)``` would give you 2, as only Adams & Denver are (IN).

**GOAL:** Access the second (IN) doctor (Denver) directly **or** iterate through entire LIST, only reaching doctors who are (IN) while ignoring all those who are OUT.

If you simply did ```DoctorsInSurgery(2)```, it would result in ```Bernard```, even though he is OUT.
To access ```Denver```, you would add the function above and then use:
```LIST_ENTRY_N(DoctorsInSurgery, 2)```

If you wanted to get a random doctor who is IN, while ignoring all who are OUT, then you would use ```LIST_RANDOM_IN(DoctorsInSurgery)```. This returns either ```(Adams)``` or ```(Denver)```.

**The logic in ```LIST_ENTRY_N()``` is very important. What you're essentially doing is iterating through a LIST**, until you find what you need. The way this works is by taking the very first element in the LIST, checking or changing it (you'd need to add this logic), and then knocking it off. It does this "n" times, which results in the final MIN being the one you want.

For example, you could use this logic to iterate through a LIST to find Cartwright, and check if he is (IN). While that isn't a good idea since you could just check with ?has, the logic is still there for when you need to do something along those lines. One step closer to having something resembling an array.

WARNING: This will be very slow in large lists. You are forced to iterate through either MIN or MAX. Correct me if I'm wrong, but if you had a list of 100 elements, the slowest would be right in the middle at 50. The fastest would be 100 (start from MAX) or 1 (start from MIN).
If this method is too slow, then I would advise using an EXTERNAL function to take the LIST into C#, iterate through it there, and then either use it in your game right then & there (preferable) or feed it back to INK (Warning2: Read when EXTERNALS should be used & when they shouldn't be used).

----------------------------

What I use this for is my Party of Characters. I will make a separate issue for my code there, for future reference or improvement suggestions.

Hope this helps!

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.