// File: kobanium[P]Ray/src/board/SearchBoard.cpp
// Function: PutStoneForSearch(search_game_info_t*, int, int)
void
PutStoneForSearch( search_game_info_t *game, const int pos, const int color )
{
  int *string_id = game->string_id;
  char *board = game->board;
  string_t *string = game->string;
  int other = GetOppositeColor(color);
  int connection = 0;
  int connect[4] = { 0 };
  int prisoner = 0;
  int neighbor[4];

  // 着手箇所と色を記録
  if (game->moves < MAX_RECORDS) {
    game->record[game->moves].color = color;
    game->record[game->moves].pos = pos;
    game->undo[game->moves].strings = 0;
  }

  // 着手がパスなら手数を進めて終了
  if (pos == PASS) {
    game->moves++;
    return;
  }

  // 石を置く
  board[pos] = (char)color;

  // 候補手から除外
  game->candidates[pos] = false;

  // パターンの更新(MD5)
  UpdateMD2Stone(game->pat, color, pos);

  // 着手点の上下左右の座標を導出
  GetNeighbor4(neighbor, pos);

  // 着手箇所の上下左右の確認
  // 自分の連があれば, その連の呼吸点を1つ減らし, 接続候補に入れる
  // 敵の連であれば, その連の呼吸点を1つ減らし, 呼吸点が0になったら取り除く
  for (int i = 0; i < 4; i++) {
    if (board[neighbor[i]] == color) {
      RemoveLiberty(game, &string[string_id[neighbor[i]]], pos);
      connect[connection++] = string_id[neighbor[i]];
    } else if (board[neighbor[i]] == other) {
      RemoveLiberty(game, &string[string_id[neighbor[i]]], pos);
      if (string[string_id[neighbor[i]]].libs == 0) {
        RecordString(game, string_id[neighbor[i]]);
        prisoner += RemoveString(game, &string[string_id[neighbor[i]]]);
      }
    }
  }

  // 打ち上げた石をアゲハマに追加
  game->prisoner[color] += prisoner;

  // 接続候補がなければ, 新しい連を作成して, 劫かどうかの確認をする
  // 接続候補が1つならば, その連に石を追加する
  // 接続候補が2つ以上ならば, 連同士を繋ぎ合わせて, 石を追加する
  if (connection == 0) {
    MakeString(game, pos, color);
    if (prisoner == 1 &&
        string[string_id[pos]].libs == 1) {
      game->ko_move = game->moves;
      game->ko_pos = string[string_id[pos]].lib[0];
    }
  } else if (connection == 1) {
    RecordString(game, connect[0]);
    AddStone(game, pos, color, connect[0]);
  } else {
    ConnectString(game, pos, color, connection, connect);
  }

  // 手数を1つだけ進める
  game->moves++;
  memset(&game->undo[game->moves], 0, sizeof(undo_record_t));
  game->undo[game->moves].ko_move_record = game->ko_move;
  game->undo[game->moves].ko_pos_record = game->ko_pos;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rax
addq $0x956f0, %rax          # imm = 0x956F0
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
addq $0x43cc, %rax           # imm = 0x43CC
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rax
addq $0x95f0, %rax           # imm = 0x95F0
movq %rax, -0x28(%rbp)
movl -0x10(%rbp), %edi
callq 0x25810
movl %eax, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x72b0
movl $0x0, -0x44(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x43b, 0x43b0(%rax)    # imm = 0x43B
jge 0x987d5
movl -0x10(%rbp), %ecx
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rdx
movslq 0x43b0(%rdx), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
movl -0xc(%rbp), %ecx
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rdx
movslq 0x43b0(%rdx), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, 0x4(%rax)
movq -0x8(%rbp), %rax
addq $0x96ffc, %rax          # imm = 0x96FFC
movq -0x8(%rbp), %rcx
movslq 0x43b0(%rcx), %rcx
imulq $0x16c0, %rcx, %rcx     # imm = 0x16C0
addq %rcx, %rax
movl $0x0, 0x16b0(%rax)
cmpl $0x0, -0xc(%rbp)
jne 0x987f3
movq -0x8(%rbp), %rax
movl 0x43b0(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x43b0(%rax)
jmp 0x98adf
movl -0x10(%rbp), %eax
movb %al, %dl
movq -0x20(%rbp), %rax
movslq -0xc(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x8(%rbp), %rax
movslq -0xc(%rbp), %rcx
movb $0x0, 0x96cb0(%rax,%rcx)
movq -0x8(%rbp), %rdi
addq $0x4718, %rdi           # imm = 0x4718
movl -0x10(%rbp), %esi
movl -0xc(%rbp), %edx
callq 0x90cc0
leaq -0x60(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x9bc90
movl $0x0, -0x64(%rbp)
cmpl $0x4, -0x64(%rbp)
jge 0x98972
movq -0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl -0x10(%rbp), %eax
jne 0x988ad
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x18(%rbp), %rax
movslq -0x64(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movslq (%rax,%rcx,4), %rax
imulq $0x7c8, %rax, %rax      # imm = 0x7C8
addq %rax, %rsi
movl -0xc(%rbp), %edx
callq 0x98af0
movq -0x18(%rbp), %rax
movslq -0x64(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movl (%rax,%rcx,4), %ecx
movl -0x30(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x30(%rbp)
cltq
movl %ecx, -0x40(%rbp,%rax,4)
jmp 0x98962
movq -0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl -0x2c(%rbp), %eax
jne 0x98960
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x18(%rbp), %rax
movslq -0x64(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movslq (%rax,%rcx,4), %rax
imulq $0x7c8, %rax, %rax      # imm = 0x7C8
addq %rax, %rsi
movl -0xc(%rbp), %edx
callq 0x98af0
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
movslq -0x64(%rbp), %rdx
movslq -0x60(%rbp,%rdx,4), %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x0, 0x4(%rax)
jne 0x9895e
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq -0x64(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movl (%rax,%rcx,4), %esi
callq 0x98bb0
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x18(%rbp), %rax
movslq -0x64(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movslq (%rax,%rcx,4), %rax
imulq $0x7c8, %rax, %rax      # imm = 0x7C8
addq %rax, %rsi
callq 0x98cf0
addl -0x44(%rbp), %eax
movl %eax, -0x44(%rbp)
jmp 0x98960
jmp 0x98962
jmp 0x98964
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x9883c
movl -0x44(%rbp), %edx
movq -0x8(%rbp), %rax
movslq -0x10(%rbp), %rcx
addl 0x43b4(%rax,%rcx,4), %edx
movl %edx, 0x43b4(%rax,%rcx,4)
cmpl $0x0, -0x30(%rbp)
jne 0x98a04
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
callq 0x98f90
cmpl $0x1, -0x44(%rbp)
jne 0x98a02
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
movslq -0xc(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0x98a02
movq -0x8(%rbp), %rax
movl 0x43b0(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x43c8(%rax)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
movslq -0xc(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x43c4(%rax)
jmp 0x98a42
cmpl $0x1, -0x30(%rbp)
jne 0x98a2a
movq -0x8(%rbp), %rdi
movl -0x40(%rbp), %esi
callq 0x98bb0
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movl -0x40(%rbp), %ecx
callq 0x991b0
jmp 0x98a40
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movl -0x30(%rbp), %ecx
leaq -0x40(%rbp), %r8
callq 0x99300
jmp 0x98a42
movq -0x8(%rbp), %rax
movl 0x43b0(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x43b0(%rax)
movq -0x8(%rbp), %rdi
addq $0x96ffc, %rdi          # imm = 0x96FFC
movq -0x8(%rbp), %rax
movslq 0x43b0(%rax), %rax
imulq $0x16c0, %rax, %rax     # imm = 0x16C0
addq %rax, %rdi
xorl %esi, %esi
movl $0x16c0, %edx           # imm = 0x16C0
callq 0x72b0
movq -0x8(%rbp), %rax
movl 0x43c8(%rax), %ecx
movq -0x8(%rbp), %rax
addq $0x96ffc, %rax          # imm = 0x96FFC
movq -0x8(%rbp), %rdx
movslq 0x43b0(%rdx), %rdx
imulq $0x16c0, %rdx, %rdx     # imm = 0x16C0
addq %rdx, %rax
movl %ecx, 0x16b8(%rax)
movq -0x8(%rbp), %rax
movl 0x43c4(%rax), %ecx
movq -0x8(%rbp), %rax
addq $0x96ffc, %rax          # imm = 0x96FFC
movq -0x8(%rbp), %rdx
movslq 0x43b0(%rdx), %rdx
imulq $0x16c0, %rdx, %rdx     # imm = 0x16C0
addq %rdx, %rax
movl %ecx, 0x16bc(%rax)
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)