// File: ATOMIC-LICHESS[P]ATOMKRAFT/pawns.cpp
// Function: Score PawnInfo::updateShelter<(Color)0>(Position const&, Square)
Score PawnInfo::updateShelter(const Position& pos, Square ksq) {

  //OLD const int Shift = (Us == WHITE ? 8 : -8);

  Bitboard pawns;
  //OLD int r;
  int shelter = 0;

  if (relative_rank(Us, ksq) <= RANK_4)
  {
      pawns = pos.pieces(PAWN, Us) & this_and_neighboring_files_bb(ksq);
      
      
//      if (!useImprovements) {
//      
//      NEW // rank of the king, shifted left 3 (rank is indicated by 3 bits)
//      r = ksq & (7 << 3);
//      for (int i = 0; i < 3; i++)
//      {
//    	  NEW // rank of the king added 1 (white) or -1 (black), then shifted left 3
//    	  NEW // note that the relative rank is <= 3 
//    	  NEW // so we search for pawns the 4 ranks in front of the king
//          r += Shift;
//    	  
//    	  NEW // shelter counts the score
//    	  NEW // as i increases the rank in front our king r increases
//    	  NEW // we count the number of pawns in front of our king 
//    	  NEW // and scale the value by the distance
//    	  NEW // in normal chess great distance is bad, in atomic i don't know :)
//    	  NEW // tipau: it is less important to have the pawns close to the king
//          OLD shelter += BitCount8Bit[(pawns >> r) & 0xFF] * (64 >> i);
//    	  shelter += BitCount8Bit[(pawns >> r) & 0xFF] * 64;
//      }
      
      
      Color Them = opposite_color(Us);
      int rook_count = pos.piece_count(Them, ROOK) + pos.piece_count(Them, QUEEN);
      
      // pawn central in front of king?
      if (pos.pieces(PAWN, Us) & squares_in_front_of(Us, ksq)) {
    	  shelter += 60 * rook_count;
      }
      
      if (square_file(ksq) > FILE_A) {
    	  // pawn left (relative) in front of king?
    	  if (  pos.pieces(PAWN, Us) 
    		  & squares_in_front_of(Us, make_square(square_file(ksq) - File(1), square_rank(ksq)))) {
    		  shelter += 48 * rook_count;
    	  }
      } else {
    	  // ksq == FILE_A thus no shelter pawn needed
    	  shelter += 48 * rook_count;
      }
      
      if (square_file(ksq) < FILE_H) {
    	  // pawn right (relative) in front of king?
    	  if (  pos.pieces(PAWN, Us) 
    		  & squares_in_front_of(Us, make_square(square_file(ksq) + File(1), square_rank(ksq)))) {
    		  shelter += 48 * rook_count;
    	  }
      } else {
    	  // ksq == FILE_H thus no shelter pawn needed
    	  shelter += 48 * rook_count;
      }
      
      
      
      
  }
  kingSquares[Us] = ksq;
  kingShelters[Us] = make_score(shelter, 0);
  return kingShelters[Us];
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movl %edx, 0x64(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0x40(%rsp)
movl $0x0, 0x54(%rsp)
movl 0x64(%rsp), %esi
xorl %edi, %edi
callq 0x1b2c0
cmpl $0x3, %eax
jg 0x35757
movq 0x68(%rsp), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x16530
movq %rax, 0x28(%rsp)
movl 0x64(%rsp), %edi
callq 0xe660
movq %rax, %rcx
movq 0x28(%rsp), %rax
andq %rcx, %rax
movq %rax, 0x58(%rsp)
xorl %edi, %edi
callq 0x122b0
movl %eax, 0x50(%rsp)
movq 0x68(%rsp), %rdi
movl 0x50(%rsp), %esi
movl $0x4, %edx
callq 0x164c0
movl %eax, 0x34(%rsp)
movq 0x68(%rsp), %rdi
movl 0x50(%rsp), %esi
movl $0x5, %edx
callq 0x164c0
movl %eax, %ecx
movl 0x34(%rsp), %eax
addl %ecx, %eax
movl %eax, 0x4c(%rsp)
movq 0x68(%rsp), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x16530
movq %rax, 0x38(%rsp)
movl 0x64(%rsp), %esi
xorl %edi, %edi
callq 0x1b520
movq %rax, %rcx
movq 0x38(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x35647
imull $0x3c, 0x4c(%rsp), %eax
addl 0x54(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x64(%rsp), %edi
callq 0xce10
cmpl $0x0, %eax
jle 0x356c1
movq 0x68(%rsp), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x16530
movq %rax, 0x20(%rsp)
movl 0x64(%rsp), %edi
callq 0xce10
movl %eax, %edi
movl $0x1, %esi
callq 0xcdf0
movl %eax, 0x1c(%rsp)
movl 0x64(%rsp), %edi
callq 0xce40
movl 0x1c(%rsp), %edi
movl %eax, %esi
callq 0xd740
movl %eax, %esi
xorl %edi, %edi
callq 0x1b520
movq %rax, %rcx
movq 0x20(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x356bf
imull $0x30, 0x4c(%rsp), %eax
addl 0x54(%rsp), %eax
movl %eax, 0x54(%rsp)
jmp 0x356ce
imull $0x30, 0x4c(%rsp), %eax
addl 0x54(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x64(%rsp), %edi
callq 0xce10
cmpl $0x7, %eax
jge 0x35748
movq 0x68(%rsp), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x16530
movq %rax, 0x10(%rsp)
movl 0x64(%rsp), %edi
callq 0xce10
movl %eax, %edi
movl $0x1, %esi
callq 0x35780
movl %eax, 0xc(%rsp)
movl 0x64(%rsp), %edi
callq 0xce40
movl 0xc(%rsp), %edi
movl %eax, %esi
callq 0xd740
movl %eax, %esi
xorl %edi, %edi
callq 0x1b520
movq %rax, %rcx
movq 0x10(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x35746
imull $0x30, 0x4c(%rsp), %eax
addl 0x54(%rsp), %eax
movl %eax, 0x54(%rsp)
jmp 0x35755
imull $0x30, 0x4c(%rsp), %eax
addl 0x54(%rsp), %eax
movl %eax, 0x54(%rsp)
jmp 0x35757
movq 0x40(%rsp), %rax
movl 0x64(%rsp), %ecx
movl %ecx, 0x28(%rax)
movl 0x54(%rsp), %edi
xorl %esi, %esi
callq 0x27f40
movl %eax, %ecx
movq 0x40(%rsp), %rax
movl %ecx, 0x3c(%rax)
movl 0x3c(%rax), %eax
addq $0x78, %rsp
retq