// File: fredericmarchand[P]TexasHoldem/main.cpp
// Function: main
int main(int argc, char** argv) 
{
    bool AI_game = true;
    Game *game = new Game(2);
    Player *me = game->getPlayers()[0];
    me->setDealer(true);

    if (argc > 1)
    {
        AI_game = false;
        me->setAI(false);
    }

    while (1)
    {
        //Check if the game is over
        if (game->getPlayers()[0]->getChipCount() == 0 || game->getPlayers()[1]->getChipCount() == 0)
        {
            break;
        }

        game->resetDeck();
        game->clearPlayerStates();
        game->rotateDealerChip();

        printLabel("Starting new game");
        cout << "Small Blind: $" << SMALL_BLIND << endl;
        cout << "Big Blind:   $" << BIG_BLIND << endl;
        cout << "Dealer: Player " << game->getPlayerIndex(game->getDealer()) << endl;
        game->shuffleDeck(0);

        //Blinds
        game->getSmallBlindPlayer()->bet(SMALL_BLIND);
        game->getBigBlindPlayer()->bet(BIG_BLIND);

        game->distributeCards();
        me->printHand();

        if (game->playRound(me, true) == true)
            goto end;

        //Finish blinds round
        game->printPot();
        
        //Flop
        printLabel("Flop");
        game->flipFlop(VERBOSE);

        //Round of betting
        if (game->playRound(me, false))
            goto end;

        game->printPot();

        //Turn
        printLabel("Turn");
        game->flipTurn(VERBOSE);

        //Round of betting
        if (game->playRound(me, false))
            goto end;

        game->printPot();

        //River
        printLabel("River");
        game->flipRiver(VERBOSE);

        //Final round of betting
        game->playRound(me, false);

        game->printPot();

end:
        //Check Results and give pot to winner
        cout << endl;
        int winnerIndex = game->determineWinner();
        if (winnerIndex == 0)
        {
            game->getPlayers()[0]->incHandsWon();
        }
        else if (winnerIndex == 1)
        {
            game->getPlayers()[1]->incHandsWon();
        }

        for (int i = 0; i < game->getPlayerCount(); ++i)
        {
            cout << "Player " << i << " has won " << game->getPlayers()[i]->getHandsWon() << " games" << endl;
        }
        
        cin.ignore();
        //break;
    }

    //Print winner
    cout << "The winner is: " << (game->getPlayers()[0]->getChipCount() == 0 ? "Player 1" : "Player 0") << endl;

    delete game;

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb $0x1, -0x11(%rbp)
movl $0x1e0, %edi            # imm = 0x1E0
callq 0x2190
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe8(%rbp)
movl $0x2, %esi
callq 0x4640
jmp 0x9f70
movq -0xe8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4a00
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
movl $0x1, %esi
callq 0x3320
cmpl $0x1, -0x8(%rbp)
jle 0x9fd2
movb $0x0, -0x11(%rbp)
movq -0x38(%rbp), %rdi
xorl %esi, %esi
callq 0x3300
jmp 0x9fd2
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
movl $0x1e0, %esi            # imm = 0x1E0
callq 0x21a0
jmp 0xa5b9
jmp 0x9fd4
movq -0x20(%rbp), %rdi
callq 0x4a00
movq (%rax), %rdi
callq 0x3250
cmpl $0x0, %eax
je 0xa001
movq -0x20(%rbp), %rdi
callq 0x4a00
movq 0x8(%rax), %rdi
callq 0x3250
cmpl $0x0, %eax
jne 0xa006
jmp 0xa50e
movq -0x20(%rbp), %rdi
callq 0x47c0
movq -0x20(%rbp), %rdi
callq 0x6390
movq -0x20(%rbp), %rdi
callq 0x4c10
leaq -0x59(%rbp), %rdi
movq %rdi, -0xf0(%rbp)
callq 0x22b0
movq -0xf0(%rbp), %rdx
leaq 0x1193(%rip), %rsi      # 0xb1d2
leaq -0x58(%rbp), %rdi
callq 0x2da0
jmp 0xa04a
leaq -0x58(%rbp), %rdi
callq 0x9e50
jmp 0xa055
leaq -0x58(%rbp), %rdi
callq 0x20c0
leaq -0x59(%rbp), %rdi
callq 0x21d0
movq 0x5f62(%rip), %rdi      # 0xffd0
leaq 0x116f(%rip), %rsi      # 0xb1e4
callq 0x2180
movq %rax, %rdi
movl $0x32, %esi
callq 0x2290
movq %rax, %rdi
movq 0x5f2f(%rip), %rsi      # 0xffc0
callq 0x21b0
movq 0x5f33(%rip), %rdi      # 0xffd0
leaq 0x114f(%rip), %rsi      # 0xb1f3
callq 0x2180
movq %rax, %rdi
movl $0x64, %esi
callq 0x2290
movq %rax, %rdi
movq 0x5f00(%rip), %rsi      # 0xffc0
callq 0x21b0
movq 0x5f04(%rip), %rdi      # 0xffd0
leaq 0x112f(%rip), %rsi      # 0xb202
callq 0x2180
movq %rax, -0xf8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4cd0
movq -0x100(%rbp), %rdi
movq %rax, %rsi
callq 0x5000
movq -0xf8(%rbp), %rdi
movl %eax, %esi
callq 0x2290
movq %rax, %rdi
movq 0x5ea6(%rip), %rsi      # 0xffc0
callq 0x21b0
movq -0x20(%rbp), %rdi
xorl %esi, %esi
callq 0x5540
movq -0x20(%rbp), %rdi
callq 0x4e10
movq %rax, %rdi
movl $0x32, %esi
callq 0x36d0
movq -0x20(%rbp), %rdi
callq 0x4d50
movq %rax, %rdi
movl $0x64, %esi
callq 0x36d0
movq -0x20(%rbp), %rdi
callq 0x5480
movq -0x38(%rbp), %rdi
callq 0x3340
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl $0x1, %edx
callq 0x5b10
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xa1ba
jmp 0xa3ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0xa1ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x20c0
leaq -0x59(%rbp), %rdi
callq 0x21d0
jmp 0xa5b9
movq -0x20(%rbp), %rdi
callq 0x5a20
leaq -0x81(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x22b0
movq -0x108(%rbp), %rdx
leaq 0x102e(%rip), %rsi      # 0xb212
leaq -0x80(%rbp), %rdi
callq 0x2da0
jmp 0xa1ef
leaq -0x80(%rbp), %rdi
callq 0x9e50
jmp 0xa1fa
leaq -0x80(%rbp), %rdi
callq 0x20c0
leaq -0x81(%rbp), %rdi
callq 0x21d0
movq -0x20(%rbp), %rdi
movl $0x1, %esi
callq 0x5060
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x5b10
testb $0x1, %al
jne 0xa232
jmp 0xa26b
jmp 0xa3ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0xa25a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x20c0
leaq -0x81(%rbp), %rdi
callq 0x21d0
jmp 0xa5b9
movq -0x20(%rbp), %rdi
callq 0x5a20
leaq -0xa9(%rbp), %rdi
movq %rdi, -0x110(%rbp)
callq 0x22b0
movq -0x110(%rbp), %rdx
leaq 0xf82(%rip), %rsi       # 0xb217
leaq -0xa8(%rbp), %rdi
callq 0x2da0
jmp 0xa2a3
leaq -0xa8(%rbp), %rdi
callq 0x9e50
jmp 0xa2b1
leaq -0xa8(%rbp), %rdi
callq 0x20c0
leaq -0xa9(%rbp), %rdi
callq 0x21d0
movq -0x20(%rbp), %rdi
movl $0x1, %esi
callq 0x53e0
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x5b10
testb $0x1, %al
jne 0xa2ec
jmp 0xa328
jmp 0xa3ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0xa317
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x20c0
leaq -0xa9(%rbp), %rdi
callq 0x21d0
jmp 0xa5b9
movq -0x20(%rbp), %rdi
callq 0x5a20
leaq -0xd1(%rbp), %rdi
movq %rdi, -0x118(%rbp)
callq 0x22b0
movq -0x118(%rbp), %rdx
leaq 0xeca(%rip), %rsi       # 0xb21c
leaq -0xd0(%rbp), %rdi
callq 0x2da0
jmp 0xa360
leaq -0xd0(%rbp), %rdi
callq 0x9e50
jmp 0xa36e
leaq -0xd0(%rbp), %rdi
callq 0x20c0
leaq -0xd1(%rbp), %rdi
callq 0x21d0
movq -0x20(%rbp), %rdi
movl $0x1, %esi
callq 0x5430
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x5b10
movq -0x20(%rbp), %rdi
callq 0x5a20
movq 0x5c1d(%rip), %rdi      # 0xffd0
movq 0x5c06(%rip), %rsi      # 0xffc0
callq 0x21b0
movq -0x20(%rbp), %rdi
callq 0x55d0
movl %eax, -0xd8(%rbp)
cmpl $0x0, -0xd8(%rbp)
jne 0xa421
movq -0x20(%rbp), %rdi
callq 0x4a00
movq (%rax), %rdi
callq 0x4600
jmp 0xa43e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0xa410
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x20c0
leaq -0xd1(%rbp), %rdi
callq 0x21d0
jmp 0xa5b9
cmpl $0x1, -0xd8(%rbp)
jne 0xa43c
movq -0x20(%rbp), %rdi
callq 0x4a00
movq 0x8(%rax), %rdi
callq 0x4600
jmp 0xa43e
movl $0x0, -0xdc(%rbp)
movl -0xdc(%rbp), %eax
movl %eax, -0x11c(%rbp)
movq -0x20(%rbp), %rdi
callq 0x49e0
movl %eax, %ecx
movl -0x11c(%rbp), %eax
cmpl %ecx, %eax
jge 0xa4fd
movq 0x5b5c(%rip), %rdi      # 0xffd0
leaq 0xd8f(%rip), %rsi       # 0xb20a
callq 0x2180
movq %rax, %rdi
movl -0xdc(%rbp), %esi
callq 0x2290
movq %rax, %rdi
leaq 0xd8a(%rip), %rsi       # 0xb222
callq 0x2180
movq %rax, -0x128(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4a00
movslq -0xdc(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x4620
movq -0x128(%rbp), %rdi
movl %eax, %esi
callq 0x2290
movq %rax, %rdi
leaq 0xd57(%rip), %rsi       # 0xb22c
callq 0x2180
movq %rax, %rdi
movq 0x5adc(%rip), %rsi      # 0xffc0
callq 0x21b0
movl -0xdc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xdc(%rbp)
jmp 0xa448
movq 0x5adc(%rip), %rdi      # 0xffe0
callq 0x22d0
jmp 0x9fd4
movq 0x5abb(%rip), %rdi      # 0xffd0
leaq 0xd17(%rip), %rsi       # 0xb233
callq 0x2180
movq %rax, -0x130(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4a00
movq (%rax), %rdi
callq 0x3250
cmpl $0x0, %eax
jne 0xa54e
leaq 0xcfe(%rip), %rax       # 0xb243
movq %rax, -0x138(%rbp)
jmp 0xa55e
leaq 0xcf7(%rip), %rax       # 0xb24c
movq %rax, -0x138(%rbp)
jmp 0xa55e
movq -0x130(%rbp), %rdi
movq -0x138(%rbp), %rsi
callq 0x2180
movq %rax, %rdi
movq 0x5a45(%rip), %rsi      # 0xffc0
callq 0x21b0
movq -0x20(%rbp), %rax
movq %rax, -0x140(%rbp)
cmpq $0x0, %rax
je 0xa5ae
movq -0x140(%rbp), %rdi
callq 0x4b20
movq -0x140(%rbp), %rdi
movl $0x1e0, %esi            # imm = 0x1E0
callq 0x21a0
xorl %eax, %eax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
movq -0x28(%rbp), %rdi
callq 0x22a0