import random import radio from microbit import display, Image, button_a, button_b, pin0, running_time class Utils: @staticmethod def deepcopy(arr): return [row[:] for row in arr] @staticmethod def build_img(arr): result = "" for subarr in arr: for item in subarr: result += str(item) result += ":" return Image(result) class Player: x = 2 y = 4 health = 9 last_changed = running_time() def __init__(self): radio.send('EP {}'.format(self.x)) def allowed_to_move(self): return running_time() - self.last_changed > 200 def act(self, frame: Image): if self.allowed_to_move(): if button_a.is_pressed(): self.x = max(self.x - 1, 0) radio.send("EP {}".format(self.x)) self.last_changed = running_time() elif button_b.is_pressed(): self.x = min(self.x + 1, 4) radio.send("EP {}".format(self.x)) self.last_changed = running_time() frame.set_pixel(self.x, self.y, self.health) return frame class RemotePlayer: last_position = None health = 9 def act(self, frame: Image, msg): if msg is not None: if 'EP' in msg: try: self.last_position = int(msg.lstrip('EP').strip()) except: pass if self.last_position is not None: frame.set_pixel(self.last_position, 0, self.health) return frame class BulletStorm: last_changed = running_time() last_shot = running_time() player_bullet_positions = [] enemy_bullet_positions = [] def __init__(self, player: Player, remote: RemotePlayer): self.player = player self.remote = remote def allowed_to_move(self): return running_time() - self.last_changed > 100 def allowed_to_fire(self): return running_time() - self.last_shot > 1000 def act(self, frame: Image, msg): if self.allowed_to_move(): for bullet in self.player_bullet_positions: bullet[1] -= 1 if bullet[1] == 0 and bullet[0] == self.remote.last_position: self.remote.health -= 1 for bullet in self.enemy_bullet_positions: bullet[1] += 1 if bullet[1] == 4 and bullet[0] == self.player.x: self.player.health -= 1 self.last_changed = running_time() self.player_bullet_positions = list(filter(lambda position: position[1] >= 0, self.player_bullet_positions)) self.enemy_bullet_positions = list(filter(lambda position: position[1] < 5, self.enemy_bullet_positions)) if self.allowed_to_fire(): radio.send("FR") self.player_bullet_positions.append([int(self.player.x), 3]) self.last_shot = running_time() if msg is not None and msg == 'FR' and self.remote.last_position is not None: self.enemy_bullet_positions.append([int(self.remote.last_position), 1]) for bullet in self.player_bullet_positions + self.enemy_bullet_positions: frame.set_pixel(bullet[0], bullet[1], 5) return frame empty_frame = [ [0] * 5, [0] * 5, [0] * 5, [0] * 5, [0] * 5, ] radio.on() radio.config(data_rate=radio.RATE_2MBIT, length=8) player = Player() remote_player = RemotePlayer() bulletstorm = BulletStorm(player, remote_player) while True: message = radio.receive() new_frame = Utils.build_img(empty_frame) new_frame = player.act(new_frame) new_frame = remote_player.act(new_frame, message) new_frame = bulletstorm.act(new_frame, message) if player.health < 1 or message == 'won': radio.send('lost') display.clear() display.scroll('You loose!') display.show(Image.SAD) break if remote_player.health < 1 or message == 'lost': radio.send('won') display.clear() display.scroll('You won!') display.show(Image.HAPPY) break display.show(new_frame) if pin0.is_touched(): display.clear() break radio.off()