// File: Dalgona[P]mine/game.cpp
// Function: game::step(int, int)
int game::step(int cy, int cx)
{
  int count = 0;
  int i, j;
  int &cp = field[index(cy, cx)];

  if (newGame)
  {
    newGame = false;
    // Plant mines
    long double x = std::log(2.15561e+9);
    long double ratio = std::log(rows * cols) / x - 0.08101856l; // logarithmic
    //long double ratio = 0.000207502l * rows * cols + 0.106649146l; // linear
    nMines = (int)lround(ratio * rows * cols);
    std::random_device rd;
    std::uniform_int_distribution<int> dist(0, rows * cols - 1);
    int idx, c = 0;

    while (true)
    {
      idx = dist(rd);
      if (idx == index(cy, cx) || field[idx] & MF_MINE) continue;
      field[idx] |= MF_MINE;
      c++;
      if (c == nMines) break;
    }

    clear();
    tBegin = steady_clock::now();
  }

  if (cp & MF_DISP_UNKNOWN)
    if (cp & MF_MINE) return 0xFF; // When the player stepped on a mine
    else
    {
      for (i = cy - 1; i <= cy + 1; i++)
        for (j = cx - 1; j <= cx + 1; j++)
          if (i < 0 || i >= rows || j < 0 || j >= cols) continue;
          else if (field[index(i, j)] & MF_MINE) count++;
      if (count == 0)
      {
        cp &= ~MF_DISP_UNKNOWN;
        cp |= MF_DISP_EMPTY;
        for (i = cy - 1; i <= cy + 1; i++)
          for (j = cx - 1; j <= cx + 1; j++)
            if (i < 0 || i >= rows || j < 0 || j >= cols) continue;
            else step(i, j);
      }
      else
      {
        cp &= ~MF_DISP_UNKNOWN;
        cp |= MF_DISP_NUMBER;
        cp |= (count << 24);
      }
      return 0;
    }
  else return -1;
}

// Assembly:
subq $0x1448, %rsp           # imm = 0x1448
movq %rdi, 0x1438(%rsp)
movl %esi, 0x1434(%rsp)
movl %edx, 0x1430(%rsp)
movq 0x1438(%rsp), %rdi
movq %rdi, 0x18(%rsp)
movl $0x0, 0x142c(%rsp)
movq %rdi, %rax
addq $0x8, %rax
movq %rax, 0x10(%rsp)
movl 0x1434(%rsp), %esi
movl 0x1430(%rsp), %edx
callq 0xcfd0
movq 0x10(%rsp), %rdi
movslq %eax, %rsi
callq 0xe400
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x1418(%rsp)
testb $0x1, 0x3c(%rax)
je 0xcbf2
movq 0x18(%rsp), %rax
movb $0x0, 0x3c(%rax)
movsd 0x5a5c(%rip), %xmm0     # 0x124a8
callq 0x21b0
movq 0x18(%rsp), %rax
movsd %xmm0, 0x30(%rsp)
fldl 0x30(%rsp)
fstpt 0x1400(%rsp)
movl 0x20(%rax), %edi
movl 0x24(%rax), %eax
imull %eax, %edi
callq 0xe420
movq 0x18(%rsp), %rax
movsd %xmm0, 0x28(%rsp)
fldl 0x28(%rsp)
fldt 0x1400(%rsp)
fdivrp %st, %st(1)
fldt 0x5a2d(%rip)            # 0x124c0
faddp %st, %st(1)
fstpt 0x13f0(%rsp)
fldt 0x13f0(%rsp)
movl 0x20(%rax), %ecx
movl 0x24(%rax), %eax
movl %ecx, 0x3c(%rsp)
fildl 0x3c(%rsp)
fmulp %st, %st(1)
movl %eax, 0x38(%rsp)
fildl 0x38(%rsp)
fmulp %st, %st(1)
fstpl 0x20(%rsp)
movsd 0x20(%rsp), %xmm0
callq 0x2030
movq %rax, %rcx
movq 0x18(%rsp), %rax
movl %ecx, 0x30(%rax)
leaq 0x68(%rsp), %rdi
callq 0xe440
movq 0x18(%rsp), %rax
movl 0x20(%rax), %edx
movl 0x24(%rax), %eax
imull %eax, %edx
decl %edx
leaq 0x60(%rsp), %rdi
xorl %esi, %esi
callq 0xe4e0
jmp 0xcaff
movl $0x0, 0x4c(%rsp)
jmp 0xcb09
leaq 0x60(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0xe510
movl %eax, 0xc(%rsp)
jmp 0xcb1e
movq 0x18(%rsp), %rdi
movl 0xc(%rsp), %eax
movl %eax, 0x50(%rsp)
movl 0x50(%rsp), %eax
movl %eax, 0x8(%rsp)
movl 0x1434(%rsp), %esi
movl 0x1430(%rsp), %edx
callq 0xcfd0
movl %eax, %ecx
movl 0x8(%rsp), %eax
cmpl %ecx, %eax
je 0xcb6d
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
movslq 0x50(%rsp), %rsi
callq 0xe400
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xcb8c
jmp 0xcb07
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x58(%rsp)
movl %eax, 0x54(%rsp)
leaq 0x68(%rsp), %rdi
callq 0xe540
jmp 0xce96
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
movslq 0x50(%rsp), %rsi
callq 0xe400
movq 0x18(%rsp), %rcx
movl (%rax), %edx
orl $0x1, %edx
movl %edx, (%rax)
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
cmpl 0x30(%rcx), %eax
jne 0xcbc1
jmp 0xcbc6
jmp 0xcb07
callq 0x23f0
jmp 0xcbcd
callq 0x2330
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x40(%rsp)
movq 0x40(%rsp), %rcx
movq %rcx, 0x40(%rax)
leaq 0x68(%rsp), %rdi
callq 0xe540
movq 0x1418(%rsp), %rax
movl (%rax), %eax
andl $0x10000, %eax          # imm = 0x10000
cmpl $0x0, %eax
je 0xce7c
movq 0x1418(%rsp), %rax
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xcc2c
movl $0xff, 0x1444(%rsp)
jmp 0xce87
movl 0x1434(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x1428(%rsp)
movl 0x1428(%rsp), %eax
movl 0x1434(%rsp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jg 0xcd34
movl 0x1430(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x1424(%rsp)
movl 0x1424(%rsp), %eax
movl 0x1430(%rsp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jg 0xcd1c
cmpl $0x0, 0x1428(%rsp)
jl 0xccb6
movq 0x18(%rsp), %rcx
movl 0x1428(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0xccb6
cmpl $0x0, 0x1424(%rsp)
jl 0xccb6
movq 0x18(%rsp), %rcx
movl 0x1424(%rsp), %eax
cmpl 0x24(%rcx), %eax
jl 0xccb8
jmp 0xcd06
movq 0x18(%rsp), %rdi
movq %rdi, %rax
addq $0x8, %rax
movq %rax, (%rsp)
movl 0x1428(%rsp), %esi
movl 0x1424(%rsp), %edx
callq 0xcfd0
movq (%rsp), %rdi
movslq %eax, %rsi
callq 0xe400
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xcd02
movl 0x142c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x142c(%rsp)
jmp 0xcd04
jmp 0xcd06
movl 0x1424(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1424(%rsp)
jmp 0xcc67
jmp 0xcd1e
movl 0x1428(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1428(%rsp)
jmp 0xcc3d
cmpl $0x0, 0x142c(%rsp)
jne 0xce35
movq 0x1418(%rsp), %rax
movl (%rax), %ecx
andl $0xfffeffff, %ecx       # imm = 0xFFFEFFFF
movl %ecx, (%rax)
movq 0x1418(%rsp), %rax
movl (%rax), %ecx
orl $0x20000, %ecx          # imm = 0x20000
movl %ecx, (%rax)
movl 0x1434(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x1428(%rsp)
movl 0x1428(%rsp), %eax
movl 0x1434(%rsp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jg 0xce33
movl 0x1430(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x1424(%rsp)
movl 0x1424(%rsp), %eax
movl 0x1430(%rsp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jg 0xce1b
cmpl $0x0, 0x1428(%rsp)
jl 0xcdec
movq 0x18(%rsp), %rcx
movl 0x1428(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0xcdec
cmpl $0x0, 0x1424(%rsp)
jl 0xcdec
movq 0x18(%rsp), %rcx
movl 0x1424(%rsp), %eax
cmpl 0x24(%rcx), %eax
jl 0xcdee
jmp 0xce08
movq 0x18(%rsp), %rdi
movl 0x1428(%rsp), %esi
movl 0x1424(%rsp), %edx
callq 0xc9c0
jmp 0xce08
movl 0x1424(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1424(%rsp)
jmp 0xcda1
jmp 0xce1d
movl 0x1428(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1428(%rsp)
jmp 0xcd77
jmp 0xce6f
movq 0x1418(%rsp), %rax
movl (%rax), %ecx
andl $0xfffeffff, %ecx       # imm = 0xFFFEFFFF
movl %ecx, (%rax)
movq 0x1418(%rsp), %rax
movl (%rax), %ecx
orl $0x40000000, %ecx       # imm = 0x40000000
movl %ecx, (%rax)
movl 0x142c(%rsp), %ecx
shll $0x18, %ecx
movq 0x1418(%rsp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movl $0x0, 0x1444(%rsp)
jmp 0xce87
movl $0xffffffff, 0x1444(%rsp) # imm = 0xFFFFFFFF
movl 0x1444(%rsp), %eax
addq $0x1448, %rsp           # imm = 0x1448
retq
movq 0x58(%rsp), %rdi
callq 0x2400