// File: /workspace/github_cpp_makefile_star2_O1/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 %r14
pushq %rbx
pushq %rax
movq 0x3b68(%rip), %rdi      # 0x6ad0
movl $0x3, %esi
callq 0x2c32
testl %eax, %eax
je 0x3071
movq 0x3057(%rip), %rbx      # 0x5fd8
leaq 0x138b(%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 0x3b0d(%rip), %rax      # 0x6ad0
leaq 0x10(%rax), %rcx
xorl %esi, %esi
leaq 0x31a0(%rip), %rdx      # 0x6170
movabsq $0x100000008, %rdi      # imm = 0x100000008
movslq %esi, %r8
xorl %r9d, %r9d
cmpl $0x1, (%rcx,%r9,4)
jne 0x300b
movslq 0xc(%rax), %r10
addq %r8, %r10
movslq 0x8(%rax), %r11
addq %r9, %r11
imulq $0x78, %r10, %r10
addq %rdx, %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 0x2fe0
incq %rsi
addq $0x10, %rcx
cmpq $0x4, %rsi
jne 0x2fda
leaq 0x315c(%rip), %rcx      # 0x6184
xorl %edi, %edi
movq %rdx, %rax
imulq $0x78, %rdi, %rsi
cmpl $0x0, 0x8(%rsi,%rdx)
je 0x305b
movq %rcx, %r8
xorl %r9d, %r9d
movq %r9, %rsi
cmpq $0x9, %r9
je 0x3055
cmpl $0x0, (%r8)
leaq 0xc(%r8), %r8
leaq 0x1(%rsi), %r9
jne 0x303e
cmpq $0x9, %rsi
jae 0x3080
incq %rdi
addq $0x78, %rax
addq $0x78, %rcx
cmpq $0x14, %rdi
jne 0x302d
jmp 0x314a
movq 0x3a58(%rip), %rax      # 0x6ad0
incl 0xc(%rax)
jmp 0x318b
movl $0x1, %esi
cmpq $0x13, %rdi
ja 0x3102
movl $0x1, %edx
xorl %r8d, %r8d
leaq 0x30d6(%rip), %r9       # 0x6170
movq %rdi, %r10
movl $0x1, %esi
imulq $0x78, %r10, %r11
cmpl $0x0, 0x8(%r11,%r9)
je 0x30d4
movq %rcx, %rbx
xorl %r14d, %r14d
movq %r14, %r11
cmpq $0x9, %r14
je 0x30ca
cmpl $0x0, (%rbx)
leaq 0xc(%rbx), %rbx
leaq 0x1(%r11), %r14
jne 0x30b4
cmpq $0x9, %r11
setae %r11b
jmp 0x30d7
xorl %r11d, %r11d
movl %r10d, %ebx
subl %edi, %ebx
incl %ebx
testb %r11b, %r11b
cmovnel %ebx, %esi
movzbl %r8b, %r8d
cmovnel %edx, %r8d
xorb $0x1, %r11b
testb %r11b, %r8b
jne 0x3102
incq %r10
addq $0x78, %rcx
cmpq $0x14, %r10
jne 0x30a2
testl %esi, %esi
jle 0x3145
leal (%rsi,%rdi), %ecx
movslq %ecx, %rcx
movabsq $0x600000007, %rdx      # imm = 0x600000007
movq %rdi, %r8
movl $0x8, %r9d
movl $0x0, (%rax,%r9)
movq %rdx, -0x8(%rax,%r9)
addq $0xc, %r9
cmpq $0x80, %r9
jne 0x311f
incq %r8
addq $0x78, %rax
cmpq %rcx, %r8
jl 0x3119
callq 0x2e1e
movq 0x397f(%rip), %rdi      # 0x6ad0
testq %rdi, %rdi
je 0x3160
movl $0x50, %esi
callq 0x21e0
movq 0x3971(%rip), %rax      # 0x6ad8
movq %rax, 0x3962(%rip)      # 0x6ad0
movl $0x7, %edi
movl $0x4, %esi
xorl %edx, %edx
movl $0x3, %ecx
callq 0x27f7
movq %rax, 0x394d(%rip)      # 0x6ad8
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq