The problem is that real humans and indeed real decisions don't work that way.
This is true. I have mostly dealt with situations where rational behavior is preferred, and imitating humans is irrelevant.
But I do have some experience in making utility systems that need to conform to rules. There are two ways of mixing them: * Rules cannot be broken (e.g., you need to obey regulations in a trading system). * Following rules is encouraged. I believe this is what applies to games.
So you can have a utility system where one of the terms in evaluating an action is whether this action is in accordance with a set of rules. The weight of this term can be adjusted so rules will be ignored at the right time. That way you may be able to get the best of both worlds: The utility mechanism will take care of emergency situations, and the designer still can describe how things should happen under normal circumstances.
For instance, a rule might say that the correct action to perform now is make tea, because a guest has requested it. But someone just started shooting. Ignoring the rules, the utility of taking cover is much higher than the utility of making tea, so even with the bonus for following rules making tea won't be selected.
Integral of density is mass, integral of position times density divided by mass is center of mass, integral of density times the square of the distance to the center of mass is moment of inertia. [EDIT: I had forgotten about the square, sorry.]
Incidentally this is probably the most significant problem that I have with utility systems - designers often have a mental model of the ranking or precedence that they want the actions to have, but trying to force the mathematics to produce that result consistently can be very difficult.
While this is indeed a problem, I think it's a problem with designers, not utility systems. The way designers often think about behavior (rankings of actions, if-then rules...) is brittle by nature and results in many absurd situations. Designers just need to get more sophisticated in their thinking and learn to describe their preferences as utility functions.
It is very important to give them tools to understand why an agent is behaving the way it's behaving, like a display of available actions, the contribution of each term in the utility function to the final assessment, etc.
Sorry for not replying for a while! I managed to get it all sorted out thanks to your help!
It would be nice if you could give us a brief description of what worked for you. That way this thread would be more helpful to people that find it in the future when they have a similar problem to yours.
The most robust strategy is to consider all targets and all interactions, and pick the best combination. Utility systems are great for this. It helps to mix in "non-targeted" actions as well (running away, healing, etc.) so you can always have something semi-reasonable to do regardless of situation.
Here's what to do in situations like this one: Make a copy of your code and boil it down to the smallest possible program that still shows the problem. Remove absolutely everything you can that doesn't have to do with the particular crash. Put all the code in a single file.
Now either of two things will happen: (1) You discover the problem in the process of creating the small version of the program. (2) You have a short program that you can post here, so we can all reproduce the problem and help you much better. If it turns out the short program is obviously correct and it's still breaking, you can include this code in a bug report.
Now, in the last 20 years of programming I have found a compiler bug exactly once. So the prior probability that you found one is very small, and the fact that your code has some issues (like not checking return values) leads me to lower my estimate in light of what I know about the situation.
A singleton is rarely a good solution. In a well-designed program you typically don't have that many dependencies, so perhaps you need to rethink your design. Sending the references everywhere at least makes the dependencies explicit. Otherwise you'll try to reuse some piece of code for a new project and you'll realize that the whole project has become one monolithic mess and you can't do it.
If you end up using global state of some sort, what is the advantage of using a singleton over using a global variable?
I might include a note about your my_atan(), and possibly exp() and some others. Did you come up with the original code?
Yes, I did. I got the idea of using something like x/polynomial from this paper.
I just found a very interesting trick I hadn't thought about: You can reduce everything to computing atan(x) for x smaller than tan(pi/12) ~= 0.268, where it's really easy to approximate well. See here. The idea seems to come from "Math Toolkit for Real-Time Programming" by Jack Crenshaw, which I don't own.
With the parametrization you have used, the samples at the poles are very close together. Try using doubles for the computation, but even that might not fix the very last line, because all those points map to the same point on the pole and you are then looking at degenerate triangles.
A clean solution would be to use a cubemap instead of spherical coordinates.