Commits

Pierre-Marie de Rodat  committed 4afd622

Test: greatly improved tiny bot to move randomly, even vertically.

This bot still hangs sometimes, but should not crash. When it appears to be
stuck somewhere, just restart it.

  • Participants
  • Parent commits a481974

Comments (0)

Files changed (1)

File test_real.py

     def __init__(self, username):
         super(MyClient, self).__init__(username)
         self.is_ready = threading.Event()
+        self.speed = 0
 
     def connect(self, address):
         super(MyClient, self).connect(address)
     def handle_spawnposition(self, packet):
         super(MyClient, self).handle_spawnposition(packet)
 
+    def handle_playerpositionlook(self, packet):
+        super(MyClient, self).handle_playerpositionlook(packet)
+        print '\x1b[34mGot playerpositionlook… centering and changing direction\x1b[0m'
+        self.player.center()
+        self.generate_destination()
+
     def handle_chat(self, packet):
         pass
 
     def handle_gravity(self):
         p = self.player
         chunk = p.get_chunk()
+        if chunk is None:
+            return False
+
         x, y, z = (
-            int(p.x) & 0xF, int(p.y), int(p.z) & 0xF
+            int(p.x) & 0xF, int(math.floor(p.y)), int(p.z) & 0xF
         )
-        print 'Before:', p.y
         bottom = chunk.get((x, y, z))
         under = chunk.get((x, y - 1, z))
+        print 'Blocks where I am: %s/%s' % (hex(bottom.type), hex(under.type))
         stable = False
+
         if bottom.type == 0 and under.type == 0:
-            print 'Im falling'
+            print '\x1b[32mFloating in void, going down\x1b[0m (to %s)' % p.y
             p.set_position(y=p.y - 0.3)
             p.on_ground = False
         elif bottom.type != 0:
-            print 'Im in solid, going up'
+            print '\x1b[32m*IN* the ground: going up\x1b[0m (to %s)' % p.y
             p.set_position(y=p.y + 0.1)
         elif under.type != 0:
-            print 'Im on ground'
+            print '\x1b[32mOn the ground\x1b[0m (%s, %s, %s)' % (p.x, p.y, p.z)
+            p.set_position(y=y)
             p.on_groud = True
             stable = True
-        print 'After:', p.y
+
         self.put_packet(p.get_position_packet())
         return stable
 
+    def generate_destination(self):
+        possible_destinations = [
+            (-1, 0, 0), (1, 0, 0), (0, 0, -1), (0, 0, 1),
+            (-1, -1, 0), (1, -1, 0), (0, -1, -1), (0, -1, 1),
+            (-1, 1, 0), (1, 1, 0), (0, 1, -1), (0, 1, 1),
+        ]
+        random.shuffle(possible_destinations)
+        for dx, dy, dz in possible_destinations:
+            dest_x = self.player.x + dx
+            dest_y = self.player.y + dy
+            dest_z = self.player.z + dz
+            if not self.is_walkable(dest_x, dest_y, dest_z):
+                continue
+            self.speed = 0.4
+            self.dx, self.dy, self.dz = dx, dy, dz
+            self.wanted_position = (dest_x, dest_y, dest_z)
+            self.start_position = (self.player.x, self.player.y, self.player.z)
+            print '\x1b[31mChanging direction\x1b[0m: %s, %s, %s' % (
+                dest_x, dest_y, dest_z
+            )
+            return True
+        print '\x1b[31mNo possible destination...\x1b[0m'
+        self.speed = 0
+        return False
+
+    def is_walkable(self, x, y, z):
+        x, y, z = int(x), int(y), int(z)
+        chunk = self.map.get((x >> 4, z >> 4))
+        if chunk is None:
+            return False
+        bx, by, bz = (x & 0x0F, y, z & 0x0F)
+        top, bottom, under = (
+            chunk.get((bx, by + 1, bz)),
+            chunk.get((bx, by, bz)),
+            chunk.get((bx, by - 1, bz)),
+        )
+        print 'Destination (%s, %s, %s) contains %s %s %s' % (
+            x, y, z,
+            top.type, bottom.type, under.type
+        )
+        return (top.type == 0 and bottom.type == 0 and under.type != 0)
+
+    def walk(self):
+        if not self.handle_gravity():
+            return False
+        if self.speed == 0:
+            self.generate_destination()
+            return False
+
+        if (
+            abs(self.player.x - self.wanted_position[0]) < 0.2 and
+            abs(self.player.z - self.wanted_position[2]) < 0.2
+        ):
+            # We arrived!
+            print self.player.x, self.wanted_position[0]
+            print self.player.y, self.wanted_position[1]
+            print self.player.z, self.wanted_position[2]
+            return True
+        nx, ny, nz = (
+            self.player.x + self.dx * self.speed,
+            self.player.y,
+            self.player.z + self.dz * self.speed
+        )
+
+        if self.is_walkable(nx, ny, nz):
+            # We stand on the ground and the destination is free: we can walk!
+            self.player.set_position(x=nx, y=ny, z=nz)
+            print 'Walking to (%s, %s, %s)' % (nx, ny, nz)
+        elif self.is_walkable(nx, ny + self.dy, nz):
+            self.player.set_position(x=nx, y=ny + self.dy, z=nz)
+            self.dy = 0
+            print 'Walking to (%s, %s, %s) (changed Y!)' % (nx, ny, nz)
+        else:
+            # The previously planned destination has become unreachable: go
+            # back to the center of the block then chose a new destination.
+            print 'I can no longer walk in this direction'
+            self.player.set_position(
+                x=self.start_position[0],
+                y=self.start_position[1],
+                z=self.start_position[2],
+            )
+            self.player.center()
+            self.generate_destination()
+        self.put_packet(self.player.get_position_packet())
+        return False
+
 
 
 def main():
     try:
         c.connect((host, int(port)))
         c.is_ready.wait()
-        speed = 0.3
-        dx, dz = 0, speed
-        p = c.player
         while True:
-            stable = c.handle_gravity()
-            nx, nz = p.x + dx, p.z + dz
-            chunk = c.map.get((int(nx) >> 4, int(nz) >> 4))
-            can_walk = False
-            if stable and chunk is not None:
-                print 'my chunk is not None'
-                x, y, z = (
-                    int(nx) & 0xF,
-                    int(p.y),
-                    int(nz) & 0xF
-                )
-                top, bottom, under = (
-                    chunk.get((x, y + 1, z)),
-                    chunk.get((x, y, z)),
-                    chunk.get((x, y - 1, z)),
-                )
-                can_walk = (
-                    top.type == 0 and bottom.type == 0 and under.type != 0
-                )
-            else:
-                print 'my chunk is None'
-            if can_walk:
-                # The way is free: walk
-                print 'I can walk!'
-                p.set_position(x=nx, z=nz)
-                c.put_packet(p.get_position_packet())
-            elif stable:
-                print '\x1b[31mChanging direction\x1b[0m'
-                p.set_position(x=nx, z=nz)
-                direction = random.random() * math.pi
-                dx = math.sin(direction) * speed
-                dz = math.cos(direction) * speed
-            time.sleep(.1)
+            if c.walk():
+                print '\x1b[33mArrived!\x1b[0m'
+                c.generate_destination()
+            time.sleep(.2)
         c.put_packet(packet.Disconnect(reason='Goodbye!'))
         time.sleep(1)
         c.close()