// File: kaiming[P]Chamber-Crawler-3k/Board/board.cc
// Function: Board::validDest(std::shared_ptr<WalkableTile>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
std::shared_ptr<WalkableTile> Board::validDest(std::shared_ptr<WalkableTile> centre, std::string direction) {
    
    // Set up variable to hold destination
    std::shared_ptr<Tile> destination;

    // Coordinate system with (0,0) in the top left
    //   first int is x value, increases left to right
    //   second int is y value, increases top to bottom

    // std::pair<int x, int y>
    if (direction == "no") {
        // no = North/Up
        std::pair<int, int> current = centre->getCoord();

        // Check if in bounds
        if (current.second - 1 < 0) {
            return nullptr;
        }

        destination = floors[floorNum-1][current.second - 1][current.first];
    } else if (direction == "so") {
        // so = South/Down
        std::pair<int, int> current = centre->getCoord();

        // Check if in bounds
        if (current.second + 1 >= static_cast<int>(floors[floorNum-1].size())) {
            return nullptr;
        }

        destination = floors[floorNum-1][current.second + 1][current.first];
    } else if (direction == "ea") {
        // ea = East/Right
        std::pair<int, int> current = centre->getCoord();

        // Check if in bounds
        if (current.first + 1 >= static_cast<int>(floors[floorNum-1][1].size())) {
            return nullptr;
        }

        destination = floors[floorNum-1][current.second][current.first + 1];
    } else if (direction == "we") {
        // we = West/Left
        std::pair<int, int> current = centre->getCoord();

        // Check if in bounds
        if (current.first - 1 < 0) {
            return nullptr;
        }

        destination = floors[floorNum-1][current.second][current.first - 1];
    } else if (direction == "ne") { // ----------------------------------------------------------------------
        // ne = North East/Right and Up
        std::pair<int, int> current = centre->getCoord();

        // Check if in bounds
        if (current.first + 1 >= static_cast<int>(floors[floorNum-1][1].size()) || current.second - 1 < 0) {
            return nullptr;
        }

        destination = floors[floorNum-1][current.second - 1][current.first + 1];
    } else if (direction == "nw") {
        // nw = North West/Left and Up 
        std::pair<int, int> current = centre->getCoord();

        // Check if in bounds
        if (current.first - 1 < 0 || current.second - 1 < 0) {
            return nullptr;
        }

        destination = floors[floorNum-1][current.second - 1][current.first - 1];
    } else if (direction == "se") {
        // se = South East/Right and Down
        std::pair<int, int> current = centre->getCoord();

        // Check if in bounds
        if (current.first + 1 >= static_cast<int>(floors[floorNum-1][1].size()) || current.second + 1 >= static_cast<int>(floors[floorNum-1].size())) {
            return nullptr;
        }

        destination = floors[floorNum-1][current.second + 1][current.first + 1];
    } else if (direction == "sw") {
        // sw = South West/Left and Down
        std::pair<int, int> current = centre->getCoord();

        // Check if in bounds
        if (current.first - 1 < 0 || current.second + 1 >= static_cast<int>(floors[floorNum-1].size())) {
            return nullptr;
        }

        destination = floors[floorNum-1][current.second + 1][current.first - 1];
    } else {
        // Invalid direction
        return nullptr;
    }

    // Check destination tile to see if it's a WalkableTile
    std::shared_ptr<WalkableTile> typeCheck = std::dynamic_pointer_cast<WalkableTile>(destination);
    if (typeCheck) {
        // Destination is a valid, WalkableTile 
        return typeCheck;        
    }

    return nullptr;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rcx, -0xa0(%rbp)
movq %rdx, -0xc0(%rbp)
movq %rdi, -0xb8(%rbp)
movq %rdi, %rax
movq %rax, -0xb0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa8(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2e090
movq -0xa0(%rbp), %rdi
leaq 0x181c5(%rip), %rsi     # 0x3d301
callq 0x8ae0
movb %al, -0x91(%rbp)
jmp 0x25149
movb -0x91(%rbp), %al
testb $0x1, %al
jne 0x25158
jmp 0x25207
movq -0xc0(%rbp), %rdi
callq 0x2e040
movq %rax, %rdi
callq 0x3be40
movq %rax, -0xc8(%rbp)
jmp 0x25175
movq -0xc8(%rbp), %rax
movq %rax, -0x44(%rbp)
movl -0x40(%rbp), %eax
subl $0x1, %eax
cmpl $0x0, %eax
jge 0x251c1
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xa1d0
jmp 0x25959
movq -0xa8(%rbp), %rdi
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl -0x40(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11fc0
movq %rax, %rdi
movslq -0x44(%rbp), %rsi
callq 0x2e0b0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x2e0d0
jmp 0x258df
movq -0xa0(%rbp), %rdi
leaq 0x180ef(%rip), %rsi     # 0x3d304
callq 0x8ae0
movb %al, -0xc9(%rbp)
jmp 0x25222
movb -0xc9(%rbp), %al
testb $0x1, %al
jne 0x25231
jmp 0x252f4
movq -0xc0(%rbp), %rdi
callq 0x2e040
movq %rax, %rdi
callq 0x3be40
movq %rax, -0xd8(%rbp)
jmp 0x2524e
movq -0xa8(%rbp), %rdi
movq -0xd8(%rbp), %rax
movq %rax, -0x50(%rbp)
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xdc(%rbp)
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
callq 0xb360
movq %rax, %rcx
movl -0xdc(%rbp), %eax
cmpl %ecx, %eax
jl 0x252ae
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
movq -0xa8(%rbp), %rdi
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x11fc0
movq %rax, %rdi
movslq -0x50(%rbp), %rsi
callq 0x2e0b0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x2e0d0
jmp 0x258dd
movq -0xa0(%rbp), %rdi
leaq 0x18005(%rip), %rsi     # 0x3d307
callq 0x8ae0
movb %al, -0xdd(%rbp)
jmp 0x2530f
movb -0xdd(%rbp), %al
testb $0x1, %al
jne 0x2531e
jmp 0x253ee
movq -0xc0(%rbp), %rdi
callq 0x2e040
movq %rax, %rdi
callq 0x3be40
movq %rax, -0xe8(%rbp)
jmp 0x2533b
movq -0xa8(%rbp), %rdi
movq -0xe8(%rbp), %rax
movq %rax, -0x58(%rbp)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xec(%rbp)
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl $0x1, %esi
callq 0x11fc0
movq %rax, %rdi
callq 0xb9d0
movq %rax, %rcx
movl -0xec(%rbp), %eax
cmpl %ecx, %eax
jl 0x253a8
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
movq -0xa8(%rbp), %rdi
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movslq -0x54(%rbp), %rsi
callq 0x11fc0
movq %rax, %rdi
movl -0x58(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x2e0b0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x2e0d0
jmp 0x258db
movq -0xa0(%rbp), %rdi
leaq 0x17f0e(%rip), %rsi     # 0x3d30a
callq 0x8ae0
movb %al, -0xed(%rbp)
jmp 0x25409
movb -0xed(%rbp), %al
testb $0x1, %al
jne 0x25418
jmp 0x254ad
movq -0xc0(%rbp), %rdi
callq 0x2e040
movq %rax, %rdi
callq 0x3be40
movq %rax, -0xf8(%rbp)
jmp 0x25435
movq -0xf8(%rbp), %rax
movq %rax, -0x60(%rbp)
movl -0x60(%rbp), %eax
subl $0x1, %eax
cmpl $0x0, %eax
jge 0x25467
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
movq -0xa8(%rbp), %rdi
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movslq -0x5c(%rbp), %rsi
callq 0x11fc0
movq %rax, %rdi
movl -0x60(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x2e0b0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x2e0d0
jmp 0x258d9
movq -0xa0(%rbp), %rdi
leaq 0x17e52(%rip), %rsi     # 0x3d30d
callq 0x8ae0
movb %al, -0xf9(%rbp)
jmp 0x254c8
movb -0xf9(%rbp), %al
testb $0x1, %al
jne 0x254d7
jmp 0x255b7
movq -0xc0(%rbp), %rdi
callq 0x2e040
movq %rax, %rdi
callq 0x3be40
movq %rax, -0x108(%rbp)
jmp 0x254f4
movq -0xa8(%rbp), %rdi
movq -0x108(%rbp), %rax
movq %rax, -0x68(%rbp)
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10c(%rbp)
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl $0x1, %esi
callq 0x11fc0
movq %rax, %rdi
callq 0xb9d0
movq %rax, %rcx
movl -0x10c(%rbp), %eax
cmpl %ecx, %eax
jge 0x25550
movl -0x64(%rbp), %eax
subl $0x1, %eax
cmpl $0x0, %eax
jge 0x2556c
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
movq -0xa8(%rbp), %rdi
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl -0x64(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11fc0
movq %rax, %rdi
movl -0x68(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x2e0b0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x2e0d0
jmp 0x258d7
movq -0xa0(%rbp), %rdi
leaq 0x17d4b(%rip), %rsi     # 0x3d310
callq 0x8ae0
movb %al, -0x10d(%rbp)
jmp 0x255d2
movb -0x10d(%rbp), %al
testb $0x1, %al
jne 0x255e1
jmp 0x25686
movq -0xc0(%rbp), %rdi
callq 0x2e040
movq %rax, %rdi
callq 0x3be40
movq %rax, -0x118(%rbp)
jmp 0x255fe
movq -0x118(%rbp), %rax
movq %rax, -0x70(%rbp)
movl -0x70(%rbp), %eax
subl $0x1, %eax
cmpl $0x0, %eax
jl 0x2561f
movl -0x6c(%rbp), %eax
subl $0x1, %eax
cmpl $0x0, %eax
jge 0x2563b
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
movq -0xa8(%rbp), %rdi
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl -0x6c(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11fc0
movq %rax, %rdi
movl -0x70(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x2e0b0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x2e0d0
jmp 0x258d5
movq -0xa0(%rbp), %rdi
leaq 0x17c7f(%rip), %rsi     # 0x3d313
callq 0x8ae0
movb %al, -0x119(%rbp)
jmp 0x256a1
movb -0x119(%rbp), %al
testb $0x1, %al
jne 0x256b0
jmp 0x257be
movq -0xc0(%rbp), %rdi
callq 0x2e040
movq %rax, %rdi
callq 0x3be40
movq %rax, -0x128(%rbp)
jmp 0x256cd
movq -0xa8(%rbp), %rdi
movq -0x128(%rbp), %rax
movq %rax, -0x78(%rbp)
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x12c(%rbp)
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl $0x1, %esi
callq 0x11fc0
movq %rax, %rdi
callq 0xb9d0
movq %rax, %rcx
movl -0x12c(%rbp), %eax
cmpl %ecx, %eax
jge 0x25757
movq -0xa8(%rbp), %rdi
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x130(%rbp)
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
callq 0xb360
movq %rax, %rcx
movl -0x130(%rbp), %eax
cmpl %ecx, %eax
jl 0x25773
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
movq -0xa8(%rbp), %rdi
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl -0x74(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x11fc0
movq %rax, %rdi
movl -0x78(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x2e0b0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x2e0d0
jmp 0x258d3
movq -0xa0(%rbp), %rdi
leaq 0x17b4a(%rip), %rsi     # 0x3d316
callq 0x8ae0
movb %al, -0x131(%rbp)
jmp 0x257d9
movb -0x131(%rbp), %al
testb $0x1, %al
jne 0x257e8
jmp 0x258b8
movq -0xc0(%rbp), %rdi
callq 0x2e040
movq %rax, %rdi
callq 0x3be40
movq %rax, -0x140(%rbp)
jmp 0x25805
movq -0x140(%rbp), %rax
movq %rax, -0x80(%rbp)
movl -0x80(%rbp), %eax
subl $0x1, %eax
cmpl $0x0, %eax
jl 0x25854
movq -0xa8(%rbp), %rdi
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x144(%rbp)
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
callq 0xb360
movq %rax, %rcx
movl -0x144(%rbp), %eax
cmpl %ecx, %eax
jl 0x25870
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
movq -0xa8(%rbp), %rdi
movl 0x108(%rdi), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x11e20
movq %rax, %rdi
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x11fc0
movq %rax, %rdi
movl -0x80(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x2e0b0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x2e0d0
jmp 0x258d1
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
jmp 0x25940
jmp 0x258d3
jmp 0x258d5
jmp 0x258d7
jmp 0x258d9
jmp 0x258db
jmp 0x258dd
jmp 0x258df
leaq -0x90(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x2e100
leaq -0x90(%rbp), %rdi
callq 0x1ed00
testb $0x1, %al
jne 0x25901
jmp 0x2591d
movq -0xb8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x1de70
movl $0x1, -0x48(%rbp)
jmp 0x25934
movq -0xb8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2dc90
movl $0x1, -0x48(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x99e0
leaq -0x30(%rbp), %rdi
callq 0xa1d0
movq -0xb0(%rbp), %rax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0x6540
nopw %cs:(%rax,%rax)