// File: /workspace/github_cpp_makefile_star2_O3/miklhh[P]tetris/src/game.cpp
// Function: iterate_game()
bool iterate_game()
{
    /* Test if the game already set to game-over. */
    if (game_over)
    {
        delete current_block;
        delete next_block;
        return false;
    }

    /* Test if the game just ended. */
    //TODO: Implement later. Don't forget to remove (delete) all blocks.

    /* If the block hits the ground. */
    if (test_movable(current_block, DIRECTION_DOWN) != NO_COLLISION)
    {
        std::cout << "CRACH" << std::endl;
        for (int y = 0; y < MAX_BLOCK_HEIGHT; y++)
        {
            for (int x = 0; x < MAX_BLOCK_WIDTH; x++)
            {
                if (current_block->structure.tile[y][x] == FILLED)
                {
                    field[y + current_block->position.y][x + current_block->position.x].tile = FILLED;
                    field[y + current_block->position.y][x + current_block->position.x].color_b = COLOR_BLOCK_BACKGROUND;
                    field[y + current_block->position.y][x + current_block->position.x].color_f = current_block->color;
                }
            }
        }

        /* Test and remove posible full rows */
        for (int y1 = 0; y1 < GRID_HEIGHT; y1++)
        {
            /* Test if the row 'y1' is full. If it is, test how many row under 'y1'
            * which also is full. */
            if (test_row_full(y1))
            {
                int   row = y1;
                int   n = 1;
                bool  one_found = false;
                for (int y2 = y1; y2 < GRID_HEIGHT; y2++)
                {
                    bool row_full = test_row_full(y2);
                    if (row_full)
                    {
                        n = y2 - y1 + 1;
                        one_found = true;
                    }
                    if (one_found && !row_full)
                        break;
                }

                /* The appropriate rows to remove and the amount of rows under it
                * has been found. Remove accordingly and move field down. */
                for (int y = y1; y < y1 + n; y++)
                {
                    remove_row(y);
                }

                /* Move down the pieces above it and break out of loop. */
                move_field_down(y1, n);
                break;
            }
        }

        /* Remove the old block and prepare a new one. */
        delete current_block;
        current_block   = next_block;
        next_block      = block_spawn();
        return false;
    }

    /* The block hasn't landed. Move it downward a step and continue the game. */
    block_move(current_block, DIRECTION_DOWN);
    return false;
}

// Assembly:
pushq %rbx
movq 0x3b94(%rip), %rdi      # 0x6ad0
movl $0x3, %esi
callq 0x2c2d
testl %eax, %eax
je 0x314b
movq 0x3083(%rip), %rbx      # 0x5fd8
leaq 0x13b7(%rip), %rsi      # 0x4313
movl $0x5, %edx
movq %rbx, %rdi
callq 0x21f0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x3b39(%rip), %rax      # 0x6ad0
leaq 0x10(%rax), %rcx
xorl %edx, %edx
leaq 0x31cc(%rip), %rsi      # 0x6170
movabsq $0x100000008, %rdi      # imm = 0x100000008
movslq %edx, %r8
xorl %r9d, %r9d
cmpl $0x1, (%rcx,%r9,4)
jne 0x2fdf
movslq 0xc(%rax), %r10
addq %r8, %r10
movslq 0x8(%rax), %r11
addq %r9, %r11
imulq $0x78, %r10, %r10
addq %rsi, %r10
leaq (%r11,%r11,2), %r11
movq %rdi, 0x4(%r10,%r11,4)
movl (%rax), %ebx
movl %ebx, (%r10,%r11,4)
incq %r9
cmpq $0x4, %r9
jne 0x2fb4
incq %rdx
addq $0x10, %rcx
cmpq $0x4, %rdx
jne 0x2fae
leaq 0x3188(%rip), %rdx      # 0x6184
xorl %edi, %edi
movq %rsi, %rcx
imulq $0x78, %rdi, %r8
cmpl $0x0, 0x8(%r8,%rsi)
je 0x3030
movq $-0x1, %r8
movq %rdx, %r9
cmpq $0x8, %r8
je 0x3046
incq %r8
cmpl $0x0, (%r9)
leaq 0xc(%r9), %r9
jne 0x3017
cmpq $0x9, %r8
jae 0x3046
incq %rdi
addq $0x78, %rcx
addq $0x78, %rdx
cmpq $0x14, %rdi
jne 0x3001
jmp 0x3111
movl $0x1, %esi
cmpq $0x13, %rdi
ja 0x30c7
movl $0x1, %esi
xorl %eax, %eax
leaq 0x3111(%rip), %r8       # 0x6170
movq %rdi, %r9
imulq $0x78, %r9, %r10
cmpl $0x0, 0x8(%r10,%r8)
je 0x30a1
movq %rdx, %r11
xorl %ebx, %ebx
movq %rbx, %r10
cmpq $0x9, %rbx
je 0x308a
cmpl $0x0, (%r11)
leaq 0xc(%r11), %r11
leaq 0x1(%r10), %rbx
jne 0x3073
movl %r9d, %r11d
subl %edi, %r11d
incl %r11d
cmpq $0x9, %r10
setae %r10b
cmovael %r11d, %esi
jmp 0x30a4
xorl %r10d, %r10d
movl %eax, %r11d
notb %r11b
orb %r10b, %r11b
testb $0x1, %r11b
je 0x30c3
incq %r9
orb %r10b, %al
addq $0x78, %rdx
cmpq $0x14, %r9
jne 0x3062
testl %esi, %esi
jle 0x3105
leal (%rsi,%rdi), %eax
cltq
movabsq $0x600000007, %rdx      # imm = 0x600000007
movq %rdi, %r8
movl $0x8, %r9d
movl $0x0, (%rcx,%r9)
movq %rdx, -0x8(%rcx,%r9)
addq $0xc, %r9
cmpq $0x80, %r9
jne 0x30df
incq %r8
addq $0x78, %rcx
cmpq %rax, %r8
jl 0x30d9
callq 0x2dfe
movq 0x39bf(%rip), %rax      # 0x6ad0
movl $0x50, %esi
movq %rax, %rdi
callq 0x21e0
movq 0x39b3(%rip), %rax      # 0x6ad8
movq %rax, 0x39a4(%rip)      # 0x6ad0
movl $0x7, %edi
movl $0x4, %esi
xorl %edx, %edx
movl $0x3, %ecx
callq 0x27f7
movq %rax, 0x398f(%rip)      # 0x6ad8
jmp 0x3155
movq 0x397e(%rip), %rax      # 0x6ad0
incl 0xc(%rax)
xorl %eax, %eax
popq %rbx
retq