Пример #1
0
    def __init__(self, pin, length):
        self._effect = Effects.RGB
        self._thread = None
        self._thread_terminate = False
        self._thread_running = False
        self.pixels = neopixel.NeoPixel(pin, length)
        self._length = length
        self.pixels[0] = (0, 255, 0)
        self.colour = Colour(0, 0, 20)
        self.paused = False
        self._brightness = 1.0

        for i in range(1, length):
            self.pixels[i] = (0, 0, 20)

        self._backup = []
        self._temperature_pixels = []

        self.save_period = Config.TIME_TO_SAVE
        self.restore_timer = MyTimer(self.save_period, self.restore)
        self.dim_timer = MyTimer(self.save_period, self._dim)

        for i in range(0, self._length):
            self._backup.append(self.pixels[i])

        self._prepare_temperature_pixels()

        self.saved = False
Пример #2
0
    def __init__(self, settings, stats, screen, *args):
        """初始化靶机并设置其起始位置"""
        TargetSample.__init__(self)
        Sprite.__init__(self)
        self.settings = settings
        self.screen = screen
        self.stats = stats
        self.screen_rect = screen.get_rect()
        self.args = args
        self.target_shield_image = pygame.image.load(
            dir_path + r'\images\target_shield.png')

        # 靶机初始位置
        self.rect.x = self.settings.x_target_position + args[
            0] * self.rect.width * 2
        self.rect.y = self.settings.y_target_boundary

        # 存储靶机准确位置
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)

        self.timer = MyTimer()
        self.shield_timer = MyTimer()
        self.moving = False

        self.delay = self.args[4]  # 靶机延时启动时长
        if self.args[3]:  # 带盾
            self.image = self.target_shield_image
            self.life = 2
        else:  # 无盾
            self.life = 1
Пример #3
0
 def __init__(self, settings, screen, target):
     super().__init__()
     self.settings = settings
     self.screen = screen
     self.rect = pygame.Rect(target.rect.left, target.rect.bottom,
                             target.rect.width, 3)
     self.y = float(self.rect.y)
     self.color = (0, 0, 0)
     self.speed = 3
     self.timer = MyTimer()
Пример #4
0
class NoticeBar(Sprite):
    """靶机启动提示条"""
    def __init__(self, settings, screen, target):
        super().__init__()
        self.settings = settings
        self.screen = screen
        self.rect = pygame.Rect(target.rect.left, target.rect.bottom,
                                target.rect.width, 3)
        self.y = float(self.rect.y)
        self.color = (0, 0, 0)
        self.speed = 3
        self.timer = MyTimer()

    def update(self):
        """向下移动提示条"""
        if self.speed != 0:
            if self.y >= self.screen.get_rect(
            ).bottom - self.settings.y_target_boundary:  # 到达底端时停止移动
                self.speed = 0
            else:
                self.y += self.speed
                self.rect.y = self.y

    def draw_bar(self):
        """绘制提示条"""
        pygame.draw.rect(self.screen, self.color, self.rect)

    def start_timer(self):
        self.timer.begin()

    def stop_timer(self):
        self.timer.stop()

    def reset_timer(self):
        self.timer.reset()
Пример #5
0
class Indicator:
    def __init__(self, pin, length):
        self._effect = Effects.RGB
        self._thread = None
        self._thread_terminate = False
        self._thread_running = False
        self.pixels = neopixel.NeoPixel(pin, length)
        self._length = length
        self.pixels[0] = (0, 255, 0)
        self.colour = Colour(0, 0, 20)
        self.paused = False
        self._brightness = 1.0

        for i in range(1, length):
            self.pixels[i] = (0, 0, 20)

        self._backup = []
        self._temperature_pixels = []

        self.save_period = Config.TIME_TO_SAVE
        self.restore_timer = MyTimer(self.save_period, self.restore)
        self.dim_timer = MyTimer(self.save_period, self._dim)

        for i in range(0, self._length):
            self._backup.append(self.pixels[i])

        self._prepare_temperature_pixels()

        self.saved = False

    def set_mode(self, mode):
        self.stop_loop()
        print("Mode: ", format(mode.value))
        if mode == Effects.FIRE:
            self._start_fire(55, 80, 0.01)
        if mode == Effects.METEOR:
            self._start_meteor(255, 0, 255, 6, 64, 0.01)
        if mode == Effects.CYLON:
            self._start_cylon(128, 0, 0, 5, 0.01, 0)
        if mode == Effects.RGB:
            if self.colour == None:
                self.restore()

        self.pixels.auto_write = False
        self._effect = mode

    def _set_pixel(self, pixel, r, g, b):
        if pixel > self._length - 1:
            return
        if pixel < 0:
            return

        red = min(int(r), 255)
        green = min(int(g), 255)
        blue = min(int(b), 255)
        self.pixels[pixel] = (red, green, blue)

    def set_colour(self, r, g, b, transient=True, display_time=0, dim_after=0):
        if not transient:
            self.saved = False
            self.colour.rgbcolour = (int(r), int(g), int(b))

        if self._effect != Effects.RGB:
            return

        self.pixels.fill((int(r), int(g), int(b)))
        self.pixels.show()

        if dim_after != 0:
            self.set_brightness(1.0)
            self.dim_timer.restart(dim_after)

        if not transient:
            print("Saving RGB")
            self.save()
        else:
            if display_time == 0:
                self.restore_timer.restart(self.save_period)
            else:
                self.restore_timer.restart(display_time)

    def set_brightness(self, brightness, fade=False):
        if self._effect != Effects.RGB:
            self._brightness = brightness
            return
        print("New brightness: " + format(brightness))
        if not fade:
            for i in range(0, self._length):
                colour = self.pixels[i]
                new_colour = [0] * 3
                for j in range(0, 3):
                    new_colour[j] = colour[j] * brightness / self._brightness
                self._set_pixel(i, new_colour[0], new_colour[1], new_colour[2])
        else:
            self.colour *= 1
            colour2 = self.colour * 0.1
            self.fade(colour2, 100, 3)
        self._brightness = brightness

    def _dim(self):
        self.set_brightness(0.1)
        self.pixels.show()

    def save(self):
        for i in range(0, self._length):
            self._backup[i] = self.pixels[i]
        self.saved = True

    def restore(self):
        print("restoring")
        self.restore_timer.stop()

        if (self._effect != Effects.RGB):
            self.set_mode(self._effect)
            return

        if not self.saved:
            self.set_colour(self.colour.r,
                            self.colour.g,
                            self.colour.b,
                            transient=False,
                            dim_after=5)
        else:
            for i in range(0, self._length):
                self.pixels[i] = self._backup[i]
            self.pixels.show()
        self.saved = False

    def pause(self):
        self.paused = True
        self.save()
        self.pixels.fill((0, 0, 0))
        self.pixels.show()

    def unpause(self):
        if self._effect == Effects.RGB:
            self.restore()
        self.paused = False

    def _prepare_temperature_pixels(self):
        self.pixels.fill((0, 0, 0))

        multiplier = 255 / self._length
        for i in range(0, self._length):
            self._set_pixel(i, round(i * multiplier), 0,
                            round(255 - (i * multiplier)))
            self._temperature_pixels.append(self.pixels[i])
            self.pixels[i] = self._backup[i]

    def set_temperature(self, temperature):
        if (self._effect != Effects.RGB):
            self.stop_loop()

        self.restore_timer.restart(self.save_period)
        self.pixels.fill((0, 0, 0))

        count = round((temperature / 100) * self._length)

        self.pixels[0:count] = self._temperature_pixels[0:count]

        self.pixels.show()

    def set_level(self, level, colour=None):
        self.pixels.fill((0, 0, 0))
        if colour == None:
            colour = self.colour

        count = round((level / 100) * self._length)
        for i in range(0, count):
            self._set_pixel(i, colour.r, colour.g, colour.b)
        self.pixels.show()

    def shoot(self):
        for i in range(0, self._length):
            self.pixels[i] = (0, 20, 0)
            time.sleep(0.100)
        for i in range(0, self._length):
            self.pixels[i] = (0, 0, 10)
            time.sleep(0.100)
        for i in range(0, self._length):
            self.pixels[i] = (0, 0, 0)
            time.sleep(0.100)

    def fade_from_to(self, colour1, colour2, steps, interval):
        while (self._thread_running):
            pass
        self._thread = threading.Thread(target=self._fade,
                                        args=(colour1, colour2, steps,
                                              interval))
        self._thread.daemon = True
        self._thread.start()

    def fade(self, colour2, steps, interval):
        self.fade_from_to(self.colour, colour2, steps, interval)

    def _fade(self, colour1, colour2, steps, interval):
        self._thread_running = True
        lastUpdate = time.time() - interval
        interval = interval / steps

        for i in range(1, steps + 1):
            r = round(((colour1.r * (steps - i)) + (colour2.r * i)) / steps)
            g = round(((colour1.g * (steps - i)) + (colour2.g * i)) / steps)
            b = round(((colour1.b * (steps - i)) + (colour2.b * i)) / steps)

            while ((time.time() - lastUpdate) < interval):
                pass

            colour = Colour(r, g, b)
            for j in range(0, self._length):
                if not self.paused:
                    self._set_pixel(j, colour.r, colour.g, colour.b)

            lastUpdate = time.time()
        self._thread_running = False
        self.colour = colour2

    def blink(self, r, g, b):
        self.set_colour(r, g, b, transient=True, display_time=0.5)


### Effects ###
# Ported from: https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/

### Base ###

    def stop_loop(self):
        self._thread_terminate = True
        while self._thread_running:
            pass

    ### Cylon ###

    def _start_cylon(self, r, g, b, EyeSize, SpeedDelay, ReturnDelay):
        while (self._thread_running):
            pass
        self._thread = threading.Thread(target=self._cylon,
                                        args=(r, g, b, EyeSize, SpeedDelay,
                                              ReturnDelay))
        self._thread.daemon = True
        self._thread.start()

    def _cylon(self, red, green, blue, EyeSize, SpeedDelay, ReturnDelay):
        self._thread_terminate = False
        self._thread_running = True
        while not self._thread_terminate:
            if not self.paused:
                for i in range(0 - EyeSize, self._length + EyeSize):
                    if self._thread_terminate:
                        self._thread_running = False
                        return

                    self.pixels.fill((0, 0, 0))
                    self._set_pixel(i, round(red / 10), round(green / 10),
                                    round(blue / 10))
                    for j in range(1, EyeSize):
                        self._set_pixel(i + j, red, green, blue)
                    self._set_pixel(i + EyeSize, round(red / 10),
                                    round(green / 10), round(blue / 10))
                    if not self.paused:
                        self.pixels.show()
                    time.sleep(SpeedDelay)

                time.sleep(ReturnDelay)

                for i in range(self._length + EyeSize, 0 - EyeSize, -1):
                    if self._thread_terminate:
                        self._thread_running = False
                        return

                    self.pixels.fill((0, 0, 0))
                    self._set_pixel(i, round(red / 10), round(green / 10),
                                    round(blue / 10))
                    for j in range(EyeSize, 0, -1):
                        self._set_pixel(i - j, red, green, blue)
                    self._set_pixel(i - EyeSize, round(red / 10),
                                    round(green / 10), round(blue / 10))
                    if not self.paused:
                        self.pixels.show()
                    time.sleep(SpeedDelay)

            time.sleep(ReturnDelay)
        self._thread_running = False

    ### Fire ###

    def _start_fire(self, cooling, sparking, speed_delay):
        self._thread_terminate = False
        while (self._thread_running):
            pass
        self._thread = threading.Thread(target=self._fire,
                                        args=(cooling, sparking, speed_delay))
        self._thread.daemon = True
        print("Starting a fire")
        self._thread.start()

    def _fire(self, cooling, sparking, speed_delay):
        heat = [0] * self._length
        cooldown = 0
        self._thread_running = True

        while not self._thread_terminate:
            if not self.paused:
                for i in range(0, self._length):
                    cooldown = random.randint(
                        0, round(((cooling * 10) / self._length) + 20))
                    if cooldown > heat[i]:
                        heat[i] = 0
                    else:
                        heat[i] = heat[i] - cooldown

                for i in range(self._length - 1, 3, -1):
                    heat[i] = (heat[i - 1] + heat[i - 2] + heat[i - 2]) / 3

                if random.randint(0, 255) < sparking:
                    y = random.randint(0, 7)
                    heat[y] = heat[y] + random.randint(160, 255)

                for i in range(0, self._length):
                    self._set_pixel_heat_colour(i, heat[i])

                if not self.paused:
                    self.pixels.show()
                time.sleep(speed_delay)

        self._thread_running = False

    def _set_pixel_heat_colour(self, pixel, temperature):

        t192 = round((temperature / 255.0) * 191)

        heatramp = t192 & 0x3F
        heatramp <<= 2

        if (t192 > 0x80):
            self._set_pixel(pixel, 255, 255, heatramp)
        elif (t192 > 0x40):
            self._set_pixel(pixel, 255, heatramp, 0)
        else:
            self._set_pixel(pixel, heatramp, 0, 0)

    ### Meteor ###
    def _start_meteor(self, red, green, blue, size, trail_decay, speed):
        self._thread_terminate = False
        while (self._thread_running):
            pass
        self._thread = threading.Thread(target=self._meteor,
                                        args=(red, green, blue, size,
                                              trail_decay, speed))
        self._thread.daemon = True
        print("Pew pew")
        self._thread.start()

    def _meteor(self, red, green, blue, size, trail_decay, speed):
        self.pixels.fill((0, 0, 0))
        self._thread_running = True

        while not self._thread_terminate:
            if not self.paused:
                for i in range(0, self._length * 2):
                    # fade
                    for j in range(0, self._length):
                        if (random.randint(0, 10) < 5):
                            self.fade_to_black(j, trail_decay)

                    for j in range(0, size):
                        if ((i - j) < self._length):
                            self._set_pixel(i - j, red, green, blue)

                    if not self.paused:
                        self.pixels.show()

                    if self._thread_terminate:
                        self._thread_running = False
                        return

                    time.sleep(speed)
        self._thread_running = False

    def fade_to_black(self, pixel, fade_value):
        old_colour = self.pixels[pixel]
        r = old_colour[0]
        g = old_colour[1]
        b = old_colour[2]

        if r <= 10:
            r = 0
        else:
            r = r - (r * fade_value / 256)
        if g <= 10:
            g = 0
        else:
            g = g - (g * fade_value / 256)
        if b <= 10:
            b = 0
        else:
            b = b - (b * fade_value / 256)

        self._set_pixel(pixel, r, g, b)
Пример #6
0
def evaluate_one_py(py_name, all_func_info, stu_name, gold_funcs, verbose):
    if verbose > 0:
        print('\nStart evaluating %s %s' % (py_name, stu_name),
              flush=True,
              file=sys.stderr)
    try:
        with MyTimer(max_time_for_import_one_py):
            this_funcs = get_funcs_in_one_module(py_name,
                                                 verbose)  #将学生代码的函数提取出来
    except Exception as e:
        print_a_thing_verbose_1(
            'import module %s timeout: %s %s' % (py_name, type(e).__name__, e),
            verbose)

    total_score = 0.
    func_scores = []
    func_names = []
    for (func_name, score, time_ratio,
         test_case_file_name) in all_func_info:  #批阅的函数名 分数 测试用例文件 时间?
        func_names.append(func_name)
        if this_funcs is None:  #判断是否有函数
            func_scores.append(0.)
            print_a_thing_verbose_1(
                'module %s does not contain func: %s' % (py_name, func_name),
                verbose)
            continue
        correct_case_cnt = 0.
        lines = get_all_lines(test_case_file_name)  #读文件,测试用例文件
        total_case_cnt = len(lines)  #测试用例个数
        gold_func = gold_funcs.get(func_name)  #返回gold文件里的特定的函数名(要评分的那些函数)
        assert gold_func is not None  #检查函数名
        if this_funcs.get(func_name) is None:
            lines = []  #如果没有相符合的函数名 测试用例文件也没有相符合的
        for i_input, one_input in enumerate(
                lines
        ):  #enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标 i是下标,one是数据
            one_input_line = one_input.strip()  #移除空格换行符
            assert len(one_input_line) > 0  #检查长度
            one_input = eval(
                one_input_line)  #eval() 函数用来执行一个字符串表达式,并返回表达式的值(字符串转为列表)
            one_input_for_sys = eval(one_input_line)
            start_time = time.time()
            gold_result = gold_func(*one_input)  #将测试用例放入函数里执行?(数组第一个元素?)
            end_time = time.time()
            time_gap_sec = end_time - start_time  #执行时间

            try:
                with MyTimer(
                        max(time_gap_sec * time_ratio,
                            min_time_for_run_one_func)):
                    result = this_funcs[func_name](
                        *one_input_for_sys)  #将测试用例放到学生函数里执行?
            except Exception as e:  #发生异常执行这一块
                print_msg_verbose_2(py_name, func_name, i_input,
                                    '%s : %s' % (type(e).__name__, e), verbose)
                continue
            if gold_result is None:
                print(*one_input, gold_result)
            if result == gold_result:  #判断学生结果和答案结果是否相等
                correct_case_cnt += 1  #通过的正确的测试用例个数+1
                print_msg_verbose_2(py_name, func_name, i_input, 'passed',
                                    verbose)
            else:
                print_msg_verbose_2(py_name, func_name, i_input, 'failed',
                                    verbose)
        this_func_score = score * correct_case_cnt / total_case_cnt  #分数就是通过的用例/总用例
        func_scores.append(this_func_score)  #函数的得分列表
        total_score += this_func_score  #总分数
        print_func_score_verbose_1(py_name, stu_name, func_name, score,
                                   correct_case_cnt, total_case_cnt, verbose)
    print_score_summary(py_name, stu_name, total_score, func_names,
                        func_scores)
Пример #7
0
class Target(TargetSample, Sprite):
    """靶机类"""
    def __init__(self, settings, stats, screen, *args):
        """初始化靶机并设置其起始位置"""
        TargetSample.__init__(self)
        Sprite.__init__(self)
        self.settings = settings
        self.screen = screen
        self.stats = stats
        self.screen_rect = screen.get_rect()
        self.args = args
        self.target_shield_image = pygame.image.load(
            dir_path + r'\images\target_shield.png')

        # 靶机初始位置
        self.rect.x = self.settings.x_target_position + args[
            0] * self.rect.width * 2
        self.rect.y = self.settings.y_target_boundary

        # 存储靶机准确位置
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)

        self.timer = MyTimer()
        self.shield_timer = MyTimer()
        self.moving = False

        self.delay = self.args[4]  # 靶机延时启动时长
        if self.args[3]:  # 带盾
            self.image = self.target_shield_image
            self.life = 2
        else:  # 无盾
            self.life = 1

    def update_shield(self):
        """更新护盾状态"""
        if self.args[3] and self.shield_timer.pass_time > 5:  # 带盾靶机每5秒会重新生成护盾
            self.shield_timer.reset()
            if self.life < 2:  # 重新生成护盾,靶机变为蓝色
                self.image = self.target_shield_image
                self.life = 2

    def check_edges(self):
        """如果靶机位于活动范围边缘,就返回True"""
        if self.rect.bottom > self.screen_rect.bottom - self.settings.y_target_boundary:
            return True
        elif self.rect.top < self.settings.y_target_boundary:
            return True
        return False

    def blitme(self):
        """在指定位置绘制靶机"""
        self.screen.blit(self.image, self.rect)

    def kill(self):
        """重写kill(),响应靶机被击中"""
        if self.timer.pass_time > 0.5:  # 0.5秒内的碰撞视为击中同一个靶机
            if self.life > 1:  # 击破护盾,靶机变为灰色
                if self.stats.sound_state:
                    shield_broken_sound.play()  # 击破护盾音效
                self.life -= 1
                self.image = self.target_image
                self.timer.reset()
            else:  # 击破靶机
                if self.stats.sound_state:
                    target_broken_sound.play()
                self.timer.stop()
                self.shield_timer.stop()
                super().kill()

    def start_timer(self):
        self.timer.begin()

    def stop_timer(self):
        self.timer.stop()

    def reset_timer(self):
        self.timer.reset()

    def start_shield_timer(self):
        self.shield_timer.begin()

    def stop_shield_timer(self):
        self.shield_timer.stop()

    def reset_shield_timer(self):
        self.shield_timer.reset()
def run_game():

    pygame.init()

    # 设置窗口
    os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (128, 60)
    settings = Settings()
    screen = pygame.display.set_mode(
        (settings.screen_width, settings.screen_height))
    pygame.display.set_caption("Shooting Practice")

    # 背景图
    dir_path = os.path.dirname(os.path.abspath(__file__))
    background = pygame.image.load(dir_path +
                                   r'\images\background.jpg').convert()

    # 创建枪支、子弹编组
    gun = Gun(settings, screen)
    bullets = Group()

    # 创建全局计时器
    overall_timer = MyTimer()

    # 创建靶机编组、提示条编组
    target_sample = TargetSample()
    targets = Group()
    notice_bars = Group()

    # 创建用于存储游戏统计信息的实例
    stats = GameStats(settings, overall_timer)

    # 文件读写
    io_helper = IOHelper(stats)

    # 创建信息显示板
    running_info = RunningInfo(settings, screen, stats)
    win_info = WinInfo(settings, screen, stats, io_helper)
    failed_info = FailedInfo(screen, stats)

    # 创建输入框
    pregame_info = PregameInfo(settings, screen, stats)

    # 开始游戏主循环
    while True:
        # 检查事件
        func.check_events(settings, screen, stats, running_info, win_info,
                          failed_info, gun, targets, bullets, pregame_info,
                          notice_bars)
        # 更新屏幕
        func.common_update_screen(background, settings, screen, stats,
                                  running_info, gun, target_sample, targets,
                                  bullets, notice_bars)
        # 游戏进行中,更新枪支、子弹、靶机提示条、靶机位置
        if stats.game_state == GameState.RUNNING:
            gun.update()
            func.update_bullets(settings, screen, stats, targets, bullets,
                                notice_bars, win_info, io_helper)
            func.update_notice(notice_bars)
            func.update_targets(targets)
        elif stats.game_state == GameState.PREGAME:
            pregame_info.draw_pregame_info()
        elif stats.game_state == GameState.GAME_OVER:
            failed_info.show_info()
        elif stats.game_state == GameState.GAME_FINISH:
            win_info.show_info()
        # 让最近绘制的屏幕可见
        pygame.display.flip()