// File: Dalgona[P]mine/game.cpp
// Function: game::start()
void game::start()
{
  // Initialize ncurses mode
  if (!scr->enabled) return;

  initColors();

  clear();
  updateDisplay();

  std::srand(std::time(nullptr));

  // Main game loop
  while (true)
  {
    int key = getch();
    int result = 0;

    switch (key)
    {
    case KEY_LEFT:  case 'h': cX = cX == 0 ? cols - 1 : cX - 1; break;
    case KEY_DOWN:  case 'j': cY = cY == rows - 1 ? 0 : cY + 1; break;
    case KEY_UP:    case 'k': cY = cY == 0 ? rows - 1 : cY - 1; break;
    case KEY_RIGHT: case 'l': cX = cX == cols - 1 ? 0 : cX + 1; break;

    case 'f': setFlag();             break;
    case 'q': setQuestionMark();     break;
    case 's': result = step(cY, cX); break;

    case KEY_RESIZE:
      scr->updateMaxYX();
      clear();
      break;
    }

    // Game Over
    if (result == 0xFF)
    {
      for (auto &i : field) if (i & MF_MINE) i = MF_DISP_MINE;
      updateDisplay();
      scr->with_color(2, [&]() {
        scr->mvprintw(-3, 0, "GAME OVER! You stepped on a mine!");
      });
      this->result.win = false;
      break;
    }
    // Game Cleared
    if (!newGame && nMines == nFlags)
    {
      clearValidate = 0;
      for (const auto &i : field)
        if (i & MF_MINE && i & MF_DISP_FLAG) clearValidate++;
      if (clearValidate == nMines)
      {
        for (auto &i : field) if (i & MF_MINE) i = MF_DISP_MINE_CLR;
        updateDisplay();
        scr->with_color(3, [&]() {
          scr->mvprintw(-3, 0, "CONGRATULATIONS! You've found all mine!");
        });
        this->result.win = true;
        break;
      }
    }

    updateDisplay();
  }

  tEnd = steady_clock::now();
  int elapsed = this->result.time =  (int)duration<double, std::centi>(tEnd - tBegin).count();
  scr->mvprintw(-2, 0, "Elapsed time: %04d.%02d seconds\n", elapsed / 100, elapsed % 100);
  clrtoeol();
  {
    scr->mvprintw(-1, 0, "Press ENTER to exit...");
    int key;
    while (true)
    {
      key = getch();
      if (key == KEY_ENTER || key == '\n') break;
    }
  }

  clear();
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x130(%rsp)
movq 0x130(%rsp), %rax
movq %rax, 0x38(%rsp)
movq (%rax), %rax
testb $0x1, (%rax)
jne 0xbb89
jmp 0xc1f3
movq 0x38(%rsp), %rdi
callq 0xc210
callq 0x23f0
movq 0x38(%rsp), %rdi
callq 0xc390
xorl %eax, %eax
movl %eax, %edi
callq 0x21f0
movl %eax, %edi
callq 0x2230
movq 0xe41f(%rip), %rax      # 0x19fd8
movq (%rax), %rdi
callq 0x20f0
movl %eax, 0x12c(%rsp)
movl $0x0, 0x128(%rsp)
movl 0x12c(%rsp), %eax
movl %eax, 0x34(%rsp)
subl $0x66, %eax
je 0xbd7d
jmp 0xbbe9
movl 0x34(%rsp), %eax
subl $0x68, %eax
je 0xbc97
jmp 0xbbf8
movl 0x34(%rsp), %eax
subl $0x6a, %eax
je 0xbcd3
jmp 0xbc07
movl 0x34(%rsp), %eax
subl $0x6b, %eax
je 0xbd0d
jmp 0xbc16
movl 0x34(%rsp), %eax
subl $0x6c, %eax
je 0xbd46
jmp 0xbc25
movl 0x34(%rsp), %eax
subl $0x71, %eax
je 0xbd89
jmp 0xbc34
movl 0x34(%rsp), %eax
subl $0x73, %eax
je 0xbd95
jmp 0xbc43
movl 0x34(%rsp), %eax
subl $0x102, %eax            # imm = 0x102
je 0xbcd3
jmp 0xbc54
movl 0x34(%rsp), %eax
subl $0x103, %eax            # imm = 0x103
je 0xbd0d
jmp 0xbc65
movl 0x34(%rsp), %eax
subl $0x104, %eax            # imm = 0x104
je 0xbc97
jmp 0xbc72
movl 0x34(%rsp), %eax
subl $0x105, %eax            # imm = 0x105
je 0xbd46
jmp 0xbc83
movl 0x34(%rsp), %eax
subl $0x19a, %eax            # imm = 0x19A
je 0xbdae
jmp 0xbdc0
movq 0x38(%rsp), %rax
cmpl $0x0, 0x2c(%rax)
jne 0xbcb3
movq 0x38(%rsp), %rax
movl 0x24(%rax), %eax
subl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0xbcc2
movq 0x38(%rsp), %rax
movl 0x2c(%rax), %eax
subl $0x1, %eax
movl %eax, 0x30(%rsp)
movq 0x38(%rsp), %rax
movl 0x30(%rsp), %ecx
movl %ecx, 0x2c(%rax)
jmp 0xbdc0
movq 0x38(%rsp), %rcx
movl 0x28(%rcx), %eax
movl 0x20(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0xbced
xorl %eax, %eax
movl %eax, 0x2c(%rsp)
jmp 0xbcfc
movq 0x38(%rsp), %rax
movl 0x28(%rax), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
movq 0x38(%rsp), %rax
movl 0x2c(%rsp), %ecx
movl %ecx, 0x28(%rax)
jmp 0xbdc0
movq 0x38(%rsp), %rax
cmpl $0x0, 0x28(%rax)
jne 0xbd29
movq 0x38(%rsp), %rax
movl 0x20(%rax), %eax
subl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0xbd38
movq 0x38(%rsp), %rax
movl 0x28(%rax), %eax
subl $0x1, %eax
movl %eax, 0x28(%rsp)
movq 0x38(%rsp), %rax
movl 0x28(%rsp), %ecx
movl %ecx, 0x28(%rax)
jmp 0xbdc0
movq 0x38(%rsp), %rcx
movl 0x2c(%rcx), %eax
movl 0x24(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0xbd60
xorl %eax, %eax
movl %eax, 0x24(%rsp)
jmp 0xbd6f
movq 0x38(%rsp), %rax
movl 0x2c(%rax), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
movq 0x38(%rsp), %rax
movl 0x24(%rsp), %ecx
movl %ecx, 0x2c(%rax)
jmp 0xbdc0
movq 0x38(%rsp), %rdi
callq 0xc7c0
jmp 0xbdc0
movq 0x38(%rsp), %rdi
callq 0xc8d0
jmp 0xbdc0
movq 0x38(%rsp), %rdi
movl 0x28(%rdi), %esi
movl 0x2c(%rdi), %edx
callq 0xc9c0
movl %eax, 0x128(%rsp)
jmp 0xbdc0
movq 0x38(%rsp), %rax
movq (%rax), %rdi
callq 0x11080
callq 0x23f0
cmpl $0xff, 0x128(%rsp)
jne 0xbefd
movq 0x38(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x120(%rsp)
movq 0x120(%rsp), %rdi
callq 0xe290
movq %rax, 0x118(%rsp)
movq 0x120(%rsp), %rdi
callq 0xe2c0
movq %rax, 0x110(%rsp)
leaq 0x118(%rsp), %rdi
leaq 0x110(%rsp), %rsi
callq 0xe2f0
testb $0x1, %al
jne 0xbe27
jmp 0xbe6d
leaq 0x118(%rsp), %rdi
callq 0xe330
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rax
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xbe5c
movq 0x108(%rsp), %rax
movl $0x100000, (%rax)       # imm = 0x100000
jmp 0xbe5e
leaq 0x118(%rsp), %rdi
callq 0xe340
jmp 0xbe0c
movq 0x38(%rsp), %rdi
callq 0xc390
movq 0x38(%rsp), %rax
movq (%rax), %rcx
movq %rcx, 0x10(%rsp)
movq %rax, 0xe0(%rsp)
leaq 0xe8(%rsp), %rdi
movq %rdi, 0x18(%rsp)
leaq 0xe0(%rsp), %rsi
callq 0xcea0
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rdx
movl $0x2, %esi
callq 0x11360
jmp 0xbebc
leaq 0xe8(%rsp), %rdi
callq 0x8c90
movq 0x38(%rsp), %rax
movb $0x0, 0x50(%rax)
jmp 0xc10e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd8(%rsp)
movl %eax, 0xd4(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x8c90
jmp 0xc1fb
movq 0x38(%rsp), %rax
testb $0x1, 0x3c(%rax)
jne 0xc0ff
movq 0x38(%rsp), %rcx
movl 0x30(%rcx), %eax
cmpl 0x34(%rcx), %eax
jne 0xc0ff
movq 0x38(%rsp), %rax
movl $0x0, 0x38(%rax)
addq $0x8, %rax
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rdi
callq 0xe290
movq %rax, 0xc0(%rsp)
movq 0xc8(%rsp), %rdi
callq 0xe2c0
movq %rax, 0xb8(%rsp)
leaq 0xc0(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0xe2f0
testb $0x1, %al
jne 0xbf7a
jmp 0xbfd4
leaq 0xc0(%rsp), %rdi
callq 0xe330
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rax
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xbfc3
movq 0xb0(%rsp), %rax
movl (%rax), %eax
andl $0x40000, %eax          # imm = 0x40000
cmpl $0x0, %eax
je 0xbfc3
movq 0x38(%rsp), %rax
movl 0x38(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x38(%rax)
jmp 0xbfc5
leaq 0xc0(%rsp), %rdi
callq 0xe340
jmp 0xbf5f
movq 0x38(%rsp), %rcx
movl 0x38(%rcx), %eax
cmpl 0x30(%rcx), %eax
jne 0xc0fd
movq 0x38(%rsp), %rax
addq $0x8, %rax
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rdi
callq 0xe290
movq %rax, 0xa0(%rsp)
movq 0xa8(%rsp), %rdi
callq 0xe2c0
movq %rax, 0x98(%rsp)
leaq 0xa0(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0xe2f0
testb $0x1, %al
jne 0xc03b
jmp 0xc081
leaq 0xa0(%rsp), %rdi
callq 0xe330
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xc070
movq 0x90(%rsp), %rax
movl $0xe00000, (%rax)       # imm = 0xE00000
jmp 0xc072
leaq 0xa0(%rsp), %rdi
callq 0xe340
jmp 0xc020
movq 0x38(%rsp), %rdi
callq 0xc390
movq 0x38(%rsp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq %rax, 0x68(%rsp)
leaq 0x70(%rsp), %rdi
movq %rdi, 0x8(%rsp)
leaq 0x68(%rsp), %rsi
callq 0xcf30
movq (%rsp), %rdi
movq 0x8(%rsp), %rdx
movl $0x3, %esi
callq 0x11360
jmp 0xc0c5
leaq 0x70(%rsp), %rdi
callq 0x8c90
movq 0x38(%rsp), %rax
movb $0x1, 0x50(%rax)
jmp 0xc10e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd8(%rsp)
movl %eax, 0xd4(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x8c90
jmp 0xc1fb
jmp 0xc0ff
movq 0x38(%rsp), %rdi
callq 0xc390
jmp 0xbbb2
callq 0x2330
movq 0x38(%rsp), %rsi
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x48(%rsi)
movq %rsi, %rdi
addq $0x48, %rdi
addq $0x40, %rsi
callq 0xe360
movq %rax, 0x48(%rsp)
leaq 0x50(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0xe3b0
leaq 0x50(%rsp), %rdi
callq 0xe3f0
movq 0x38(%rsp), %rax
cvttsd2si %xmm0, %ecx
movl %ecx, 0x54(%rax)
movl %ecx, 0x5c(%rsp)
movq (%rax), %rdi
movl 0x5c(%rsp), %eax
movl $0x64, %ecx
cltd
idivl %ecx
movl %eax, %r8d
movl 0x5c(%rsp), %eax
movl $0x64, %ecx
cltd
idivl %ecx
movl %edx, %r9d
movl $0xfffffffe, %esi       # imm = 0xFFFFFFFE
xorl %edx, %edx
leaq 0x6411(%rip), %rcx      # 0x125a4
movb $0x0, %al
callq 0x11230
movq 0xde37(%rip), %rax      # 0x19fd8
movq (%rax), %rdi
callq 0x2280
movq 0x38(%rsp), %rax
movq (%rax), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
xorl %edx, %edx
leaq 0x6406(%rip), %rcx      # 0x125c5
movb $0x0, %al
callq 0x11230
movq 0xde0b(%rip), %rax      # 0x19fd8
movq (%rax), %rdi
callq 0x20f0
movl %eax, 0x44(%rsp)
cmpl $0x157, 0x44(%rsp)      # imm = 0x157
je 0xc1ea
cmpl $0xa, 0x44(%rsp)
jne 0xc1ec
jmp 0xc1ee
jmp 0xc1c6
callq 0x23f0
addq $0x138, %rsp            # imm = 0x138
retq
movq 0xd8(%rsp), %rdi
callq 0x2400
nopl (%rax,%rax)