Jump to content

  • Log In with Google      Sign In   
  • Create Account

Álvaro

Member Since 07 Mar 2002
Online Last Active Today, 03:39 PM

#5134158 How to move particle on sphere

Posted by Álvaro on 24 February 2014 - 12:14 PM

If (x,y,z) is a point on the surface of the unit sphere centered at the origin, the East vector is something like (z, 0, -x) and the North vector is something like (-xy/S, S, -yz/S), with S:=sqrt(1-y^2). You can then express your direction as North * cos(angle) + East * sin(angle).

 

I kind of rushed through the Math, so I am not 100% certain that the formulas are correct, but you can try to reproduce them yourself.




#5134141 An Ever Changing/Learing AI

Posted by Álvaro on 24 February 2014 - 10:56 AM

This notion that in order to have learning AI you need programs that modify their own code is preposterous, but also very common. The divide between code and parameters is an arbitrary one, and it's much more productive to think of learning as changing parameters.

 

The other thing that should be mentioned is that adaptive AI is something you probably don't want in a video game. It's hard enough to debug a non-adaptive AI to make sure that the bad guys don't get stuck in corners or do other stupid things that break the illusion. If the AI can change once it's in the hands of the player, this can become a much harder problem, unless the adaptability is very limited and controlled.




#5134133 How to move particle on sphere

Posted by Álvaro on 24 February 2014 - 10:33 AM

Weird. I just answered a question about quaternions that is essentially the same question.

 

If your time step is small, move the particle in R^3, forgetting about the sphere for a moment, then project back to the sphere. If that approximation is not good enough, there is a formula you can use that involves computing cosine and sine. I'll figure it out and post it, if you really need it.




#5134125 Can't get Quaternion Time Derivative to work?

Posted by Álvaro on 24 February 2014 - 10:13 AM

Notice that my formula is exact only if the angular velocity is constant for the whole second. In your simulation that will probably not be true, and you'll have to split time into smaller steps. At that point the steps will probably be small enough that your original approximation is perfectly acceptable.

 

I should have mentioned in my previous post that if you make the approximations cos(epsilon) = 1 and sin(epsilon)=epsilon (which are good for small epsilon), my formula turns into the one you posted.




#5134092 data compression

Posted by Álvaro on 24 February 2014 - 07:10 AM

I wonder what was OP smoking to start this thread smile.png He's just trolling... So many nice and relevant answers, just in vein sad.png


We can enjoy each other's comments about the subject. I don't give a flying fig about the OP's part in this thread. smile.png


#5134047 Can't get Quaternion Time Derivative to work?

Posted by Álvaro on 24 February 2014 - 03:02 AM

The derivative is a linear approximation, so a formula for the derivative of something only tells you how it changes in infinitesimally small periods of time. In your case, one second is too large of a step for the approximation to work.

Try this instead:

Q' = (cos(t*|W|/2) + sin(t*|W|/2)*W/|W|) * Q

If you plug in Q=(0 0 0 1), W=(0 0 pi 0) and t=1, you get Q'=(0 0 1 0)


#5133931 How to account for position's history in transposition tables

Posted by Álvaro on 23 February 2014 - 03:08 PM

If that's the case, you are not using alpha-beta search: You are doing straight minimax search. Alpha-beta doesn't always return exact scores.

 
I am currently only storing nodes that haven't been pruned/cut off. In this case we do get the minimax value, don't we?


No, if you didn't find a successor that was better than alpha, you only know that the minimax score of this node is alpha or worse.
 
 

Why are you storing the difference between bestEval and node.getScore() instead of just storing bestEval? What's the point of node.getScore() anyway if you are doing exhaustive search?


 
I am doing the subtraction in order to "decouple" the subtree from its history. In my opinion, this difference will express: "How many points can the declarer achieve, starting from this position?"


Yes, you are right about storing the difference between search result and current score. Sorry, I forgot you described this in your first post.


#5133731 How to account for position's history in transposition tables

Posted by Álvaro on 22 February 2014 - 10:34 PM

The "depth" I am referring to here is the "depth left". Presumably you are not examining the whole tree exhaustively, but you have a depth limit and use a heuristic evaluation function at the leaves. If you are doing that, you might be using other common refinements, like extensions for forced moves, reductions for moves that show little promise, iterative deepening... All of these things can result in the same position being examined with different "depth left" at different times.

A partial implementation of transposition tables that only stores exact scores shouldn't break anything, but you have to be careful to only store at the right times. That is, whenever one of the successors has yielded a score better than alpha and none of them has yielded a score that is beta of better.

Yes, I suspect there is a problem with the implementation. As I said earlier, it is very tricky to get transposition tables right, even when you fully understand the theory behind them.


#5133541 Array question

Posted by Álvaro on 22 February 2014 - 07:43 AM

This is tricky to get right. Here's my attempt (with same-length arrays, to keep sanity):
#include <algorithm> // Just for std::swap

unsigned find_first_unlocked(bool const *locked, unsigned n, unsigned i) {
  for (; i < n; ++i) {
    if (!locked[i])
      break;
  }
  
  return i;
}

void shift(int *v, bool const *locked, unsigned n) {
  unsigned i, j;
  for (i = find_first_unlocked(locked, n, 0), j = find_first_unlocked(locked, n, i + 1);
       j < n;
       std::swap(i, j), j = find_first_unlocked(locked, n, i + 1)) {
    v[i] = v[j];
  }
  
  if (i < n)
    v[i] = 0;
}




#5133260 How did you learn C++?

Posted by Álvaro on 21 February 2014 - 08:25 AM

I tried to learn C++ on my own twice in the 90s and I failed miserably. Then I got a job where C++ was used and I learned it relatively quickly. One thing that helped a lot was having access to a C++ guru down the hall. Oh, and nobody cared that I didn't know C++ in my job interview: My interviewers were satisfied because I could solve problems and I could program in C.


#5132853 I don't get c++11.

Posted by Álvaro on 19 February 2014 - 09:45 PM

I also like the new initializer lists, because they make my code more clear in some common situations:

  for (int delta : {-8, -1, +1, +8}) {
    // ...
  }

  // ...

  std::map<std::string, std::string> dictionary = {
    {"spring", "muelle"},
    {"summer", "verano"},
    {"fall", "caida"},
    {"winter", "invierno"}
  };



#5132833 What am I doing wrong with this code?

Posted by Álvaro on 19 February 2014 - 08:05 PM

I prefer this type of code (not tested):
  struct {                                                                                                            
    int key;                                                                                                          
    int delta_x;
    int delta_y;                                                                                             
    int xscale;                                                                                                       
  } const directions[4] = {                                                                                           
    {vk_right, 4, 0, 1},                                                                                              
    {vk_left, -4, 0, -1},                                                                                             
    {vk_up, 0, -4, 1},                                                                                                
    {vk_down, 0, 4, 1}                                                                                                
  };                                                                                                                  
                                                                                                                      
  if (sprite_index != spr_playerattack) {                                                                             
    for (auto direction : directions) {                                                                               
      if (keyboard_check(direction.key) && place_free(x + direction.delta_x, y + direction.delta_y)) {                
        x += direction.delta_x;                                                                                       
        y += direction.delta_y;                                                                                       
        sprite_index = spr_playerrun;                                                                                 
        image_speed = .2;                                                                                             
        image_xscale = direction.xscale;                                                                              
      }                                                                                                               
    }                                                                                                                 
  }                                                                                                                   



#5132750 Binary to Integer (Read hex binary file)

Posted by Álvaro on 19 February 2014 - 02:49 PM

It's a 16-bit floating point type.

#include <cstdio>
#include <cmath>

void print_as_tinyfloat(int i) {
  int sign = (i < 0);
  int exponent = static_cast<int>(std::floor(std::log2(std::abs(i))));
  int mantissa = (i << (7 - exponent)) ^ (1 << 7);
  unsigned tinyfloat = (sign << 15) + ((exponent + 127) << 7 ) + mantissa;

  std::printf("%d -> %d %d\n", i, tinyfloat % 256, tinyfloat / 256);
}

int main() {
  for (int i=1; i<20; ++i)
    print_as_tinyfloat(i);
}



#5132397 Need algorith to rotate isometric image sprite !

Posted by Álvaro on 18 February 2014 - 12:22 PM

A solution does not exist, and I'll give you an informal proof. If I only have that last picture to work with, I don't know if the spear is parallel to the ground or if he is holding it in a direction that is very close to the direction of projection and the spear is very very long: Both situations produce the same projection. When the figure is rotated, the two scenarios will look dramatically different.

 

Just get a 3D model that you can render yourself, or get someone else to render more angles for you.




#5132361 Need algorith to rotate isometric image sprite !

Posted by Álvaro on 18 February 2014 - 10:36 AM

You think you can take a 2D rendering of a 3D figure and compute a rendering from a different camera angle? How do you think that would work? Do you at least have depth information in the original image?






PARTNERS