Completed
Push — master ( abe2f6...4a15f4 )
by Kyle
01:34
created

Console.default_alignment()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
dl 0
loc 4
rs 10
1
"""This module focuses on improvements to the Python libtcod API.
2
"""
3
from __future__ import absolute_import as _
4
5
import os as _os
0 ignored issues
show
Unused Code introduced by
Unused os imported as _os
Loading history...
6
import sys as _sys
7
8
import platform as _platform
0 ignored issues
show
Unused Code introduced by
Unused platform imported as _platform
Loading history...
9
import weakref as _weakref
0 ignored issues
show
Unused Code introduced by
Unused weakref imported as _weakref
Loading history...
10
import functools as _functools
11
12
import numpy as _np
0 ignored issues
show
Configuration introduced by
The import numpy could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
13
14
from tcod.libtcod import lib, ffi, BKGND_DEFAULT, BKGND_SET
0 ignored issues
show
Bug introduced by
The name BKGND_DEFAULT does not seem to exist in module tcod.libtcod.
Loading history...
Bug introduced by
The name BKGND_SET does not seem to exist in module tcod.libtcod.
Loading history...
15
16
def _unpack_char_p(char_p):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
17
    if char_p == ffi.NULL:
18
        return ''
19
    return ffi.string(char_p).decode()
20
21
def _int(int_or_str):
22
    'return an integer where a single character string may be expected'
23
    if isinstance(int_or_str, str):
24
        return ord(int_or_str)
25
    if isinstance(int_or_str, bytes):
26
        return int_or_str[0]
27
    return int(int_or_str) # check for __count__
28
29
def _cdata(cdata):
30
    """covert value into a cffi.CData instance"""
31
    try: # first check for _CDataWrapper
32
        cdata = cdata.cdata
33
    except AttributeError: # assume cdata is valid
0 ignored issues
show
Unused Code introduced by
This except handler seems to be unused and could be removed.

Except handlers which only contain pass and do not have an else clause can usually simply be removed:

try:
    raises_exception()
except:  # Could be removed
    pass
Loading history...
34
        pass
35
    except KeyError:
0 ignored issues
show
Unused Code introduced by
This except handler seems to be unused and could be removed.

Except handlers which only contain pass and do not have an else clause can usually simply be removed:

try:
    raises_exception()
except:  # Could be removed
    pass
Loading history...
36
        pass
37
    if cdata is None or cdata == 0: # convert None to NULL
38
        cdata = ffi.NULL
39
    return cdata
40
41
if _sys.version_info[0] == 2: # Python 2
42
    def _bytes(string):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
43
        if isinstance(string, unicode):
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'unicode'
Loading history...
44
            return string.encode()
45
        return string
46
47
    def _unicode(string):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
48
        if not isinstance(string, unicode):
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'unicode'
Loading history...
49
            return string.decode()
50
        return string
51
52
else: # Python 3
53
    def _bytes(string):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
54
        if isinstance(string, str):
55
            return string.encode()
56
        return string
57
58
    def _unicode(string):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
59
        if isinstance(string, bytes):
60
            return string.decode()
61
        return string
62
63
def _fmt_bytes(string):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
64
    return _bytes(string).replace(b'%', b'%%')
65
66
def _fmt_unicode(string):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
67
    return _unicode(string).replace(u'%', u'%%')
68
69
class _PropagateException():
70
    """ context manager designed to propagate exceptions outside of a cffi
71
    callback context.  normally cffi suppresses the exception
72
73
    when propagate is called this class will hold onto the error until the
74
    control flow leaves the context, then the error will be raised
75
76
    with _PropagateException as propagate:
77
    # give propagate as onerror parameter for ffi.def_extern
78
    """
79
80
    def __init__(self):
81
        self.exc_info = None # (exception, exc_value, traceback)
82
83
    def propagate(self, *exc_info):
84
        """ set an exception to be raised once this context exits
85
86
        if multiple errors are caught, only keep the first exception raised
87
        """
88
        if not self.exc_info:
89
            self.exc_info = exc_info
90
91
    def __enter__(self):
92
        """ once in context, only the propagate call is needed to use this
93
        class effectively
94
        """
95
        return self.propagate
96
97
    def __exit__(self, type, value, traceback):
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in type.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
98
        """ if we're holding on to an exception, raise it now
99
100
        prefers our held exception over any current raising error
101
102
        self.exc_info is reset now in case of nested manager shenanigans
103
        """
104
        if self.exc_info:
105
            type, value, traceback = self.exc_info
2 ignored issues
show
Bug introduced by
The tuple unpacking with sequence seems to be unbalanced; 3 value(s) for 0 label(s)

This happens when the amount of values does not equal the amount of labels:

a, b = ("a", "b", "c")  # only 2 labels for 3 values
Loading history...
Bug Best Practice introduced by
It seems like you are trying to unpack a non-sequence, which was defined at line 81.
Loading history...
Bug Best Practice introduced by
It seems like you are trying to unpack a non-sequence, which was defined at line 106.
Loading history...
106
            self.exc_info = None
107
        if type:
108
            # Python 2/3 compatible throw
109
            exception = type(value)
110
            exception.__traceback__ = traceback
111
            raise exception
112
113
class _CDataWrapper(object):
0 ignored issues
show
Coding Style introduced by
This class should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
114
115
    def __init__(self, *args, **kargs):
116
        self.cdata = self._get_cdata_from_args(*args, **kargs)
117
        if self.cdata == None:
118
            self.cdata = ffi.NULL
119
        super(_CDataWrapper, self).__init__()
120
121
    def _get_cdata_from_args(self, *args, **kargs):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
122
        if len(args) == 1 and isinstance(args[0], ffi.CData) and not kargs:
123
            return args[0]
124
        else:
125
            return None
126
127
128
    def __hash__(self):
129
        return hash(self.cdata)
130
131
    def __eq__(self, other):
132
        try:
133
            return self.cdata == other.cdata
134
        except AttributeError:
135
            return NotImplemented
136
137
    def __getattr__(self, attr):
138
        if 'cdata' in self.__dict__:
139
            return getattr(self.__dict__['cdata'], attr)
140
        raise AttributeError(attr)
141
142
    def __setattr__(self, attr, value):
143
        if hasattr(self, 'cdata') and hasattr(self.cdata, attr):
144
            setattr(self.cdata, attr, value)
145
        else:
146
            super(_CDataWrapper, self).__setattr__(attr, value)
147
148
def _assert_cdata_is_not_null(func):
149
    """Any BSP methods which use a cdata object in a TCOD call need to have
150
    a sanity check, otherwise it may end up passing a NULL pointer"""
151
    if __debug__:
152
        @_functools.wraps(func)
153
        def check_sanity(*args, **kargs):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
Unused Code introduced by
The variable check_sanity seems to be unused.
Loading history...
154
            assert self.cdata != ffi.NULL and self.cdata is not None, \
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'self'
Loading history...
155
                   'cannot use function, cdata is %r' % self.cdata
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'self'
Loading history...
156
            return func(*args, **kargs)
157
    return func
158
159
class BSP(object):
160
    """
161
162
163
    Attributes:
164
        x (int): Rectangle left coordinate.
165
        y (int): Rectangle top coordinate.
166
        width (int): Rectangle width.
167
        height (int): Rectangle height.
168
        level (int): This nodes depth.
169
        position (int): The integer of where the node was split.
170
        horizontal (bool): This nodes split orientation.
171
        parent (Optional[BSP]): This nodes parent or None
172
        children (Optional[Tuple[BSP, BSP]]):
173
            A tuple of (left, right) BSP instances, or
174
            None if this BSP has no children.
175
176
    Args:
177
        x (int): Rectangle left coordinate.
178
        y (int): Rectangle top coordinate.
179
        width (int): Rectangle width.
180
        height (int): Rectangle height.
181
182
    .. versionchanged:: 2.0
183
       You can create BSP's with this class contructor instead of using
184
       :any:`bsp_new_with_size`.
185
    """
186
187
    def __init__(self, x, y, width, height):
188
        self.x = x
189
        self.y = y
190
        self.width = width
191
        self.height = height
192
193
        self.level = 0
194
        self.position = 0
195
        self.horizontal = False
196
197
        self.parent = None
198
        self.children = ()
199
200
    @property
201
    def w(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
202
        return self.width
203
    @w.setter
204
    def w(self, value):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
205
        self.width = value
206
207
    @property
208
    def h(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
209
        return self.height
210
    @h.setter
211
    def h(self, value):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
212
        self.height = value
213
214
    def _as_cdata(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
215
        cdata = ffi.gc(lib.TCOD_bsp_new_with_size(self.x, self.y,
216
                                                  self.width, self.height),
217
                       lib.TCOD_bsp_delete)
218
        cdata.level = self.level
219
        return cdata
220
221
    def __str__(self):
222
        """Provide a useful readout when printed."""
223
        status = 'leaf'
224
        if self.children:
225
            status = ('split at position=%i,horizontal=%r' %
226
                      (self.position, self.horizontal))
227
228
        return ('<%s(x=%i,y=%i,width=%i,height=%i)level=%i,%s>' %
229
                (self.__class__.__name__,
230
                 self.x, self.y, self.width, self.height, self.level, status))
231
232
    def _unpack_bsp_tree(self, cdata):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
233
        self.x = cdata.x
234
        self.y = cdata.y
235
        self.width = cdata.w
236
        self.height = cdata.h
237
        self.level = cdata.level
238
        self.position = cdata.position
239
        self.horizontal = bool(cdata.horizontal)
240
        if lib.TCOD_bsp_is_leaf(cdata):
241
            return
242
        self.children = (BSP(0, 0, 0, 0), BSP(0, 0, 0, 0))
243
        self.children[0].parent = self
244
        self.children[0]._unpack_bsp_tree(lib.TCOD_bsp_left(cdata))
245
        self.children[1].parent = self
246
        self.children[1]._unpack_bsp_tree(lib.TCOD_bsp_right(cdata))
247
248
    def split_once(self, horizontal, position):
249
        """
250
251
        .. versionadded:: 2.0
252
        """
253
        cdata = self._as_cdata()
254
        lib.TCOD_bsp_split_once(cdata, horizontal, position)
255
        self._unpack_bsp_tree(cdata)
256
257
    def split_recursive(self, depth, min_width, min_height,
258
                        max_horizontal_ratio, max_vertical_raito, random=None):
259
        """
260
261
        .. versionadded:: 2.0
262
        """
263
        cdata = self._as_cdata()
264
        lib.TCOD_bsp_split_recursive(cdata, random or ffi.NULL,
265
                                      depth, min_width, min_height,
266
                                      max_horizontal_ratio, max_vertical_raito)
267
        self._unpack_bsp_tree(cdata)
268
269
    def walk(self):
270
        """Iterate over this BSP's hieracrhy.
271
272
        The iterator will include the instance which called it.
273
        It will traverse its own children and grandchildren, in no particular
274
        order.
275
276
        Returns:
277
            Iterator[BSP]: An iterator of BSP nodes.
278
279
        .. versionadded:: 2.0
280
        """
281
        return self._iter_post_order()
282
283
    def _iter_pre_order(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
284
        yield self
285
        for child in self.children:
286
            for grandchild in child._iter_pre_order():
287
                yield grandchild
288
289
    def _iter_in_order(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
290
        if self.children:
291
            for grandchild in self.children[0]._iter_in_order():
292
                yield grandchild
293
            yield self
294
            for grandchild in self.children[1]._iter_in_order():
295
                yield grandchild
296
        else:
297
            yield self
298
299
    def _iter_post_order(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
300
        for child in self.children:
301
            for grandchild in child._iter_post_order():
302
                yield grandchild
303
        yield self
304
305
    def _iter_level_order(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
306
        return sorted(self._iter_pre_order(), key=lambda n:n.level)
0 ignored issues
show
Coding Style introduced by
Exactly one space required after :
return sorted(self._iter_pre_order(), key=lambda n:n.level)
^
Loading history...
307
308
    def _iter_inverted_level_order(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
309
        return reversed(self._iter_level_order())
310
311
    def contains(self, x, y):
312
        """Returns True if this node contains these coordinates.
313
314
        Args:
315
            x (int): X position to check.
316
            y (int): Y position to check.
317
318
        Returns:
319
            bool: True if this node contains these coordinates.
320
                  Otherwise False.
321
322
        .. versionadded:: 2.0
323
        """
324
        return (self.x <= x < self.x + self.width and
325
                self.y <= y < self.y + self.height)
326
327
    def find_node(self, x, y):
328
        """Return the deepest node which contains these coordinates.
329
330
        Returns:
331
            Optional[BSP]: BSP object or None.
332
333
        .. versionadded:: 2.0
334
        """
335
        if not self.contains(x, y):
336
            return None
337
        for child in self.children:
338
            found = child.find_node(x, y)
339
            if found:
340
                return found
341
        return self
342
343
class Key(_CDataWrapper):
344
    """Key Event instance
345
346
    Attributes:
347
        vk (int): TCOD_keycode_t key code
348
        c (int): character if vk == TCODK_CHAR else 0
349
        text (Text): text[TCOD_KEY_TEXT_SIZE]; text if vk == TCODK_TEXT else text[0] == '\0'
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (92/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
350
        pressed (bool): does this correspond to a key press or key release event ?
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
351
        lalt (bool): True when left alt is held.
352
        lctrl (bool): True when left control is held.
353
        lmeta (bool): True when left meta key is held.
354
        ralt (bool): True when right alt is held.
355
        rctrl (bool): True when right control is held.
356
        rmeta (bool): True when right meta key is held.
357
        shift (bool): True when any shift is held.
358
    """
359
360
    _BOOL_ATTRIBUTES = ('lalt', 'lctrl', 'lmeta',
361
                        'ralt', 'rctrl', 'rmeta', 'pressed', 'shift')
362
363
    def __init__(self, *args, **kargs):
364
        super(Key, self).__init__(*args, **kargs)
365
        if self.cdata == ffi.NULL:
366
            self.cdata = ffi.new('TCOD_key_t*')
367
368
    def __getattr__(self, attr):
369
        if attr in self._BOOL_ATTRIBUTES:
370
            return bool(getattr(self.cdata, attr))
371
        if attr == 'c':
372
            return ord(getattr(self.cdata, attr))
373
        if attr == 'text':
374
            return _unpack_char_p(getattr(self.cdata, attr))
375
        return super(Key, self).__getattr__(attr)
376
377
class Mouse(_CDataWrapper):
378
    """Mouse event instance
379
380
    Attributes:
381
        x (int): Absolute mouse position at pixel x.
382
        y (int):
383
        dx (int): Movement since last update in pixels.
384
        dy (int):
385
        cx (int): Cell coordinates in the root console.
386
        cy (int):
387
        dcx (int): Movement since last update in console cells.
388
        dcy (int):
389
        lbutton (bool): Left button status.
390
        rbutton (bool): Right button status.
391
        mbutton (bool): Middle button status.
392
        lbutton_pressed (bool): Left button pressed event.
393
        rbutton_pressed (bool): Right button pressed event.
394
        mbutton_pressed (bool): Middle button pressed event.
395
        wheel_up (bool): Wheel up event.
396
        wheel_down (bool): Wheel down event.
397
    """
398
399
    def __init__(self, *args, **kargs):
400
        super(Mouse, self).__init__(*args, **kargs)
401
        if self.cdata == ffi.NULL:
402
            self.cdata = ffi.new('TCOD_mouse_t*')
403
404
class _ChBufferArray(_np.ndarray):
1 ignored issue
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
405
    """Numpy subclass designed to access libtcod's character buffer.
406
407
    This class needs to modify the char_t.cf attribute as a side effect so that
408
    libtcod will select the correct characters on flush.
409
    """
410
411
    def __new__(cls, ch_array, cf_array):
412
        self = ch_array.view(cls)
413
        self._cf_array = cf_array
414
        return self
415
416
    def __array_finalize__(self, obj):
417
        if obj is None:
418
            return
419
        self._cf_array = None
1 ignored issue
show
Coding Style introduced by
The attribute _cf_array was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
420
421
    def __repr__(self):
422
        return repr(self.view(_np.ndarray))
0 ignored issues
show
Bug introduced by
The Instance of _ChBufferArray does not seem to have a member named view.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
423
424
    def __getitem__(self, index):
425
        """Slicing this array also slices its _cf_array attribute."""
426
        array = _np.ndarray.__getitem__(self, index)
427
        if self._cf_array is None or array.size == 1:
428
            return array.view(_np.ndarray)
429
        array._cf_array = self._cf_array[index]
430
        return array
431
432
    def _covert_ch_to_cf(self, index, ch_arr):
433
        """Apply a set of Unicode variables to libtcod's special format.
434
435
        _cf_array should be the same shape as ch_arr after being sliced by
436
        index.
437
        """
438
        if lib.TCOD_ctx.max_font_chars == 0:
439
            return # libtcod not initialized
440
        ch_table = ffi.buffer(
441
            lib.TCOD_ctx.ascii_to_tcod[0:lib.TCOD_ctx.max_font_chars])
442
        ch_table = _np.frombuffer(ch_table, _np.intc)
443
        self._cf_array[index] = ch_table[ch_arr.ravel()].reshape(ch_arr.shape)
444
445
    def __setitem__(self, index, value):
446
        """Properly set up the char_t.cf variables as a side effect."""
447
        _np.ndarray.__setitem__(self, index, value)
448
        if self._cf_array is not None:
449
            self._covert_ch_to_cf(index, self[index])
450
451
class Console(_CDataWrapper):
452
    """
453
    Args:
454
        width (int): Width of the new Console.
455
        height (int): Height of the new Console.
456
457
    .. versionadded:: 2.0
458
    """
459
460
    def __init__(self, *args, **kargs):
0 ignored issues
show
Bug introduced by
The __init__ method of the super-class _CDataWrapper is not called.

It is generally advisable to initialize the super-class by calling its __init__ method:

class SomeParent:
    def __init__(self):
        self.x = 1

class SomeChild(SomeParent):
    def __init__(self):
        # Initialize the super class
        SomeParent.__init__(self)
Loading history...
461
        self.cdata = self._get_cdata_from_args(*args, **kargs)
462
        if self.cdata is None:
463
            self._init(*args, **kargs)
464
        self._init_setup_console_data()
465
466
    def _init(self, width, height):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
467
        self.cdata = ffi.gc(lib.TCOD_console_new(width, height),
468
                            lib.TCOD_console_delete)
469
470
    def _init_setup_console_data(self):
471
        """Setup numpy arrays over libtcod data buffers."""
472
        import numpy
0 ignored issues
show
Configuration introduced by
The import numpy could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
Unused Code introduced by
The variable numpy seems to be unused.
Loading history...
473
        if self.cdata == ffi.NULL:
474
            self._console_data = lib.TCOD_ctx.root
475
        else:
476
            self._console_data = ffi.cast('TCOD_console_data_t *', self.cdata)
477
478
        def unpack_color(image_cdata):
479
            """return a (height, width, 3) shaped array from an image struct"""
480
            color_data = lib.TCOD_image_get_colors(image_cdata)
481
            color_buffer = ffi.buffer(color_data[0:self.width * self.height])
482
            array = _np.frombuffer(color_buffer, _np.uint8)
483
            return array.reshape((self.height, self.width, 3))
484
485
        self._fg = unpack_color(self._console_data.state.fg_colors)
486
        self._bg = unpack_color(self._console_data.state.bg_colors)
487
488
        buf = self._console_data.state.buf
489
        buf = ffi.buffer(buf[0:self.width * self.height])
490
        if ffi.sizeof('char_t') != 12:
491
            # I'm expecting some compiler to have this at 9.
492
            raise RuntimeError("Expected ffi.sizeof('char_t') to be 12. "
493
                               "Got %i instead." % ffi.sizeof('char_t'))
494
        buf = _np.frombuffer(buf, [('c', _np.intc),
495
                                   ('cf', _np.intc),
496
                                   ('dirty', _np.intc)])
497
        self._buf = buf.reshape((self.height, self.width))
498
        self._ch = _ChBufferArray(self._buf['c'], self._buf['cf'])
499
500
    @property
501
    def width(self):
502
        """int: The width of this Console. (read-only)"""
503
        return lib.TCOD_console_get_width(self.cdata)
504
505
    @property
506
    def height(self):
507
        """int: The height of this Console. (read-only)"""
508
        return lib.TCOD_console_get_height(self.cdata)
509
510
    @property
511
    def bg(self):
512
        """A numpy array with the shape (height, width, 3).
513
514
        You can change the background color by using this array.
515
516
        Index this array with ``console.bg[y, x, channel]``
517
        """
518
        return self._bg
519
520
    @property
521
    def fg(self):
522
        """A numpy array with the shape (height, width, 3).
523
524
        You can change the foreground color by using this array.
525
526
        Index this array with ``console.fg[y, x, channel]``
527
        """
528
        return self._fg
529
530
    @property
531
    def ch(self):
532
        """A numpy array with the shape (height, width).
533
534
        You can change the character tiles by using this array.
535
536
        Index this array with ``console.ch[y, x]``
537
        """
538
        return self._ch
539
540
    @property
541
    def default_bg(self):
542
        """Tuple[int, int, int]: The default background color."""
543
        color = self._console_data.back
544
        return color.r, color.g, color.b
545
    @default_bg.setter
546
    def default_bg(self, color):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
547
        self._console_data.back = color
548
549
    @property
550
    def default_fg(self):
551
        """Tuple[int, int, int]: The default foreground color."""
552
        color = self._console_data.fore
553
        return color.r, color.g, color.b
554
    @default_fg.setter
555
    def default_fg(self, color):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
556
        self._console_data.fore = color
557
558
    @property
559
    def default_blend(self):
560
        """int: The default blending mode."""
561
        return self._console_data.bkgnd_flag
562
    @default_blend.setter
563
    def default_blend(self, value):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
564
        self._console_data.bkgnd_flag = value
565
566
    @property
567
    def default_alignment(self):
568
        """int: The default text alignment."""
569
        return self._console_data.alignment
570
    @default_alignment.setter
571
    def default_alignment(self, value):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
572
        self._console_data.alignment = value
573
574
    def clear(self):
575
        """Reset this console to its default colors and the space character.
576
        """
577
        lib.TCOD_console_clear(self.cdata)
578
579
    def put_char(self, x, y, ch, flag=BKGND_DEFAULT):
580
        """Draw the character c at x,y using the default colors and a blend mode.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (81/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
581
582
        Args:
583
            x (int): Character x position from the left.
584
            y (int): Character y position from the top.
585
            c (Union[int, AnyStr]): Character to draw, can be an integer or string.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
586
            flag (int): Blending mode to use, defaults to BKGND_DEFAULT.
587
        """
588
        lib.TCOD_console_put_char(self.cdata, x, y, _int(ch), flag)
589
590
    def put_char_ex(self, x, y, ch, fore, back):
591
        """Draw the character c at x,y using the colors fore and back.
592
593
        Args:
594
            x (int): Character x position from the left.
595
            y (int): Character y position from the top.
596
            c (Union[int, AnyStr]): Character to draw, can be an integer or string.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
597
            fore (Union[Tuple[int, int, int], Sequence[int]]):
598
                An (r, g, b) sequence or Color instance.
599
            back (Union[Tuple[int, int, int], Sequence[int]]):
600
                An (r, g, b) sequence or Color instance.
601
        """
602
        lib.TCOD_console_put_char_ex(self.cdata, x, y,
603
                                 _int(ch), fore, back)
604
605
    def set_char_bg(self, x, y, col, flag=BKGND_SET):
606
        """Change the background color of x,y to col using a blend mode.
607
608
        Args:
609
            x (int): Character x position from the left.
610
            y (int): Character y position from the top.
611
            col (Union[Tuple[int, int, int], Sequence[int]]):
612
                An (r, g, b) sequence or Color instance.
613
            flag (int): Blending mode to use, defaults to BKGND_SET.
614
        """
615
        lib.TCOD_console_set_char_background(self.cdata, x, y, col, flag)
616
617
    def set_char_fg(self, x, y, color):
0 ignored issues
show
Unused Code introduced by
The argument color seems to be unused.
Loading history...
618
        """Change the foreground color of x,y to col.
619
620
        Args:
621
            x (int): Character x position from the left.
622
            y (int): Character y position from the top.
623
            color (Union[Tuple[int, int, int], Sequence[int]]):
624
                An (r, g, b) sequence or Color instance.
625
        """
626
        lib.TCOD_console_set_char_foreground(self.cdata, x, y, col)
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'col'
Loading history...
627
628
    def set_char(self, x, y, ch):
629
        """Change the character at x,y to c, keeping the current colors.
630
631
        Args:
632
            x (int): Character x position from the left.
633
            y (int): Character y position from the top.
634
            c (Union[int, AnyStr]): Character to draw, can be an integer or string.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
635
        """
636
        lib.TCOD_console_set_char(self.cdata, x, y, _int(ch))
637
638
    def print_str(self, x, y, fmt):
639
        """Print a color formatted string on a console.
640
641
        Args:
642
            x (int): Character x position from the left.
643
            y (int): Character y position from the top.
644
            fmt (AnyStr): A unicode or bytes string optionaly using color codes.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (80/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
645
        """
646
        lib.TCOD_console_print_utf(self.cdata, x, y, _fmt_unicode(fmt))
647
648
    def print_ex(self, x, y, flag, alignment, fmt):
649
        """Print a string on a console using a blend mode and alignment mode.
650
651
        Args:
652
            x (int): Character x position from the left.
653
            y (int): Character y position from the top.
654
        """
655
        lib.TCOD_console_print_ex_utf(self.cdata, x, y,
656
                                      flag, alignment, _fmt_unicode(fmt))
657
658
    def print_rect(self, x, y, w, h, fmt):
0 ignored issues
show
Unused Code introduced by
The argument w seems to be unused.
Loading history...
Unused Code introduced by
The argument h seems to be unused.
Loading history...
659
        """Print a string constrained to a rectangle.
660
661
        If h > 0 and the bottom of the rectangle is reached,
662
        the string is truncated. If h = 0,
663
        the string is only truncated if it reaches the bottom of the console.
664
665
666
667
        Returns:
668
            int: The number of lines of text once word-wrapped.
669
        """
670
        return lib.TCOD_console_print_rect_utf(
671
            self.cdata, x, y, width, height, _fmt_unicode(fmt))
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'width'
Loading history...
Comprehensibility Best Practice introduced by
Undefined variable 'height'
Loading history...
672
673
    def print_rect_ex(self, x, y, w, h, flag, alignment, fmt):
0 ignored issues
show
Unused Code introduced by
The argument w seems to be unused.
Loading history...
Unused Code introduced by
The argument h seems to be unused.
Loading history...
674
        """Print a string constrained to a rectangle with blend and alignment.
675
676
        Returns:
677
            int: The number of lines of text once word-wrapped.
678
        """
679
        return lib.TCOD_console_print_rect_ex_utf(self.cdata,
680
            x, y, width, height, flag, alignment, _fmt_unicode(fmt))
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'width'
Loading history...
Comprehensibility Best Practice introduced by
Undefined variable 'height'
Loading history...
681
682
    def get_height_rect(self, x, y, width, height, fmt):
683
        """Return the height of this text once word-wrapped into this rectangle.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (80/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
684
685
        Returns:
686
            int: The number of lines of text once word-wrapped.
687
        """
688
        return lib.TCOD_console_get_height_rect_utf(
689
            self.cdata, x, y, width, height, _fmt_unicode(fmt))
690
691
    def rect(self, x, y, w, h, clr, flag=BKGND_DEFAULT):
692
        """Draw a the background color on a rect optionally clearing the text.
693
694
        If clr is True the affected tiles are changed to space character.
695
        """
696
        lib.TCOD_console_rect(self.cdata, x, y, w, h, clr, flag)
697
698
    def hline(self, x, y, width, flag=BKGND_DEFAULT):
699
        """Draw a horizontal line on the console.
700
701
        This always uses the character 196, the horizontal line character.
702
        """
703
        lib.TCOD_console_hline(self.cdata, x, y, width, flag)
704
705
    def vline(self, x, y, height, flag=BKGND_DEFAULT):
706
        """Draw a vertical line on the console.
707
708
        This always uses the character 179, the vertical line character.
709
        """
710
        lib.TCOD_console_vline(self.cdata, x, y, height, flag)
711
712
    def print_frame(self, x, y, w, h, clear=True, flag=BKGND_DEFAULT, fmt=b''):
713
        """Draw a framed rectangle with optinal text.
714
715
        This uses the default background color and blend mode to fill the
716
        rectangle and the default foreground to draw the outline.
717
718
        fmt will be printed on the inside of the rectangle, word-wrapped.
719
        """
720
        lib.TCOD_console_print_frame(self.cdata, x, y, w, h, clear, flag,
721
                                  _fmt_bytes(fmt))
722
723
    def blit(self, x, y, w, h,
724
             dest, dest_x, dest_y, fg_alpha=1, bg_alpha=1):
0 ignored issues
show
Unused Code introduced by
The argument dest seems to be unused.
Loading history...
725
        """Blit this console from x,y,w,h to the console dst at xdst,ydst."""
726
        lib.TCOD_console_blit(self.cdata, x, y, w, h,
727
                              _cdata(dst), dest_x, dest_y, fg_alpha, bg_alpha)
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'dst'
Loading history...
728
729
    def set_key_color(self, color):
730
        """Set a consoles blit transparent color."""
731
        lib.TCOD_console_set_key_color(self.cdata, color)
732
733
734
class Image(_CDataWrapper):
735
    """
736
    .. versionadded:: 2.0
737
738
    Args:
739
        width (int): Width of the new Image.
740
        height (int): Height of the new Image.
741
742
    Attributes:
743
        width (int): Read only width of this Image.
744
        height (int): Read only height of this Image.
745
    """
746
    def __init__(self, *args, **kargs):
747
        super(Image, self).__init__(*args, **kargs)
748
        if not self.cdata:
749
            self._init(*args, **kargs)
750
        self.width, self.height = self._get_size()
751
752
    def _init(self, width, height):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
753
        self.cdata = ffi.gc(lib.TCOD_image_new(width, height),
754
                            lib.TCOD_image_delete)
755
756
    def clear(self, color):
757
        """Fill this entire Image with color.
758
759
        Args:
760
            color (Union[Tuple[int, int, int], Sequence[int]]):
761
                An (r, g, b) sequence or Color instance.
762
        """
763
        lib.TCOD_image_clear(self.cdata, color)
764
765
    def invert(self):
766
        """Invert all colors in this Image."""
767
        lib.TCOD_image_invert(self.cdata)
768
769
    def hflip(self):
770
        """Horizontally flip this Image."""
771
        lib.TCOD_image_hflip(self.cdata)
772
773
    def rotate90(self, rotations=1):
774
        """Rotate this Image clockwise in 90 degree steps.
775
776
        Args:
777
            rotations (int): Number of 90 degree clockwise rotations.
778
        """
779
        lib.TCOD_image_rotate90(self.cdata, rotations)
780
781
    def vflip(self):
782
        """Vertically flip this Image."""
783
        lib.TCOD_image_vflip(self.cdata)
784
785
    def scale(self, width, height):
786
        """Scale this Image to the new width and height.
787
788
        Args:
789
            width (int): The new width of the Image after scaling.
790
            height (int): The new height of the Image after scaling.
791
        """
792
        lib.TCOD_image_scale(self.cdata, width, height)
793
        self.width, self.height = width, height
794
795
    def set_key_color(self, color):
796
        """Set a color to be transparent during blitting functions.
797
798
        Args:
799
            color (Union[Tuple[int, int, int], Sequence[int]]):
800
                An (r, g, b) sequence or Color instance.
801
        """
802
        lib.TCOD_image_set_key_color(self.cdata, color)
803
804
    def get_alpha(self, x, y):
805
        """Get the Image alpha of the pixel at x, y.
806
807
        Args:
808
            x (int): X pixel of the image.  Starting from the left at 0.
809
            y (int): Y pixel of the image.  Starting from the top at 0.
810
811
        Returns:
812
            int: The alpha value of the pixel.
813
            With 0 being fully transparent and 255 being fully opaque.
814
        """
815
        return lib.TCOD_image_get_alpha(self.cdata, x, y)
816
817
    def refresh_console(self, console):
818
        """Update an Image created with :any:`tcod.image_from_console`.
819
820
        The console used with this function should have the same width and
821
        height as the Console given to :any:`tcod.image_from_console`.
822
        The font width and height must also be the same as when
823
        :any:`tcod.image_from_console` was called.
824
825
        Args:
826
            console (Console): A Console with a pixel width and height
827
                               matching this Image.
828
        """
829
        lib.TCOD_image_refresh_console(self.cdata, _cdata(console))
830
831
    def _get_size(self):
832
        """Return the (width, height) for this Image.
833
834
        Returns:
835
            Tuple[int, int]: The (width, height) of this Image
836
        """
837
        w = ffi.new('int *')
838
        h = ffi.new('int *')
839
        lib.TCOD_image_get_size(self.cdata, w, h)
840
        return w[0], h[0]
841
842
    def get_pixel(self, x, y):
843
        """Get the color of a pixel in this Image.
844
845
        Args:
846
            x (int): X pixel of the Image.  Starting from the left at 0.
847
            y (int): Y pixel of the Image.  Starting from the top at 0.
848
849
        Returns:
850
            Tuple[int, int, int]:
851
                An (r, g, b) tuple containing the pixels color value.
852
                Values are in a 0 to 255 range.
853
        """
854
        return lib.TCOD_image_get_pixel(self.cdata, x, y)
855
856
    def get_mipmap_pixel(self, left, top, right, bottom):
857
        """Get the average color of a rectangle in this Image.
858
859
        Parameters should stay within the following limits:
860
        * 0 <= left < right < Image.width
861
        * 0 <= top < bottom < Image.height
862
863
        Args:
864
            left (int): Left corner of the region.
865
            top (int): Top corner of the region.
866
            right (int): Right corner of the region.
867
            bottom (int): Bottom corner of the region.
868
869
        Returns:
870
            Tuple[int, int, int]:
871
                An (r, g, b) tuple containing the averaged color value.
872
                Values are in a 0 to 255 range.
873
        """
874
        color = lib.TCOD_image_get_mipmap_pixel(self.cdata,
875
                                                left, top, right, bottom)
876
        return (color.r, color.g, color.b)
877
878
    def put_pixel(self, x, y, color):
879
        """Change a pixel on this Image.
880
881
        Args:
882
            x (int): X pixel of the Image.  Starting from the left at 0.
883
            y (int): Y pixel of the Image.  Starting from the top at 0.
884
            color (Union[Tuple[int, int, int], Sequence[int]]):
885
                An (r, g, b) sequence or Color instance.
886
        """
887
        lib.TCOD_image_put_pixel(self.cdata, x, y, color)
888
889
    def blit(self, console, x, y, bg_blend, scale_x, scale_y, angle):
890
        """Blit onto a Console using scaling and rotation.
891
892
        Args:
893
            console (Console): Blit destination Console.
894
            x (int): Console X position for the center of the Image blit.
895
            y (int): Console Y position for the center of the Image blit.
896
                     The Image blit is centered on this position.
897
            bg_blend (int): Background blending mode to use.
898
            scale_x (float): Scaling along Image x axis.
899
                             Set to 1 for no scaling.  Must be over 0.
900
            scale_y (float): Scaling along Image y axis.
901
                             Set to 1 for no scaling.  Must be over 0.
902
            angle (float): Rotation angle in radians. (Clockwise?)
903
        """
904
        lib.TCOD_image_blit(self.cdata, _cdata(console), x, y, bg_blend,
905
                            scale_x, scale_y, angle)
906
907
    def blit_rect(self, console, x, y, width, height, bg_blend):
908
        """Blit onto a Console without scaling or rotation.
909
910
        Args:
911
            console (Console): Blit destination Console.
912
            x (int): Console tile X position starting from the left at 0.
913
            y (int): Console tile Y position starting from the top at 0.
914
            width (int): Use -1 for Image width.
915
            height (int): Use -1 for Image height.
916
            bg_blend (int): Background blending mode to use.
917
        """
918
        lib.TCOD_image_blit_rect(self.cdata, _cdata(console),
919
                                 x, y, width, height, bg_blend)
920
921
    def blit_2x(self, console, dest_x, dest_y,
922
                img_x=0, img_y=0, img_width=-1, img_height=-1):
923
        """Blit onto a Console with double resolution.
924
925
        Args:
926
            console (Console): Blit destination Console.
927
            dest_x (int): Console tile X position starting from the left at 0.
928
            dest_y (int): Console tile Y position starting from the top at 0.
929
            img_x (int): Left corner pixel of the Image to blit
930
            img_y (int): Top corner pixel of the Image to blit
931
            img_width (int): Width of the Image to blit.
932
                             Use -1 for the full Image width.
933
            img_height (int): Height of the Image to blit.
934
                              Use -1 for the full Image height.
935
        """
936
        lib.TCOD_image_blit_2x(self.cdata, _cdata(console), dest_x, dest_y,
937
                               img_x, img_y, img_width, img_height)
938
939
    def save_as(self, filename):
940
        """Save the Image to a 32-bit .bmp or .png file.
941
942
        Args:
943
            filename (AnyStr): File path to same this Image.
944
        """
945
        lib.TCOD_image_save(self.cdata, _bytes(filename))
946
947
class Random(_CDataWrapper):
948
    """
949
    .. versionadded:: 2.0
950
951
    If all you need is a random number generator then it's recommended
952
    that you use the :any:`random` module from the Python standard library.
953
954
    Args:
955
        seed (Hashable): The RNG seed.  Should be a 32-bit integer, but any
956
                         hashable object is accepted.
957
        algorithm (int): The algorithm to use.
958
    """
959
    def __init__(self, *args, **kargs):
960
        super(Random, self).__init__(*args, **kargs)
961
        if not self.cdata:
962
            self._init(*args, **kargs)
963
964
    def _init(self, seed, algorithm):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
965
        self.cdata = ffi.gc(lib.TCOD_random_new_from_seed(algorithm,
966
                                                          hash(seed)),
967
                            lib.TCOD_random_delete)
968
969
970
    def random_int(self, low, high, mean=None):
971
        """Return a random integer from a linear or triangular range.
972
973
        Args:
974
            low (int): The lower bound of the random range, inclusive.
975
            high (int): The upper bound of the random range, inclusive.
976
            mean (Optional[int]): The mean return value, or None.
977
978
        Returns:
979
            int: A random number from the given range: low <= n <= high.
980
        """
981
        lib.TCOD_random_set_distribution(self.cdata,
982
                                         lib.TCOD_DISTRIBUTION_LINEAR)
983
        if mean is None:
984
            return lib.TCOD_random_get_int(self.cdata, low, high)
985
        return lib.TCOD_random_get_int_mean(self.cdata, low, high, mean)
986
987
988
    def random_float(self, low, high, mean=None):
989
        """Return a random float from a linear or triangular range.
990
991
        Args:
992
            low (float): The lower bound of the random range.
993
            high (float): The upper bound of the random range.
994
            mean (Optional[float]): The mean return value, or None.
995
996
        Returns:
997
            float: A random number from the given range: low <= n <= high.
998
        """
999
        lib.TCOD_random_set_distribution(self.cdata,
1000
                                         lib.TCOD_DISTRIBUTION_LINEAR)
1001
        if mean is None:
1002
            return lib.TCOD_random_get_double(self.cdata, low, high)
1003
        return lib.TCOD_random_get_double_mean(self.cdata, low, high, mean)
1004
1005
    def gaussian(self, mu, sigma):
1006
        """Return a number from a random gaussian distribution.
1007
1008
        Args:
1009
            mu (float): The mean returned value.
1010
            sigma (float): The standard deviation.
1011
1012
        Returns:
1013
            float: A random number derived from the given parameters.
1014
        """
1015
        lib.TCOD_random_set_distribution(self.cdata,
1016
                                         lib.TCOD_DISTRIBUTION_GAUSSIAN)
1017
        return lib.TCOD_random_get_double(self.cdata, mu, sigma)
1018
1019
    def inverse_gaussian(self, mu, sigma):
1020
        """Return a number from a random inverse gaussian distribution.
1021
1022
        Args:
1023
            mu (float): The mean returned value.
1024
            sigma (float): The standard deviation.
1025
1026
        Returns:
1027
            float: A random number derived from the given parameters.
1028
        """
1029
        lib.TCOD_random_set_distribution(self.cdata,
1030
            lib.TCOD_DISTRIBUTION_GAUSSIAN_INVERSE)
1031
        return lib.TCOD_random_get_double(self.cdata, mu, sigma)
1032
1033
    def gaussian_range(self, low, high, mean=None):
1034
        """Return a random gaussian number clamped to a range.
1035
1036
        When ``mean`` is None it will be automatically determined
1037
        from the ``low`` and ``high`` parameters.
1038
1039
        Args:
1040
            low (float): The lower bound of the random range.
1041
            high (float): The upper bound of the random range.
1042
            mean (Optional[float]): The mean return value, or None.
1043
1044
        Returns:
1045
            float: A clamped gaussian number.
1046
        """
1047
        lib.TCOD_random_set_distribution(self.cdata,
1048
            lib.TCOD_DISTRIBUTION_GAUSSIAN_RANGE)
1049
        if mean is None:
1050
            return lib.TCOD_random_get_double(self.cdata, low, high)
1051
        return lib.TCOD_random_get_double_mean(self.cdata, low, high, mean)
1052
1053
    def inverse_gaussian_range(self, low, high, mean=None):
1054
        """Return a random inverted gaussian number clamped to a range.
1055
1056
        When ``mean`` is None it will be automatically determined
1057
        from the ``low`` and ``high`` parameters.
1058
1059
        Args:
1060
            low (float): The lower bound of the random range.
1061
            high (float): The upper bound of the random range.
1062
            mean (Optional[float]): The mean return value, or None.
1063
1064
        Returns:
1065
            float: A clamped inverse gaussian number.
1066
        """
1067
        lib.TCOD_random_set_distribution(self.cdata,
1068
            lib.TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE)
1069
        if mean is None:
1070
            return lib.TCOD_random_get_double(self.cdata, low, high)
1071
        return lib.TCOD_random_get_double_mean(self.cdata, low, high, mean)
1072
1073
    # TODO: Eventually add these functions:
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
1074
    #def save(self):
1075
    #    return ffi.gc(lib.TCOD_random_save(self.cdata),
1076
    #                  lib.TCOD_random_delete)
1077
    #def restore(self, backup):
1078
    #    lib.TCOD_random_restore(self.cdata, backup)
1079
1080
NOISE_IMP_SIMPLE = 0
1081
NOISE_IMP_FBM = 1
1082
NOISE_IMP_TURBULENCE = 2
1083
1084
class Noise(_CDataWrapper):
1085
    """
1086
    .. versionadded:: 2.0
1087
1088
    The ``hurst`` exponent describes the raggedness of the resultant noise,
1089
    with a higher value leading to a smoother noise.
1090
    Not used with NOISE_IMP_SIMPLE.
1091
1092
    ``lacunarity`` is a multiplier that determines how fast the noise
1093
    frequency increases for each successive octave.
1094
    Not used with NOISE_IMP_SIMPLE.
1095
1096
    Args:
1097
        dimentions (int): Must be from 1 to 4.
1098
        algorithm (int): Defaults to NOISE_SIMPLEX
1099
        implementation (int): Defaults to NOISE_IMP_SIMPLE
1100
        hurst (float): The hurst exponent.  Should be in the 0.0-1.0 range.
1101
        lacunarity (float): The noise lacunarity.
1102
        octaves (float): The level of detail on fBm and turbulence
1103
                         implementations.
1104
        rand (Optional[Random]): A Random instance, or None.
1105
    """
1106
    def __init__(self, *args, **kargs):
1107
        self.octaves = 4
1108
        self.implementation = NOISE_IMP_SIMPLE
1109
        self._cdata_random = None # keep alive the random cdata instance
1110
        self._algorithm = None
1111
        self._dimentions = None
1112
        self._hurst = None
1113
        self._lacunarity = None
1114
        super(Noise, self).__init__(*args, **kargs)
1115
        if not self.cdata:
1116
            self._init(*args, **kargs)
1117
1118
    def _init(self, dimentions, algorithm=2, implementation=NOISE_IMP_SIMPLE,
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1119
              hurst=0.5, lacunarity=2.0, octaves=4, rand=None):
1120
        self._cdata_random = _cdata(rand)
1121
        self.implementation = implementation
1122
        self._dimentions = dimentions
1123
        self._hurst = hurst
1124
        self._lacunarity = lacunarity
1125
        self.octaves = octaves
1126
        self.cdata = ffi.gc(lib.TCOD_noise_new(self._dimentions, self._hurst,
1127
                                               self._lacunarity,
1128
                                               self._cdata_random),
1129
                            lib.TCOD_noise_delete)
1130
        self.algorithm = algorithm
1131
1132
    @property
1133
    def algorithm(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1134
        return self._algorithm
1135
    @algorithm.setter
1136
    def algorithm(self, value):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1137
        self._algorithm = value
1138
        lib.TCOD_noise_set_type(self.cdata, value)
1139
1140
    @property
1141
    def dimentions(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1142
        return self._dimentions
1143
1144
    @property
1145
    def hurst(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1146
        return self._hurst
1147
1148
    @property
1149
    def lacunarity(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1150
        return self._lacunarity
1151
1152
    def get_point(self, x=0, y=0, z=0, w=0):
1153
        """Return the noise value at the (x, y, z, w) point.
1154
1155
        Args:
1156
            x (float): The position on the 1st axis.
1157
            y (float): The position on the 2nd axis.
1158
            z (float): The position on the 3rd axis.
1159
            w (float): The position on the 4th axis.
1160
        """
1161
        if self.implementation == NOISE_IMP_SIMPLE:
1162
            return lib.TCOD_noise_get(self.cdata, (x, y, z, w))
1163
        elif self.implementation == NOISE_IMP_FBM:
1164
            return lib.TCOD_noise_get_fbm(self.cdata, (x, y, z, w),
1165
                                          self.octaves)
1166
        elif self.implementation == NOISE_IMP_TURBULENCE:
1167
            return lib.TCOD_noise_get_turbulence(self.cdata, (x, y, z, w),
1168
                                                 self.octaves)
1169
        raise RuntimeError('implementation must be one of tcod.NOISE_IMP_*')
1170
1171
class Map(_CDataWrapper):
1172
    """
1173
    .. versionadded:: 2.0
1174
1175
    Args:
1176
        width (int): Width of the new Map.
1177
        height (int): Height of the new Map.
1178
1179
    Attributes:
1180
        width (int): Read only width of this Map.
1181
        height (int): Read only height of this Map.
1182
    """
1183
1184
    def __init__(self, *args, **kargs):
1185
        super(Map, self).__init__(*args, **kargs)
1186
        if not self.cdata:
1187
            self._init(*args, **kargs)
1188
1189
        self.width = lib.TCOD_map_get_width(self.cdata)
1190
        self.height = lib.TCOD_map_get_width(self.cdata)
1191
1192
    def _init(self, width, height):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1193
        self.cdata = ffi.gc(lib.TCOD_map_new(width, height),
1194
                            lib.TCOD_map_delete)
1195
1196
    def set_properties(self, x, y, transparent, walkable):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1197
        lib.TCOD_map_set_properties(self.cdata, x, y, transparent, walkable)
1198
1199
    def clear(self, transparent, walkable):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1200
        lib.TCOD_map_clear(self.cdata, transparent, walkable)
1201
1202
    def compute_fov(self, x, y, radius=0, light_walls=True,
1203
                    algorithm=lib.FOV_RESTRICTIVE):
1204
        """
1205
1206
        Args:
1207
            x (int):
1208
            y (int):
1209
            radius (int):
1210
            light_walls (bool):
1211
            algorithm (int): Defaults to FOV_RESTRICTIVE
1212
        """
1213
        lib.TCOD_map_compute_fov(self.cdata, x, y, radius, light_walls,
1214
                                 algorithm)
1215
1216
    def is_fov(self, x, y):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1217
        return lib.TCOD_map_is_in_fov(self.cdata, x, y)
1218
1219
    def is_transparent(self, x, y):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1220
        return lib.TCOD_map_is_transparent(self.cdata, x, y)
1221
1222
    def is_walkable(self, x, y):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1223
        return lib.TCOD_map_is_walkable(self.cdata, x, y)
1224
1225
1226
class _PathFinder(object):
1227
    """
1228
    .. versionadded:: 2.0
1229
    """
1230
1231
    def __init__(self):
1232
        self.width = None
1233
        self.height = None
1234
        self.diagonal_cost = None
1235
        self.cdata = None
1236
        self.handle = None
1237
        self.map_obj = None
1238
1239
    @classmethod
1240
    def new_with_map(cls, tcod_map, diagonal_cost=1.41):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1241
        self = cls()
1242
        self.width = tcod_map.width
1243
        self.height = tcod_map.height
1244
        self.diagonal_cost = diagonal_cost
1245
1246
        self.map_obj = tcod_map
1247
        self.cdata = ffi.gc(
1248
            self._path_new_using_map(tcod_map.cdata, diagonal_cost),
1249
            self._path_delete)
1250
        return self
1251
1252
    @classmethod
1253
    def new_with_callback(cls, width, height, callback, diagonal_cost=1.41):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1254
        self = cls()
1255
        self.width = width
1256
        self.height = height
1257
        self.diagonal_cost = diagonal_cost
1258
1259
        self.handle = ffi.new_handle(callback)
1260
        self.cdata = ffi.gc(
1261
            self._path_new_using_function(
1262
                width, height, lib._pycall_path_simple,
1263
                self.handle, diagonal_cost),
1264
            self._path_delete)
1265
        return self
1266
1267
    @classmethod
1268
    def _new_with_callback_old(cls, width, height, callback, diagonal_cost,
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
1269
                               userData):
1270
        self = cls()
1271
        self.width = width
1272
        self.height = height
1273
        self.diagonal_cost = diagonal_cost
1274
1275
        self.handle = ffi.new_handle((callback, userData))
1276
        self.cdata = ffi.gc(
1277
            self._path_new_using_function(
1278
                width, height, lib._pycall_path_old,
1279
                self.handle, diagonal_cost),
1280
            self._path_delete)
1281
        return self
1282
1283
1284
    _path_new_using_map = lib.TCOD_path_new_using_map
1285
    _path_new_using_function = lib.TCOD_path_new_using_function
1286
    _path_delete = lib.TCOD_path_delete
1287
1288
1289
class AStar(_PathFinder):
1290
    """
1291
    .. versionadded:: 2.0
1292
    """
1293
1294
    def get_path(self, start_x, start_y, goal_x, goal_y):
1295
        """Return a list of (x, y) steps to reach the goal point, if possible.
1296
1297
        Args:
1298
            start_x (int): Starting X position.
1299
            start_y (int): Starting Y position.
1300
            goal_x (int): Destination X position.
1301
            goal_y (int): Destination Y position.
1302
        Returns:
1303
            List[Tuple[int, int]]:
1304
                A list of points, or an empty list if there is no valid path.
1305
        """
1306
        lib.TCOD_path_compute(self.cdata, start_x, start_y, goal_x, goal_y)
1307
        path = []
1308
        x = ffi.new('int[2]')
1309
        y = x + 1
1310
        while lib.TCOD_path_walk(self.cdata, x, y, False):
1311
            path.append((x[0], y[0]))
1312
        return path
1313
1314
1315
class Dijkstra(_PathFinder):
1316
    """
1317
    .. versionadded:: 2.0
1318
    """
1319
1320
    _path_new_using_map = lib.TCOD_dijkstra_new
1321
    _path_new_using_function = lib.TCOD_dijkstra_new_using_function
1322
    _path_delete = lib.TCOD_dijkstra_delete
1323
1324
    def set_goal(self, x, y):
1325
        """Set the goal point and recompute the Dijkstra path-finder.
1326
        """
1327
        lib.TCOD_dijkstra_compute(self.cdata, x, y)
1328
1329
    def get_path(self, x, y):
1330
        """Return a list of (x, y) steps to reach the goal point, if possible.
1331
        """
1332
        lib.TCOD_dijkstra_path_set(self.cdata, x, y)
1333
        path = []
1334
        pointer_x = ffi.new('int[2]')
1335
        pointer_y = pointer_x + 1
1336
        while lib.TCOD_dijkstra_path_walk(self.cdata, pointer_x, pointer_y):
1337
            path.append(pointer_x[0], pointer_y[0])
1338
        return path
1339
1340
1341
def clipboard_set(string):
1342
    """Set the clipboard contents to string.
1343
1344
    Args:
1345
        string (AnyStr): A Unicode or UTF-8 encoded string.
1346
1347
    .. versionadded:: 2.0
1348
    """
1349
    lib.TCOD_sys_clipboard_set(_bytes(string))
1350
1351
def clipboard_get():
1352
    """Return the current contents of the clipboard.
1353
1354
    Returns:
1355
        Text: The clipboards current contents.
1356
1357
    .. versionadded:: 2.0
1358
    """
1359
    return _unpack_char_p(lib.TCOD_sys_clipboard_get())
1360
1361
__all__ = [_name for _name in list(globals()) if _name[0] != '_']
1362