Skip to content

Commit d14cb44

Browse files
author
4b796c65
committed
Added libtcod pathfinding. Untested.
1 parent 9a99db1 commit d14cb44

File tree

3 files changed

+88
-10
lines changed

3 files changed

+88
-10
lines changed

tdl/__tcod.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ def __repr__(self):
484484
# PATH
485485

486486
TCOD_path_t = c_void_p
487-
PATHCALL = CFUNCTYPE(c_float, (c_int, c_int, c_int, c_int, c_void_p))
487+
PATHCALL = CFUNCTYPE(c_float, c_int, c_int, c_int, c_int, c_void_p)
488488

489489
_lib.TCOD_path_new_using_map.restype = TCOD_path_t
490490
_lib.TCOD_path_new_using_map.argtypes = (TCOD_map_t, c_float)

tdl/fov.py

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,41 @@
11

22
import itertools
3+
import ctypes
4+
import array
35

46
from .__tcod import _lib
57

68
class Map(object):
79

8-
def __init__(self, width, height):
10+
def __init__(self, width, height, callback):
911
self._width = int(width)
1012
self._height = int(height)
1113
self._size = self._width * self._height
1214
self._tcodMap = _lib.TCOD_map_new(width, height)
1315
self._as_parameter_ = self._tcodMap
14-
self._fovConf = (0, 0, 0) # fov settings (x, y, radius)
16+
self._callback = callback
17+
self._clean = set()
1518
#self._walkable = array.array('b', [0] * self._size)
1619
#self._transparent = array.array('b', [0] * self._size)
1720

1821
def __del__(self):
1922
_lib.TCOD_map_delete(self)
2023

24+
def _pointsInRadius(self, x, y, radius):
25+
'returns a list of (x, y) items'
26+
x = range(max(0, x - radius), min(x + radius + 1, self._width))
27+
y = range(max(0, y - radius), min(y + radius + 1, self._height))
28+
return itertools.product(x, y)
29+
30+
def _pointsInRadiusC(self, x, y, radius):
31+
'returns a list of ((x, ctypeX), (y, ctypeY)) items'
32+
c_int = ctypes.c_int
33+
x = ((i, c_int(i)) for i in
34+
range(max(0, x - radius), min(x + radius + 1, self._width)))
35+
y = ((i, c_int(i)) for i in
36+
range(max(0, y - radius), min(y + radius + 1, self._height)))
37+
return itertools.product(x, y)
38+
2139
def setFromCallbacks(self, walkableCall, transparentCall):
2240
for x, y in itertools.product(range(self._width), range(self._height)):
2341
_lib.TCOD_map_set_properties(self._tcodMap, x, y,
@@ -30,6 +48,15 @@ def set(self, x, y, walkable, transparent):
3048
_lib.TCOD_map_set_properties(self._as_parameter_,
3149
x, y, walkable, transparent)
3250

51+
def _updateMap(self, x, y, radius):
52+
c_bool = ctypes.c_bool
53+
for (x, cX),(y, cY) in self._pointsInRadiusC(x, y, radius):
54+
#if (x, y) not in self._clean:
55+
# self._clean.add((x,y))
56+
transparent = c_bool(self._callback(x, y))
57+
_lib.TCOD_map_set_properties(self._as_parameter_,
58+
cX, cY, transparent, transparent)
59+
3360
def computeFOV(self, x, y, fov='PERMISSIVE', radius=8, lightWalls=True):
3461
oldFOV = fov
3562
fov = str(fov).upper()
@@ -41,15 +68,19 @@ def computeFOV(self, x, y, fov='PERMISSIVE', radius=8, lightWalls=True):
4168
fov = 4 + int(fov[10])
4269
else:
4370
raise TDLError('No such fov as %s' % oldFOV)
71+
72+
self._updateMap(x, y, radius)
4473
_lib.TCOD_map_compute_fov(self, x, y, radius, lightWalls, fov)
45-
self._fovConf = (x, y, radius)
46-
return self._iterFOV()
74+
return self._listFOV(x, y, radius)
4775

48-
def _iterFOV(self):
49-
x, y, radius = self._fovConf
76+
def _iterFOV(self, x, y, radius):
5077
inFOV = _lib.TCOD_map_is_in_fov
5178
map = self._as_parameter_
52-
for x,y in itertools.product(range(x - radius, x + radius + 1),
53-
range(y - radius, y + radius + 1)):
54-
if inFOV(map, x, y):
79+
for (x, cX),(y, cY) in self._pointsInRadiusC(x, y, radius):
80+
if inFOV(map, cX, cY):
5581
yield(x, y)
82+
83+
def _listFOV(self, x, y, radius):
84+
return list(self._iterFOV(x, y, radius))
85+
86+
__all__ = [Map]

tdl/path.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,52 @@
11

2+
import math
3+
import ctypes
24

5+
from .__tcod import _lib
6+
7+
class AStar(object):
8+
9+
def __init__(self, width, height, callback, diagnalCost=math.sqrt(2)):
10+
def newCallback(fromX, fromY, toX, toY, null):
11+
pathCost = callback(toX, toY) # expecting a float or 0
12+
return pathCost
13+
self.callback = newCallback
14+
self._as_parameter_ = _lib.TCOD_path_new_using_function(width, height,
15+
newCallback, None, diagnalCost)
16+
17+
def getPath(self, origX, origY, destX, destY):
18+
found = _lib.TCOD_path_compute(self, origX, origY, destX, destY)
19+
if not found:
20+
pass # path not found, not sure what to do
21+
x, y = ctypes.c_int(), ctypes.c_int()
22+
xRef, yRef = ctypes.byref(x), ctypes.byref(y)
23+
recalculate = ctypes.c_bool(False)
24+
path = []
25+
while _lib.TCOD_path_walk(self, xRef, yRef, recalculate):
26+
path.append(x.value, y.value)
27+
return path
28+
29+
30+
def __del__(self):
31+
_lib.TCOD_path_delete(self)
32+
33+
class Dijkstra(object):
34+
35+
def __init__(self, width, height, callback, diagnalCost=math.sqrt(2)):
36+
def newCallback(fromX, fromY, toX, toY, null):
37+
pathCost = callback(toX, toY) # expecting a float or 0
38+
return pathCost
39+
self.callback = newCallback
40+
self._as_parameter_ = _lib.TCOD_dijkstra_new_using_function(width, height,
41+
newCallback, None, diagnalCost)
42+
# add code to compute here with x,y
43+
44+
def getPathFrom(self, startX, startY):
45+
pass
46+
47+
def getPathTo(self, destX, destY):
48+
pass
49+
350
def bresenham(x1, y1, x2, y2):
451
points = []
552
issteep = abs(y2-y1) > abs(x2-x1)

0 commit comments

Comments
 (0)