@p.meled.in has joined the channel
Am I alright to ask a question? It’s a bit lengthy (as in, several lines) but I don’t think it’s particularly “complicated” for someone more experienced than I. I’ve got a solution, but I feel like there’s probably a much more declarative way to be doing it using the racket stdlib.
Ask away!
Thanks :slightly_smiling_face: Thanks for suggesting this place to me on reddit too soegaard, I appreciate it.
I have a chance-based AI for an rpg, which splits up actions like this: if some-condition is true, ?/4 chance of casting ____ otherwise, ?/4 chance of casting ____ otherwise, attack but the ?s don’t always “add up”, in the sense that if we have: if health-is-low, 1/4 chance of casting heal otherwise, 3/4 chance of casting hurt otherwise attack that doesn’t mean the attack never happens, it means there is a 1/4 chance of healing if low on hp, then a 3/4 chance of casting hurt, then if neither of those are the case, just attack.
The system I currently have is basically just a translation of the above to a function, with the conditions and spells passed as parameters, with a random number generated at each step other than the last.
The other system I considered was a list of functions of the above form, which is iterated through (using ormap) calling each one in turn and returning the first non false result.
Both sounds sensible.
Have you experimented with for/first
?
(as an alternative to ormap
?
for/first did stand out to me yes, but I couldn’t quite work out how best to use it. I think you need to have some kind of #:when clause to make it useful, right?
Yes. Something like:
(for/first ([chance '(1/4 1/3)]
[action (list attack heal)]
#:when (< (random) chance))
(action))
where attack
and heal
are functions to be called.
That’s great! I settled on the function because the ormap with the list was starting to look rather obscure, but that shows the intent perfectly I think.
I figured a list with that method may be better because you’re not hard-coding the shape of the function, you can just define behaviours by plugging together predicates that return spells/actions.
And if you need a default action in the end:
(for/first ([chance '(1/4 1/3 +inf.0 )]
[action (list attack heal default)]
#:when (< (random) chance))
(action))
where default
is the funtion to call, when one of the other actions were invoked.
ah, because (random) is always going to be less than infinity.
yes
thank you very much for the help, that’s ideal :slightly_smiling_face: I’m glad you don’t think that’s too-obscure a way of handling it. It seemed very reasonable to me (especially with lists being so ubiquitous) but I wasn’t entirely convinced a more experienced programmer would think so too.
no problem
Would someone mind glancing over this ncurses ffi/api and let me know if it’s looking alright? This is my first time writing any kind of library/package for Racket (for any language, in fact) so I’m still finding my bearings.
does struct inheritance not extend to methods?
i.e. if I have a struct that defines some method for some gen:interface, and then I have another struct defined as a “substruct” of that struct using the (struct struct-id super-id (field-id …)) form, then that substruct isn’t supposed to be able to use methods of the supertype if that method isn’t specifically defined for that subtype, right?
I sort of expected that it would, and I just want to make sure that’s intended behaviour (that a method undefined error is displayed) rather than me doing something wrong that’s preventing the method from automatically being inherited in lieu of a more specific implementation on the subtype.