Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2001:
[Freeciv-Dev] Re: directional system: more magic code cleanups
Home

[Freeciv-Dev] Re: directional system: more magic code cleanups

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: directional system: more magic code cleanups
From: Jason Dorje Short <jshort@xxxxxxxxxxxxx>
Date: Mon, 17 Sep 2001 13:01:51 -0400
Reply-to: jdorje@xxxxxxxxxxxxxxxxxxxxx

Jason Dorje Short wrote:
> No, it must be positive (>0) rather than non-negative (>=0).  Traveling
> orthogonally to the destination is not OK.

This is wrong of course, as Raimar pointed out.


Raimar Falke wrote:
> On Mon, Sep 17, 2001 at 02:26:43PM +0100, Gregory Berkolaiko wrote:
> >  --- Raimar Falke <hawk@xxxxxxxxxxxxxxxxxxxxxxx> wrote:
> > [..]
> > > I think the code should be changed as follow:
> > >
> > > int dir_ok(int src_x, int src_y, int dest_x, int dest_y, int dir, int
> > > only_straightest /* this will make only 3 dirs ok */)
> > [..]
> > >
> > > And remove straightest_direction.
> >
> > Well, straightest_direction is used in a different context, if only once.
> >  You can come up with a way to substitute it with randomly chosen
> > direction (provided it's dir_ok(...., only_straightest=1) ), but it's
> > kind of bother really.
> 
> *rereading server/gotohand.c* straightest_direction is similar to
> get_direction_for_step and also to dir_ok.
> 
> Proposed dir_ok function:
> 
> int dir_ok(int src_x, int src_y, int dest_x, int dest_y, int dir,
>   int only_straightest /* this will make only 1 direction ok */)
> {
>   int diff_x, diff_y,scalar_product;
> 
>   if (dest_x > src_x) {
>     diff_x = dest_x-src_x < map.xsize/2 ? 1 : -1;
>   } else if (dest_x < src_x) {
>     diff_x = src_x-dest_x < map.xsize/2 ? -1 : 1;
>   } else { /* dest_x == src_x */
>     diff_x = 0;
>   }
>   if (dest_y != src_y)
>     diff_y = dest_y > src_y ? 1 : -1;
>   else
>     diff_y = 0;
> 
>   scalar_product=diff_x*DIR_DX[dir] + diff_y*DIR_DY[dir];
>   if(only_straightest)
>         return scalar_product==2;
>   else
>         return scalar_product>=0;
> }

This won't work, since scalar_product can sometimes be just 1 for the
straightest direction.

Another point of note is that the code to determine diff_x and diff_y is
topology-dependent, and so should be moved into a macro/function
somewhere in map.[ch].

How about something like this?  It computes straightest_direction by
finding the actual cartesian product of the travel vector with the
normalized directional unit vector.  The largest product means the
straightest direction.  dir_ok could then be written in terms of
straightest_direction.  This code should give results similar to Ross's
proposed straightest_direction.

static int straightest_direction(int src_x, int src_y, int dest_x, int
dest_y)
{
  int best_dir = -1, dir;
  float best = -1;
  int diff_x, diff_y;

  /* This code is topology-dependent */
  diff_x = dest_x - src_x;
  if (diff_x < -map.xsize / 2) diff_x += map.xsize;
  if (diff_x > map.xsize / 2) diff_x -= map.xsize;
  diff_y = dest_y - src_y;

  for (dir=0; dir<8; dir++) {
    float product = diff_x * DIR_DX[dir] + diff_y * DIR_DY[dir];
    product /= sqrt(DIR_DX[dir] * DIR_DX[dir] + DIR_DY[dir] *
DIR_DY[dir]);

    if (product > best) {
      best = product;
      best_dir = dir;
    }
  }

  assert(best >= 0 && best_dir >= 0);
  return best_dir;
}


[Prev in Thread] Current Thread [Next in Thread]