def init(numplayers = 2):
    screen = pygame.display.get_surface()
    em = EventManager()
    bg = load.image("select-bg.png")
    move_snd = load.sound("select-move.wav")
    confirm_snd = load.sound("select-confirm.wav")
    confirm_snd.set_volume(0.4)

    sprites = RenderUpdates()
    portraits = [PortraitDisplay([20, 20]), PortraitDisplay([20, 320])]
    names = [NameDisplay([20, 220]), NameDisplay([20, 520])]
    drops = [DropDisplay([240, 20]), DropDisplay([240, 320])]
    stats = [StatDisplay([240, 150]), StatDisplay([240, 450])]
    descs = [DescDisplay([430, 20]), DescDisplay([430, 320])]
    char_sprites = zip(portraits, names, drops, stats, descs)

    idx = [0, 0]
    confirmed = [False, False]
    for i, sprs in enumerate(char_sprites):
        if i < numplayers:
            for spr in sprs: spr.set_char(Character.available[i])
            sprites.add(sprs)
            idx[i] = i

    init_bg = bg.convert()
    sprites.update(pygame.time.get_ticks())
    sprites.draw(init_bg)
    wipes.wipe_in(init_bg)
    init_bg = None # Let us GC it
    pygame.display.update()
    sprites.clear(screen, bg)

    while False in [(c.confirmed or i >= numplayers)
                    for i, c in enumerate(portraits)]:
        for ev in em.wait():
            if ev.type == PLAYER:
                if ev.key == LEFT:
                    i = (idx[ev.player] - 1) % len(Character.available)
                    idx[ev.player] = i
                elif ev.key == RIGHT:
                    i = (idx[ev.player] + 1) % len(Character.available)
                    idx[ev.player] = i
                elif ev.key in [ROT_CC, ROT_CW, CONFIRM]:
                    confirm_snd.play()
                    portraits[ev.player].confirmed = True

                if ev.key in [LEFT, RIGHT]:
                    move_snd.play()
                    for spr in char_sprites[ev.player]:
                        spr.set_char(Character.available[idx[ev.player]])
                    portraits[ev.player].confirmed = False

            elif ev.type == QUIT:
                return None, None

        sprites.update(pygame.time.get_ticks())
        pygame.display.update(sprites.draw(screen))
        sprites.clear(screen, bg)

    return [Character.available[i] for i in idx]
def init(*args):
    em = EventManager()
    disp = pygame.Surface([800, 600])

    disp.fill([0, 0, 0])
    font = textfx.WrapFont(30, 760)
    bg = Character.default.border([780, 100]).convert()

    bg.set_alpha(256)
    disp.blit(bg, [0, 0])
    t = font.render(
        "Welcome to the unlock screen! As you do more in this "
        "game, new features will sometimes appear. By playing the "
        "game at least once, you've managed to unlock this unlock "
        "screen, for example. Keep practicing, and more things will "
        "appear..."
    )

    disp.blit(t, t.get_rect(midleft=[20, 60]))

    if config.getboolean("unlock", "single"):
        bg.set_alpha(256)
        disp.blit(bg, [0, 120])
        t = font.render(
            "Congratulations! By scoring over 20,000 points in a 2/3 versus "
            "match, you've unlocked single player mode. It's a lot "
            "harder, so you should practice your crystal building and "
            "combo setups."
        )
        disp.blit(t, t.get_rect(midleft=[20, 180]))
    else:
        bg.set_alpha(127)
        disp.blit(bg, [0, 120])

    if config.getboolean("unlock", "unixbros"):
        bg.set_alpha(256)
        disp.blit(bg, [0, 240])
        t = font.render(
            "By breaking a crystal of over 16 gems, you've unlocked two more "
            "characters - The Yuniks brothers. Both encourage a very "
            "unique style of attacks. Go check them out."
        )
        disp.blit(t, t.get_rect(midleft=[20, 300]))
    else:
        bg.set_alpha(127)
        disp.blit(bg, [0, 240])

    if config.getboolean("unlock", "combat"):
        bg.set_alpha(256)
        disp.blit(bg, [0, 360])
        t = font.render(
            "By getting at least a 4 chain, you've unlocked combat "
            "mode. If this is on, special attack rocks might appear in "
            "versus mode, that have strange effects on the other "
            "player. Enable it in the setup menu."
        )
        disp.blit(t, t.get_rect(midleft=[20, 420]))
    else:
        bg.set_alpha(127)
        disp.blit(bg, [0, 360])

    if config.getboolean("unlock", "cpuversus"):
        bg.set_alpha(256)
        disp.blit(bg, [0, 480])
        t = font.render(
            "You've made it at least halfway through arcade mode! "
            "You can now practice against any dwarf, on any "
            "of the AI levels."
        )
        disp.blit(t, t.get_rect(midleft=[20, 540]))
    else:
        bg.set_alpha(127)
        disp.blit(bg, [0, 480])

    wipes.wipe_in(disp)
    pygame.display.update()
    quit = False
    while not quit:
        for ev in em.wait():
            quit = quit or ev.type == QUIT or (ev.type == PLAYER and ev.key in [ROT_CC, ROT_CW, CONFIRM])

    return True
def init(*args):
    em = EventManager()
    screen = pygame.display.get_surface()
    move_snd = load.sound("select-move.wav")

    index = 0

    # The format is up to three paragraphs per screen, displayed
    # left, right, left,
    texts = [
        ["In Angry, Drunken Dwarves, you are an angry, drunken dwarf. Why "
         "are you so angry? Who knows. But you've decided to take your "
         "aggression out on other dwarves, by dropping gems on their "
         "heads.",
         "Multicolored gems will fall from the top of the screen. You "
         "should try to arrange them into groups by color. The arrow keys "
         "or a/d and j/l will move them left and right. s or k will make "
         "then fall faster, and q/e and u/o will rotate them.",
         "As gems reach the bottom, they will land and sit in place. If you "
         "put enough gems of the same color in a rectangle shape, they will "
         "merge and form a crystal."
         ],
        ["Less common are break gems. When you drop a break gem on a gem "
         "or crystal of the same color, it will destroy any gems of that "
         "color adjacent to it. Crystals are worth much more than an equal "
         "number of regular gems.",
         "When you destroy gems on your side, it will drop counter gems "
         "onto your opponent. These are harder to destroy, but turn into "
         "regular gems after a few turns. You can try to cancel an incoming "
         "attack by breaking gems yourself, but you'll need to break twice "
         "as many as are coming.",
         "Rarer is the diamond. When you drop a diamond onto something, "
         "it will destroy all gems of that color on your side, even "
         "counter gems! Be careful though, because a crystal "
         "destroyed by a diamond isn't worth any more than normal gems."
         ],
        ["Each dwarf has a drop gem pattern, and an attack strength. The drop "
         "pattern is a display of what kinds of gems will be dropped when "
         "you attack your opponent. Small attacks will drop the same "
         "row over and over, which will probably help them!",
         "The attack strength is a measurement of how strong your drop "
         "pattern is; drops with weirder patterns are harder to plan "
         "against. Before gems are dropped, they are multiplied by this "
         "attack strength, and so the damage is scaled up or down.",
         "For the most devestating results, try chaining attacks together, "
         "so breaking some gems results in even more breaking afterwards. "
         "Breaking many crystals in a chain can result in huge drops."
         ]
        ]

    drop = pygame.Surface([64, 64])
    drop.blit(load.block("blue"), [0, 0])
    drop.blit(load.block("yellow"), [0, 32])
    drop.blit(load.block("green"), [32, 0])
    drop.blit(load.block("red"), [32, 32])

    crystal = load.gem("green", 4, 3)

    breaks = pygame.Surface([64, 64])
    breaks.blit(load.block("red", "-crash"), [0, 0])
    breaks.blit(load.block("green", "-crash"), [0, 32])
    breaks.blit(load.block("yellow", "-crash"), [32, 0])
    breaks.blit(load.block("blue", "-crash"), [32, 32])

    counters = pygame.Surface([64, 64])
    counters.blit(textfx.lettered_box("5", "green"), [0, 0])
    counters.blit(textfx.lettered_box("4", "blue"), [32, 0])
    counters.blit(textfx.lettered_box("3", "red"), [0, 32])
    counters.blit(textfx.lettered_box("2", "yellow"), [32, 32])

    chain = pygame.Surface([64, 96])
    chain.blit(load.block("blue", "-crash"), [0, 64])
    chain.blit(load.block("green"), [32, 64])
    chain.blit(load.block("green", "-crash"), [32, 32])
    chain.blit(load.block("blue"), [32, 0])

    # Followed by up to three images per screen, right, left, right.
    images = [
        [None, drop, crystal],
        [breaks, counters, load.block("diamond")],
        [Character.arcade[4].drop.render(), None, chain],
        ]

    if config.getboolean("unlock", "single"):
        texts.append([
            "In single player mode, rather than competing against someone "
            "else, you're racing the clock. You have to clear a certain "
            "number of blocks in a certain number of turns, or the ones "
            "left get dumped on you.",
            "Your field is also twice as big. So it sounds easy, right? "
            "Well, to start with, you've got three new colors of gems to "
            "contend with: orange, purple, and cyan.",
            "If that wasn't bad enough, the number of gems you have to clear "
            "goes up much faster than the number of turns you have "
            "to do it, so build up those crystals early and save them."
            ])

        newcols = pygame.Surface([64, 64])
        newcols.blit(load.block("orange"), [16, 0])
        newcols.blit(load.block("cyan"), [0, 32])
        newcols.blit(load.block("purple"), [32, 32])

        
        counts = pygame.Surface([130, 100])
        box = Character.default.border([40, 40])
        text1 = textfx.shadow("new:", 20)
        text2 = textfx.shadow("turns:", 20)
        num1 = textfx.shadow("122", 30)
        num2 = textfx.shadow("10", 30)
        counts.blit(box, [0, 20])
        counts.blit(box, [70, 20])
        counts.blit(text1, text1.get_rect(center = [30, 38]))
        counts.blit(text2, text2.get_rect(center = [100, 38]))
        counts.blit(num1, [12, 45])
        counts.blit(num2, [87, 45])
        images.append([None, newcols, counts])

    if config.getboolean("unlock", "combat"):
        texts.append([
            "Combat blocks look like normal gems with a special symbol "
            "in the middle. These gems don't form crystals, but otherwise "
            "break like normal colored gems. When you break one of these, "
            "you 'pick up' the special attack in it.",
            "To use the attack, press start (enter/2). There are five basic "
            "attacks; from left to right: make your opponent's field blink, "
            "clear  your own field of all blocks,",
            "flip your opponent's screen upside down, disable the 'next' "
            "indicator, drop some gray blocks, or reverse your opponent's "
            "controls. Blink, flip, and reverse last for a few "
            "seconds. Scramble lasts 10 turns."])

        blink = load.block("blue")
        clear = load.block("red")
        rev = load.block("yellow")
        flip = load.block("green")
        gray = load.block("red")
        scram = load.block("purple")
        blink.blit(SpecialSprite.load(BLINK), [6, 6])
        flip.blit(SpecialSprite.load(FLIP), [6, 6])
        clear.blit(SpecialSprite.load(CLEAR), [6, 6])
        rev.blit(SpecialSprite.load(REVERSE), [6, 6])
        gray.blit(SpecialSprite.load(GRAY), [6, 6])
        scram.blit(SpecialSprite.load(SCRAMBLE), [6, 6])
        img1 = pygame.Surface([64, 32])
        img2 = pygame.Surface([64, 64])
        img1.blit(blink, [0, 0])
        img1.blit(clear, [32, 0])
        img2.blit(flip, [0, 0])
        img2.blit(scram, [32, 0])
        img2.blit(gray, [0, 32])
        img2.blit(rev, [32, 32])

        images.append([None, img1, img2])

    wipes.wipe_in(render_help_page(texts[index], images[index]))

    cont = True
    screen.blit(render_help_page(texts[index], images[index]), [0, 0])
    img = textfx.shadow("Enter: Menu - Left/Right: Turn Page (%d/%d)" %
                 (index + 1, len(images)), 18)
    screen.blit(img, [785 - img.get_width(), 10])
    pygame.display.update()
    while cont:
        oldindex = index
        for ev in em.wait():
            if ev.type == QUIT: cont = False
            elif ev.type == PLAYER:
                if ev.key == CONFIRM: cont = False
                elif ev.key == UP or ev.key == LEFT:
                    index = (index - 1) % len(texts)
                    move_snd.play()
                elif ev.key in [DOWN, RIGHT, ROT_CC, ROT_CW]:
                    index = (index + 1) % len(texts)
                    move_snd.play()

        if oldindex != index:
            screen.blit(render_help_page(texts[index], images[index]), [0, 0])
            img = textfx.shadow("Enter: Menu - Left/Right: Turn Page (%d/%d)" %
                         (index + 1, len(images)), 18)
            screen.blit(img, [785 - img.get_width(), 10])
            pygame.display.update()

    return True