Beispiel #1
0
 def decode(self):
     super().decode()
     self.eid = self._buffer.next_long()
     x = self._buffer.next_int()
     z = self._buffer.next_int()
     y = self._buffer.next_byte()
     self.pos = Position(x, z, y)
Beispiel #2
0
 def load(self, conn, player_id):
     c = conn.cursor()
     param = (str(player_id), )
     c.execute("SELECT * FROM player WHERE player_id=?", param)
     row = c.fetchone()
     if row == None:
         player = None
     else:
         player = PlayerEntity(int(player_id), None, None, None)
         player.name = str(row['name'], encoding='utf8')
         player.pos = Position(row['x'], row['z'], row['y'])
         player.injury = row['injury']
         player.air = row['air']
         player.spawn_pos = Position(row['spawn_x'], row['spawn_z'],
                                     row['spawn_y'])
     c.close()
     return player
Beispiel #3
0
 def __init__(self, player_id, public_id, skin_name, skin):
     super().__init__()
     self.spawn_pos = Position(0, 0, 0)
     self.opening_container = 0
     self._player_id = player_id
     self._public_id = public_id
     self._skin_name = skin_name
     self._skin = skin
     self._meta.set(MetaData.Key.SHOW_NAMETAG, 1)
     self._meta.set(MetaData.Key.PLAYER_BED_POSITION, Position(0, 0, 0))
     self._meta.set(MetaData.Key.POTION_COLOR, 0)
     self._meta.set(MetaData.Key.POTION_AMBIENT, 0)
     self._meta.set(MetaData.Key.PLAYER_FLAGS, 0)
     self._slots = InventoryContainer()
     self._armor_slots = ArmorContainer()
     self._hotbar = [self.HOTBAR_NONE] * self.NUM_OF_HOTBAR
     self._held_hotbar = 0
Beispiel #4
0
 def load_all(self, conn):
     c = conn.cursor()
     c.execute("SELECT * FROM sign")
     for row in c:
         sign = Sign(Position(row['x'], row['z'], row['y']))
         sign.named_tag = row['named_tag']
         yield sign
     c.close()
Beispiel #5
0
 def load_all(self, conn):
     c = conn.cursor()
     c.execute("SELECT * FROM furnace")
     for row in c:
         furnace = Furnace(Position(row['x'], row['z'], row['y']),
                           row['window_id'])
         yield furnace
     c.close()
Beispiel #6
0
 def load_all(self, conn):
     c = conn.cursor()
     c.execute("SELECT * FROM chest")
     for row in c:
         chest = Chest(Position(row['x'], row['z'], row['y']),
                       row['window_id'])
         yield chest
     c.close()
Beispiel #7
0
 def intercection(p, q, v):
     x, z = MotionLaw.axis(p.x, v.x), MotionLaw.axis(p.z, v.z)
     b = q.x * p.z - p.x * q.z
     r_x = Position(x, (x * v.z + b) / v.x, q.y) if x != None else None
     r_z = Position((z * v.x - b) / v.z, z, q.y) if z != None else None
     if r_x == None:
         return r_z
     if r_z == None:
         return r_x
     return r_x if r_x.distance(p) < r_z.distance(p) else r_z
Beispiel #8
0
 def add(self, player, seed):
     """新しいプレイヤーを追加する
     
     データストアにデータがある場合には
     データストアのデータをマージする。
     """
     player_id = player.player_id
     stored_player = self._datastore.load_player(player_id)
     if stored_player == None:
         player.spawn_pos = Position(128, 128, 71)
         player.spawn()
     else:
         player.copy_from(stored_player)
         if not player.is_living():
             player.spawn()
     player.meet_callback = self._hit_callback
     player.lose_callback = self._lose_callback
     self._players[player_id] = player
     self._entity.add(player)
     self._listener.player_loggedin(player, seed)
Beispiel #9
0
 def _move(self, mob):
     # AIから情報を受け取る
     m = self._ai_process.recv(mob.eid)
     if m == None:
         return None
     # 名前を変更
     old_name = mob.name
     mob.name = m.name
     if mob.name != old_name:
         self._listener.entity_changed(mob.eid, mob.meta)
     # 相対値から絶対値に変換
     yaw = mob.yaw + m.yaw
     head_yaw = mob.head_yaw + m.yaw + m.head_yaw
     pitch = mob.pitch + m.pitch
     # 前進する
     abs_fm = abs(m.forward_move)
     if abs_fm > self.MAX_MOVEMENT:
         forward_move = m.forward_move/abs_fm * self.MAX_MOVEMENT
     else:
         forward_move = m.forward_move
     d = Vector.by_angle(
         forward_move, yaw, (pitch if mob.can_fly() else None))
     pos = mob.pos + d
     # 動いた先に Chunk がなければ動かない
     if not self._terrain.map.has_chunk(mob.BODY_SIZE.lower_bounds(pos)):
         return None
     # 地形にあわせて上下に移動する
     if not mob.can_fly():
         pos = self._move_y(mob, pos)
         pos = self._push_back(mob, pos, forward_move)
         if mob.pos.y - pos.y > 1 and mob.can_climb():
             pos = Position(pos.x,pos.z,mob.pos.y-1)
     # 動作を通知する
     motion = Motion(mob.eid, pos, yaw, head_yaw, pitch)
     if motion == mob.motion:
         return None
     return motion
Beispiel #10
0
    def test_angle_v(self):
        p0 = Position(100, 100, 60)  # center
        pe = Position(150, 100, 60)  # 東
        pw = Position(50, 100, 60)  # 西
        ps = Position(100, 150, 60)  # 南
        pn = Position(100, 50, 60)  # 北

        p0u = Position(100, 100, 110)  # 上
        peu = Position(150, 100, 110)  # 東上
        pwu = Position(50, 100, 110)  # 西上
        psu = Position(100, 150, 110)  # 南上
        pnu = Position(100, 50, 110)  # 北上

        p0d = Position(100, 100, 10)  # 下
        ped = Position(150, 100, 10)  # 東下
        pwd = Position(50, 100, 10)  # 西下
        psd = Position(100, 150, 10)  # 南下
        pnd = Position(100, 50, 10)  # 北下

        self.assertAlmostEquals(p0.angle_v(p0, 0), 0)
        self.assertAlmostEquals(p0.angle_v(ps, 0), 0)
        self.assertAlmostEquals(p0.angle_v(pw, 0), 0)
        self.assertAlmostEquals(p0.angle_v(pn, 0), 0)
        self.assertAlmostEquals(p0.angle_v(pe, 0), 0)

        self.assertAlmostEquals(p0.angle_v(p0u, 0), 90)
        self.assertAlmostEquals(p0.angle_v(psu, 0), 45)
        self.assertAlmostEquals(p0.angle_v(pwu, 0), 45)
        self.assertAlmostEquals(p0.angle_v(pnu, 0), 45)
        self.assertAlmostEquals(p0.angle_v(peu, 0), 45)

        self.assertAlmostEquals(p0.angle_v(p0d, 0), -90)
        self.assertAlmostEquals(p0.angle_v(psd, 0), -45)
        self.assertAlmostEquals(p0.angle_v(pwd, 0), -45)
        self.assertAlmostEquals(p0.angle_v(pnd, 0), -45)
        self.assertAlmostEquals(p0.angle_v(ped, 0), -45)

        self.assertAlmostEquals(p0.angle_v(p0, 45), 0)
        self.assertAlmostEquals(p0.angle_v(ps, 45), -45)
        self.assertAlmostEquals(p0.angle_v(p0, 90), 0)
        self.assertAlmostEquals(p0.angle_v(pw, 90), -90)
        self.assertAlmostEquals(p0.angle_v(p0, -45), 0)
        self.assertAlmostEquals(p0.angle_v(pn, -45), 45)
        self.assertAlmostEquals(p0.angle_v(p0, -90), 0)
        self.assertAlmostEquals(p0.angle_v(pe, -90), 90)

        self.assertAlmostEquals(p0.angle_v(p0u, 45), 45)
        self.assertAlmostEquals(p0.angle_v(psu, 45), 0)
        self.assertAlmostEquals(p0.angle_v(p0u, 90), 0)
        self.assertAlmostEquals(p0.angle_v(pwu, 90), -45)
        self.assertAlmostEquals(p0.angle_v(p0u, -45), 135)
        self.assertAlmostEquals(p0.angle_v(pnu, -45), 90)
        self.assertAlmostEquals(p0.angle_v(p0u, -90), 180)
        self.assertAlmostEquals(p0.angle_v(peu, -90), 135)

        self.assertAlmostEquals(p0.angle_v(p0d, 45), -135)
        self.assertAlmostEquals(p0.angle_v(psd, 45), -90)
        self.assertAlmostEquals(p0.angle_v(p0d, 90), -180)
        self.assertAlmostEquals(p0.angle_v(pwd, 90), -135)
        self.assertAlmostEquals(p0.angle_v(p0d, -45), -45)
        self.assertAlmostEquals(p0.angle_v(pnd, -45), 0)
        self.assertAlmostEquals(p0.angle_v(p0d, -90), 0)
        self.assertAlmostEquals(p0.angle_v(ped, -90), 45)
Beispiel #11
0
 def reset(self, x=False, z=False, y=False):
     px = self._center_pos.x if x else self._cur_pos.x
     pz = self._center_pos.z if z else self._cur_pos.z
     py = self._center_pos.y if y else self._cur_pos.y
     self._cur_pos = Position(px, pz, py)
Beispiel #12
0
 def _can_move_up(self, mob, pos):
     for x, z, y in mob.BODY_SIZE.lower_bounds(pos):
         y += mob.BODY_SIZE.height
         if not self._terrain.is_transparent(Position(x,z,y)):
             return False
     return True
Beispiel #13
0
 def has_collision(p):
     for y in range(int(p.y), int(p.y+mob.BODY_SIZE.height+1)):
         if not self._terrain.is_transparent(Position(p.x, p.z, y)):
             return True
     return False
Beispiel #14
0
 def _move_y(self, mob, pos):
     def get_y():
         return (self._terrain.get_ground_pos(p.astype(int)).y 
             for p in mob.BODY_SIZE.lower_bounds(pos))
     y = max(get_y())
     return Position(pos.x, pos.z,y) if y - pos.y <= 1 else pos
Beispiel #15
0
    def test_angle_h_01(self):
        p0 = Position(100, 100, 64)  # center
        pe = Position(150, 100, 64)  # 東
        pw = Position(50, 100, 64)  # 西
        ps = Position(100, 150, 64)  # 南
        pn = Position(100, 50, 64)  # 北
        pu = Position(100, 100, 127)  # 上
        pd = Position(100, 100, 0)  # 下

        # yaw 南
        self.assertAlmostEqual(p0.angle_h(ps, 0), 0)
        self.assertAlmostEqual(p0.angle_h(pw, 0), 90)
        self.assertAlmostEqual(p0.angle_h(pn, 0), 180)
        self.assertAlmostEqual(p0.angle_h(pe, 0), -90)

        # yaw 西
        self.assertAlmostEqual(p0.angle_h(ps, 90), -90)
        self.assertAlmostEqual(p0.angle_h(pw, 90), 0)
        self.assertAlmostEqual(p0.angle_h(pn, 90), 90)
        self.assertAlmostEqual(p0.angle_h(pe, 90), -180)

        # yaw 北
        self.assertAlmostEqual(p0.angle_h(ps, 180), -180)
        self.assertAlmostEqual(p0.angle_h(pw, 180), -90)
        self.assertAlmostEqual(p0.angle_h(pn, 180), 0)
        self.assertAlmostEqual(p0.angle_h(pe, 180), 90)

        # yaw 東
        self.assertAlmostEqual(p0.angle_h(ps, 270), 90)
        self.assertAlmostEqual(p0.angle_h(pw, 270), -180)
        self.assertAlmostEqual(p0.angle_h(pn, 270), -90)
        self.assertAlmostEqual(p0.angle_h(pe, 270), 0)

        # yaw 南
        self.assertAlmostEqual(p0.angle_h(ps, 360), 0)
        self.assertAlmostEqual(p0.angle_h(pw, 360), 90)
        self.assertAlmostEqual(p0.angle_h(pn, 360), -180)
        self.assertAlmostEqual(p0.angle_h(pe, 360), -90)

        # yaw 西
        self.assertAlmostEqual(p0.angle_h(ps, 450), -90)
        self.assertAlmostEqual(p0.angle_h(pw, 450), 0)
        self.assertAlmostEqual(p0.angle_h(pn, 450), 90)
        self.assertAlmostEqual(p0.angle_h(pe, 450), -180)

        # yaw 東
        self.assertAlmostEqual(p0.angle_h(ps, -90), 90)
        self.assertAlmostEqual(p0.angle_h(pw, -90), 180)
        self.assertAlmostEqual(p0.angle_h(pn, -90), -90)
        self.assertAlmostEqual(p0.angle_h(pe, -90), 0)

        self.assertAlmostEqual(p0.angle_h(p0, 0), None)

        self.assertAlmostEqual(p0.angle_h(pu, 0), None)
        self.assertAlmostEqual(p0.angle_h(pu, 90), None)
        self.assertAlmostEqual(p0.angle_h(pu, 180), None)
        self.assertAlmostEqual(p0.angle_h(pu, 270), None)
        self.assertAlmostEqual(p0.angle_h(pu, 360), None)
        self.assertAlmostEqual(p0.angle_h(pu, 450), None)
        self.assertAlmostEqual(p0.angle_h(pu, -90), None)

        self.assertAlmostEqual(p0.angle_h(pd, 0), None)
        self.assertAlmostEqual(p0.angle_h(pd, 90), None)
        self.assertAlmostEqual(p0.angle_h(pd, 180), None)
        self.assertAlmostEqual(p0.angle_h(pd, 270), None)
        self.assertAlmostEqual(p0.angle_h(pd, 360), None)
        self.assertAlmostEqual(p0.angle_h(pd, 450), None)
        self.assertAlmostEqual(p0.angle_h(pd, -90), None)
Beispiel #16
0
    def test_intersection_01(self):
        p0 = Position(100.5, 100.5, 60.5)

        self.assertEqual(p0.intersection(p0), None)

        pn = Position(100.5, 99.5, 60.5)
        ps = Position(100.5, 101.5, 60.5)
        pw = Position(99.5, 100.5, 60.5)
        pe = Position(101.5, 100.5, 60.5)
        pd = Position(100.5, 100.5, 59.5)
        pu = Position(100.5, 100.5, 61.5)

        self.assertPositionEqual(p0.intersection(pn), (100.5, 100, 60.5))
        self.assertPositionEqual(p0.intersection(ps), (100.5, 101, 60.5))
        self.assertPositionEqual(p0.intersection(pw), (100, 100.5, 60.5))
        self.assertPositionEqual(p0.intersection(pe), (101, 100.5, 60.5))
        self.assertPositionEqual(p0.intersection(pd), (100.5, 100.5, 60))
        self.assertPositionEqual(p0.intersection(pu), (100.5, 100.5, 61))

        # 境界線上
        pn = Position(100.5, 100, 60.5)
        ps = Position(100.5, 101, 60.5)
        pw = Position(100, 100.5, 60.5)
        pe = Position(101, 100.5, 60.5)
        pd = Position(100.5, 100.5, 60)
        pu = Position(100.5, 100.5, 61)

        self.assertPositionEqual(p0.intersection(pn), (100.5, 100, 60.5))
        self.assertPositionEqual(p0.intersection(ps), (100.5, 101, 60.5))
        self.assertPositionEqual(p0.intersection(pw), (100, 100.5, 60.5))
        self.assertPositionEqual(p0.intersection(pe), (101, 100.5, 60.5))
        self.assertPositionEqual(p0.intersection(pd), (100.5, 100.5, 60))
        self.assertPositionEqual(p0.intersection(pu), (100.5, 100.5, 61))

        # 2マス以上離れている点
        pn = Position(100.5, 98, 60.5)
        ps = Position(100.5, 103, 60.5)
        pw = Position(98, 100.5, 60.5)
        pe = Position(103, 100.5, 60.5)
        pd = Position(100.5, 100.5, 58)
        pu = Position(100.5, 100.5, 63)

        self.assertPositionEqual(p0.intersection(pn), (100.5, 100, 60.5))
        self.assertPositionEqual(p0.intersection(ps), (100.5, 101, 60.5))
        self.assertPositionEqual(p0.intersection(pw), (100, 100.5, 60.5))
        self.assertPositionEqual(p0.intersection(pe), (101, 100.5, 60.5))
        self.assertPositionEqual(p0.intersection(pd), (100.5, 100.5, 60))
        self.assertPositionEqual(p0.intersection(pu), (100.5, 100.5, 61))

        pnd = Position(100.5, 99.5, 59.5)
        psd = Position(100.5, 101.5, 59.5)
        pwd = Position(99.5, 100.5, 59.5)
        ped = Position(101.5, 100.5, 59.5)

        self.assertPositionEqual(p0.intersection(pnd), (100.5, 100, 60))
        self.assertPositionEqual(p0.intersection(psd), (100.5, 101, 60))
        self.assertPositionEqual(p0.intersection(pwd), (100, 100.5, 60))
        self.assertPositionEqual(p0.intersection(ped), (101, 100.5, 60))

        pnu = Position(100.5, 99.5, 61.5)
        psu = Position(100.5, 101.5, 61.5)
        pwu = Position(99.5, 100.5, 61.5)
        peu = Position(101.5, 100.5, 61.5)

        self.assertPositionEqual(p0.intersection(pnu), (100.5, 100, 61))
        self.assertPositionEqual(p0.intersection(psu), (100.5, 101, 61))
        self.assertPositionEqual(p0.intersection(pwu), (100, 100.5, 61))
        self.assertPositionEqual(p0.intersection(peu), (101, 100.5, 61))

        pnwd = Position(99.5, 99.5, 59.5)
        pned = Position(101.5, 99.5, 59.5)
        pswd = Position(99.5, 101.5, 59.5)
        psed = Position(101.5, 101.5, 59.5)

        self.assertPositionEqual(p0.intersection(pnwd), (100, 100, 60))
        self.assertPositionEqual(p0.intersection(pned), (101, 100, 60))
        self.assertPositionEqual(p0.intersection(pswd), (100, 101, 60))
        self.assertPositionEqual(p0.intersection(psed), (101, 101, 60))

        pnwu = Position(99.5, 99.5, 61.5)
        pneu = Position(101.5, 99.5, 61.5)
        pswu = Position(99.5, 101.5, 61.5)
        pseu = Position(101.5, 101.5, 61.5)

        self.assertPositionEqual(p0.intersection(pnwu), (100, 100, 61))
        self.assertPositionEqual(p0.intersection(pneu), (101, 100, 61))
        self.assertPositionEqual(p0.intersection(pswu), (100, 101, 61))
        self.assertPositionEqual(p0.intersection(pseu), (101, 101, 61))
Beispiel #17
0
    def test_angle_h_02(self):
        p0 = Position(100, 100, 64)  # center
        pse = Position(150, 150, 64)  # 南東
        psw = Position(50, 150, 64)  # 南西
        pne = Position(150, 50, 64)  # 北東
        pnw = Position(50, 50, 64)  # 北西

        self.assertAlmostEqual(p0.angle_h(pse, 0), -45)
        self.assertAlmostEqual(p0.angle_h(pse, -45), 0)
        self.assertAlmostEqual(p0.angle_h(pse, -90), 45)

        self.assertAlmostEqual(p0.angle_h(psw, 90), -45)
        self.assertAlmostEqual(p0.angle_h(psw, 45), 0)
        self.assertAlmostEqual(p0.angle_h(psw, 0), 45)

        self.assertAlmostEqual(p0.angle_h(pne, -90), -45)
        self.assertAlmostEqual(p0.angle_h(pne, -135), 0)
        self.assertAlmostEqual(p0.angle_h(pne, -180), 45)

        self.assertAlmostEqual(p0.angle_h(pnw, 180), -45)
        self.assertAlmostEqual(p0.angle_h(pnw, 135), 0)
        self.assertAlmostEqual(p0.angle_h(pnw, 90), 45)
Beispiel #18
0
    def test_on_lay(self):
        p0 = Position(100.5, 100.5, 60.5)

        p1 = Position(102.5, 100.5, 60.5)
        self.assertLayEqual(p0.on_lay(p1), [(101, 100, 60), (102, 100, 60)])

        p1 = Position(102.5, 102.5, 60.5)
        self.assertLayEqual(p0.on_lay(p1), [(101, 100, 60), (100, 101, 60),
                                            (101, 101, 60), (102, 101, 60),
                                            (101, 102, 60), (102, 102, 60)])

        p1 = Position(102.5, 102.5, 62.5)
        self.assertLayEqual(p0.on_lay(p1), [(101, 100, 60), (100, 101, 60),
                                            (100, 100, 61), (101, 101, 60),
                                            (101, 100, 61), (100, 101, 61),
                                            (101, 101, 61), (102, 101, 61),
                                            (101, 102, 61), (101, 101, 62),
                                            (102, 102, 61), (102, 101, 62),
                                            (101, 102, 62), (102, 102, 62)])

        p0 = Position(100, 100.5, 60.5)
        p1 = Position(102, 100.5, 60.5)
        self.assertLayEqual(p0.on_lay(p1), [(101, 100, 60), (102, 100, 60)])

        p0 = Position(100, 100, 60.5)
        p1 = Position(102, 102, 60.5)
        self.assertLayEqual(p0.on_lay(p1), [(101, 100, 60), (100, 101, 60),
                                            (101, 101, 60), (102, 101, 60),
                                            (101, 102, 60), (102, 102, 60)])

        p0 = Position(100, 100, 60)
        p1 = Position(102, 102, 62)
        self.assertLayEqual(p0.on_lay(p1), [(101, 100, 60), (100, 101, 60),
                                            (100, 100, 61), (101, 101, 60),
                                            (101, 100, 61), (100, 101, 61),
                                            (101, 101, 61), (102, 101, 61),
                                            (101, 102, 61), (101, 101, 62),
                                            (102, 102, 61), (102, 101, 62),
                                            (101, 102, 62), (102, 102, 62)])
Beispiel #19
0
    def test_intersection_02(self):
        p0 = Position(100, 100.5, 60.5)

        self.assertEqual(p0.intersection(p0), None)

        pn = Position(100, 99.5, 60.5)
        ps = Position(100, 101.5, 60.5)
        pw = Position(99, 100.5, 60.5)
        pe = Position(101, 100.5, 60.5)
        pd = Position(100, 100.5, 59.5)
        pu = Position(100, 100.5, 61.5)

        self.assertPositionEqual(p0.intersection(pn), (100, 100, 60.5))
        self.assertPositionEqual(p0.intersection(ps), (100, 101, 60.5))
        self.assertPositionEqual(p0.intersection(pw), (100, 100.5, 60.5))
        self.assertPositionEqual(p0.intersection(pe), (100, 100.5, 60.5))
        self.assertPositionEqual(p0.intersection(pd), (100, 100.5, 60))
        self.assertPositionEqual(p0.intersection(pu), (100, 100.5, 61))

        p0 = Position(100.5, 100, 60.5)

        self.assertEqual(p0.intersection(p0), None)

        pn = Position(100.5, 99, 60.5)
        ps = Position(100.5, 101, 60.5)
        pw = Position(99.5, 100, 60.5)
        pe = Position(101.5, 100, 60.5)
        pd = Position(100.5, 100, 59.5)
        pu = Position(100.5, 100, 61.5)

        self.assertPositionEqual(p0.intersection(pn), (100.5, 100, 60.5))
        self.assertPositionEqual(p0.intersection(ps), (100.5, 100, 60.5))
        self.assertPositionEqual(p0.intersection(pw), (100, 100, 60.5))
        self.assertPositionEqual(p0.intersection(pe), (101, 100, 60.5))
        self.assertPositionEqual(p0.intersection(pd), (100.5, 100, 60))
        self.assertPositionEqual(p0.intersection(pu), (100.5, 100, 61))

        p0 = Position(100.5, 100.5, 60)

        self.assertEqual(p0.intersection(p0), None)

        pn = Position(100.5, 99.5, 60)
        ps = Position(100.5, 101.5, 60)
        pw = Position(99.5, 100.5, 60)
        pe = Position(101.5, 100.5, 60)
        pd = Position(100.5, 100.5, 59)
        pu = Position(100.5, 100.5, 61)

        self.assertPositionEqual(p0.intersection(pn), (100.5, 100, 60))
        self.assertPositionEqual(p0.intersection(ps), (100.5, 101, 60))
        self.assertPositionEqual(p0.intersection(pw), (100, 100.5, 60))
        self.assertPositionEqual(p0.intersection(pe), (101, 100.5, 60))
        self.assertPositionEqual(p0.intersection(pd), (100.5, 100.5, 60))
        self.assertPositionEqual(p0.intersection(pu), (100.5, 100.5, 60))

        p0 = Position(100, 100, 60.5)

        self.assertEqual(p0.intersection(p0), None)

        pn = Position(100, 99, 60.5)
        ps = Position(100, 101, 60.5)
        pw = Position(99, 100, 60.5)
        pe = Position(101, 100, 60.5)
        pd = Position(100, 100, 59.5)
        pu = Position(100, 100, 61.5)

        self.assertPositionEqual(p0.intersection(pn), (100, 100, 60.5))
        self.assertPositionEqual(p0.intersection(ps), (100, 100, 60.5))
        self.assertPositionEqual(p0.intersection(pw), (100, 100, 60.5))
        self.assertPositionEqual(p0.intersection(pe), (100, 100, 60.5))
        self.assertPositionEqual(p0.intersection(pd), (100, 100, 60))
        self.assertPositionEqual(p0.intersection(pu), (100, 100, 61))

        p0 = Position(100, 100, 60)

        self.assertEqual(p0.intersection(p0), None)

        pn = Position(100, 99, 60)
        ps = Position(100, 101, 60)
        pw = Position(99, 100, 60)
        pe = Position(101, 100, 60)
        pd = Position(100, 100, 59)
        pu = Position(100, 100, 61)

        self.assertPositionEqual(p0.intersection(pn), (100, 100, 60))
        self.assertPositionEqual(p0.intersection(ps), (100, 100, 60))
        self.assertPositionEqual(p0.intersection(pw), (100, 100, 60))
        self.assertPositionEqual(p0.intersection(pe), (100, 100, 60))
        self.assertPositionEqual(p0.intersection(pd), (100, 100, 60))
        self.assertPositionEqual(p0.intersection(pu), (100, 100, 60))