Fix bits and add new action.
[naja.git] / naja / player.py
1 from naja.constants import BITS
2
3
4 class PlayerBits(object):
5     """
6     A glorified byte.
7     """
8
9     def __init__(self, bits):
10         self.bits = bits
11
12     @property
13     def bits(self):
14         return self._bits
15
16     @bits.setter
17     def bits(self, value):
18         assert 0 <= value <= 0xff
19         self._bits = value
20
21     # Operate on individual bits
22
23     def check_bit(self, bit):
24         return bool(self.bits & (1 << bit))
25
26     def set_bit(self, bit):
27         self.bits |= (1 << bit)
28
29     def clear_bit(self, bit):
30         self.bits &= (0xff ^ (1 << bit))
31
32     def toggle_bit(self, bit):
33         self.bits ^= (1 << bit)
34
35     # Operate on sets of bits
36
37     def check_bits(self, bits):
38         return all(self.check_bit(bit) for bit in bits)
39
40     def set_bits(self, bits):
41         for bit in bits:
42             self.set_bit(bit)
43
44     def clear_bits(self, bits):
45         for bit in bits:
46             self.clear_bit(bit)
47
48     def toggle_bits(self, bits):
49         for bit in bits:
50             self.toggle_bit(bit)
51
52
53 class Player(object):
54     """
55     A representation of the player.
56     """
57
58     def __init__(self, bits, position):
59         self.bits = PlayerBits(bits)
60         self.position = position
61
62     @classmethod
63     def import_player(cls, definition):
64         return cls(definition['bits'], tuple(definition['position']))
65
66     def export(self):
67         return {
68             'bits': self.bits.bits,
69             'position': list(self.position),
70         }
71
72     def move(self, direction):
73         if not self.bits.check_bit(direction):
74             return False
75         # TODO: Something cleaner than this.
76         x, y = self.position
77         if direction == BITS.NORTH:
78             if y > 0 and self.bits.check_bit(BITS.NORTH):
79                 self.position = (x, y - 1)
80                 return True
81         elif direction == BITS.SOUTH:
82             if y < 4 and self.bits.check_bit(BITS.SOUTH):
83                 self.position = (x, y + 1)
84                 return True
85         elif direction == BITS.EAST:
86             if x < 4 and self.bits.check_bit(BITS.EAST):
87                 self.position = (x + 1, y)
88                 return True
89         elif direction == BITS.WEST:
90             if x > 0 and self.bits.check_bit(BITS.WEST):
91                 self.position = (x - 1, y)
92                 return True
93
94         return False