1 #ifndef KOORD_H
2 #define KOORD_H
3 
4 #include "ribi.h"
5 #include "../simtypes.h"
6 
7 #include <stdlib.h>
8 
9 class loadsave_t;
10 
11 /**
12  * 2D Coordinates
13  */
14 class koord
15 {
16 public:
17 	// this is set by einstelugen_t
18 	static uint32 locality_factor;
19 
20 	sint16 x;
21 	sint16 y;
22 
koord()23 	koord() : x(0), y(0) {}
24 
koord(short xp,short yp)25 	koord(short xp, short yp) : x(xp), y(yp) {}
koord(ribi_t::ribi ribi)26 	koord(ribi_t::ribi ribi) { *this = from_ribi[ribi]; }
koord(slope_t::type slope)27 	koord(slope_t::type slope) { *this = from_hang[slope]; }
28 
29 	// use this instead of koord(simrand(x),simrand(y)) to avoid
30 	// different order on different compilers
31 	static koord koord_random(uint16 xrange, uint16 yrange);
32 
33 	void rdwr(loadsave_t *file);
34 
35 	const char *get_str() const;
36 	const char *get_fullstr() const;	// including brackets
37 
38 	const koord& operator += (const koord & k)
39 	{
40 		x += k.x;
41 		y += k.y;
42 		return *this;
43 	}
44 
45 	const koord& operator -= (const koord & k)
46 	{
47 		x -= k.x;
48 		y -= k.y;
49 		return *this;
50 	}
51 
rotate90(sint16 y_size)52 	void rotate90( sint16 y_size )
53 	{
54 		if(  (x&y)<0  ) {
55 			// do not rotate illegal coordinates
56 			return;
57 		}
58 		sint16 new_x = y_size-y;
59 		y = x;
60 		x = new_x;
61 	}
62 
clip_min(koord k_min)63 	inline void clip_min( koord k_min )
64 	{
65 		if (x < k_min.x) {
66 			x = k_min.x;
67 		}
68 		if (y < k_min.y) {
69 			y = k_min.y;
70 		}
71 	}
72 
clip_max(koord k_max)73 	inline void clip_max( koord k_max )
74 	{
75 		if (x > k_max.x) {
76 			x = k_max.x;
77 		}
78 		if (y > k_max.y) {
79 			y = k_max.y;
80 		}
81 	}
82 
83 	static const koord invalid;
84 	static const koord north;
85 	static const koord south;
86 	static const koord east;
87 	static const koord west;
88 	// the 4 basic directions as an Array
89 	static const koord nsew[4];
90 	// 8 next neighbours
91 	static const koord neighbours[8];
92 
93 private:
94 	static const koord from_ribi[16];
95 	static const koord from_hang[81];
96 };
97 
98 
koord_distance(const koord & a,const koord & b)99 static inline uint32 koord_distance(const koord &a, const koord &b)
100 {
101 	return abs(a.x - b.x) + abs(a.y - b.y);
102 }
103 
104 // Knightly : shortest distance in cardinal (N, E, S, W) and ordinal (NE, SE, SW, NW) directions
shortest_distance(const koord & a,const koord & b)105 static inline uint32 shortest_distance(const koord &a, const koord &b)
106 {
107 	const uint32 x_offset = abs(a.x - b.x);
108 	const uint32 y_offset = abs(a.y - b.y);
109 	// square root of 2 is estimated by 181/128; 64 is for rounding
110 	if(  x_offset>=y_offset  ) {
111 		return (x_offset - y_offset) + ( ((y_offset * 181u) + 64u) >> 7 );
112 	}
113 	else {
114 		return (y_offset - x_offset) + ( ((x_offset * 181u) + 64u) >> 7 );
115 	}
116 }
117 
118 // Knightly : multiply the value by the distance weight
weight_by_distance(const sint32 value,const uint32 distance)119 static inline uint32 weight_by_distance(const sint32 value, const uint32 distance)
120 {
121 	return value<=0 ? 0 : 1+(uint32)( ( ((sint64)value<<8) * koord::locality_factor ) / (sint64)( koord::locality_factor + (distance < 4u ? 4u : distance) ) );
122 }
123 
124 static inline koord operator * (const koord &k, const sint16 m)
125 {
126 	return koord(k.x * m, k.y * m);
127 }
128 
129 
130 static inline koord operator / (const koord &k, const sint16 m)
131 {
132 	return koord(k.x / m, k.y / m);
133 }
134 
135 
136 static inline bool operator == (const koord &a, const koord &b)
137 {
138 	// only this works with O3 optimisation!
139 	return ((a.x-b.x)|(a.y-b.y))==0;
140 }
141 
142 
143 static inline bool operator != (const koord &a, const koord &b)
144 {
145 	// only this works with O3 optimisation!
146 	return ((a.x-b.x)|(a.y-b.y))!=0;
147 }
148 
149 
150 static inline koord operator + (const koord &a, const koord &b)
151 {
152 	return koord(a.x + b.x, a.y + b.y);
153 }
154 
155 
156 static inline koord operator - (const koord &a, const koord &b)
157 {
158 	return koord(a.x - b.x, a.y - b.y);
159 }
160 
161 
162 static inline koord operator - (const koord &a)
163 {
164 	return koord(-a.x, -a.y);
165 }
166 #endif
167