Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2001:
[Freeciv-Dev] Re: RFC: 8-topology system
Home

[Freeciv-Dev] Re: RFC: 8-topology system

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Cc: freeciv-dev <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: RFC: 8-topology system
From: Jason Dorje Short <vze2zq63@xxxxxxxxxxx>
Date: Wed, 17 Oct 2001 00:47:49 -0400
Reply-to: jdorje@xxxxxxxxxxxx

Jason Dorje Short wrote:
> 
> Here is a (hopefully) full explanation of how I propose to implement an
> 8-topology system.  The eight topologies include flat vs isometric,
> north-south wrapping vs no wrapping, and east-west wrapping vs no
> wrapping.  We also allow the possibility of adding non-rectangular maps
> in the future.  Any of these 8 topologies will work under my proposed
> general topological system (an earlier post), either with or without the
> linear-combination-of-vectors (LCOV) extension (LCOV allows
> wrap_map_pos()).

There are several incorrect things here.

> To implement variations of the iso-rectanglular is much harder.  An
> iso-rectangle may be of the form
> 
>       X             X             X X           X X
>     X X X         X X X         X X X X       X X X X
>   X X X X X     X X X X X     X X X X X     X X X X X
> X X X X X     X X X X X X   X X X X X     X X X X X X
>   X X X         X X X X       X X X         X X X X
>     X             X X           X             X X
> 
> (1) - 7x5      (2) - 7x6     (3) - 8x5     (4) - 8x6

Whoops!  #4 should be
      X X
    X X X X
  X X X X X X
X X X X X X
  X X X X
    X X

> - xsize = ysize = (height-1)/2 + (width-1)/2 + 1

Because of the above mistake, I messed up here.

We still have
  ysize = (height-1)/2 + (width-1)/2 + 1
but now we get
  xsize (height+width)/2

> - The western end of the world is defined by the line x+y=(height-1)/2.
> A point is off the map to the west if x+y<(height-1)/2.
> 
> - The northern end of the world is defined by the line
> x-y=-(height-1)/2.  A point is off the map to the north if
> x-y<-(height-1)/2.
> 
> - The eastern end of the world is defined by the line
> x+y=(height-1)/2+width.  A point is off the map to the east if
> x+y>(height-1)/2+width.
> 
> - The southern end of the world is defined by the line
> x-y=-(height-1)/2+height.  A point is off the map to the south if
> x-y>-(height-1)/2+height.

I forgot that FreeCiv, like all things in programming, counts y from the
top instead of the bottom.  This is important because the north is in
that direction (towards y=0) and that's the way the client shows things.

Plus, the addition of "width" and "height" should obviously be "width-1"
and "height-1".

So the new (correct) functions are

North: x + y < (width - 1) / 2
West: x - y < -(width - 1) / 2
South: x + y > (width - 1) / 2 + height - 1
East: x - y > -(width - 1) / 2 + width - 1

The attached c program should help to clear this stuff up (and looks
really cool in the process).  Compile it and run with parameters "0 1 7
5" (shape isometric width height) to get started.

jason
int shape;
int isometric;
int ns_wrap, ew_wrap;           /* not used...yet */
int width, height;

int xsize, ysize;

#define IS_EVEN(n) ( ((n)/2) * 2 == (n) )


int is_normal_map_pos(int x, int y)
{
        switch (shape) {
        case 0:         /* rectangle */
                if (isometric) {
                        /* The northern border travels from (0, (width-1)/2) to
                           ((width-1)/2, 0). */
                        /* test northern edge */
                        if (x + y < (width - 1) / 2)
                                return 0;

                        /* test western edge */
                        if (x - y < -(width - 1) / 2)
                                return 0;

                        /* test southern edge */
                        if (x + y > (width - 1) / 2 + height - 1)
                                return 0;

                        /* test eastern edge */
                        if (x - y > -(width - 1) / 2 + width - 1)
                                return 0;

                        return 1;
                } else {
                        return y >= 0 && y < height && x >= 0 && x < width;
                }
                break;
        case 1:         /* ellipse */
                if (isometric) {
                        printf("Iso-ellipses not implemented.\n");
                        exit(-1);
                } else {
                        int xr = width / 2;
                        int yr = height / 2;
                        x -= xr, y -= yr;
                        xr++, yr++;
                        return (x * x * yr * yr + y * y * xr * xr <
                                xr * xr * yr * yr);
                }
        default:
                exit(-1);
        }

}

int init_topology(void)
{
        if (shape == 1) {
                /* Did I say we must have even dimension? I meant we must
                   have ODD dimension. */
                width = (width / 2) * 2 + 1;
                height = (height / 2) * 2 + 1;
        }
        if (isometric) {
                ysize = (height - 1) / 2 + (width - 1) / 2 + 1;
                /* xsize is correctly determined by taking the intersection of 
the
                   southern and eastern world edges, as above, rounding down, 
and adding 1. */
                xsize = (height + width) / 2;
        } else {
                xsize = width;
                ysize = height;
        }
}

void print_map(void)
{
        int x, y;

        for (y = -1; y <= ysize; y++) {
                for (x = -1; x <= xsize; x++) {
                        char c = ' ';
                        if (x < 0 || x >= xsize)
                                c = '|';
                        if (y < 0 || y >= ysize)
                                c = '-';

                        if (is_normal_map_pos(x, y))
                                c = '#';
                        printf("%c ", c);
                }
                printf("\n");
        }

}

int main(int argc, char **argv)
{
        if (argc != 5) {
                printf("Usage: %s <shape> <isometric> <width> <height>.\n",
                       argv[0]);
                return -1;
        }

        sscanf(argv[1], "%d", &shape);
        sscanf(argv[2], "%d", &isometric);
        sscanf(argv[3], "%d", &width);
        sscanf(argv[4], "%d", &height);

        init_topology();

        print_map();
}

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