WinnerFinder::findAWinner()   C
last analyzed

Complexity

Conditions 7
Paths 14

Size

Total Lines 32
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 32
rs 6.7272
cc 7
eloc 15
nc 14
nop 1
1
<?php
2
3
namespace Bourdeau\Bundle\HandEvaluatorBundle\HandEvaluator;
4
5
/**
6
 * Hand Evaluator for Poker.
7
 *
8
 * @author Pierre-Henri Bourdeau <[email protected]>
9
 */
10
class WinnerFinder
11
{
12
    private $handFinder;
13
14
    /**
15
     * Constructor.
16
     *
17
     * @param HandFinder $handFinder
18
     */
19
    public function __construct(HandFinder $handFinder)
20
    {
21
        $this->handFinder = $handFinder;
22
    }
23
24
    /**
25
     * Get a winner.
26
     *
27
     * @param array $players A simple array with key as Player Name and value
28
     *                       as the cards.
29
     *
30
     * @return array
31
     */
32
    public function findAWinner(array $players)
33
    {
34
        $playerRanks = [
35
            'winners' => [],
36
            'other_players' => [],
37
        ];
38
39
        foreach ($players as $playerName => $cards) {
40
            //@todo should one care about the given card? I remove them for now
41
            $players[$playerName] = $this->handFinder->findhand($cards);
42
43
            // We do not have a winner yet
44
            if (count($playerRanks['winners']) == 0) {
45
                $playerRanks['winners'] = [$playerName => $players[$playerName]];
46
            }
47
48
            // If we already have a winner it must be challenged with other players
49
            if (count($playerRanks['winners']) > 0 && key($playerRanks['winners']) !== $playerName) {
50
                if ($newWinner = $this->challengeTheWinner($playerRanks['winners'], [$playerName => $players[$playerName]])) {
51
                    $playerRanks['winners'] = $newWinner;
52
                }
53
            }
54
        }
55
56
        foreach ($playerRanks['winners'] as $winner => $data) {
57
            unset($players[$winner]);
58
        }
59
60
        $playerRanks['other_players'] = $players;
61
62
        return $playerRanks;
63
    }
64
65
    /**
66
     * Return the new winner if it beats the current one.
67
     *
68
     * @param array $currentWinners
69
     * @param array $challenger
70
     *
71
     * @return array|bool
72
     */
73
    private function challengeTheWinner(array $currentWinners, array $challenger)
74
    {
75
        $currentChallenger = current($challenger);
76
77
        foreach ($currentWinners as $currentWinnerName => $currentWinner) {
78
            // Current player hand rank is higher than current winner
79
            if ($currentWinner['hand_rank'] < $currentChallenger['hand_rank']) {
80
                return $challenger;
81
            }
82
83
            $equalHandRank = $currentWinner['hand_rank'] == $currentChallenger['hand_rank'];
84
            
85
            // Current player hand rank is equal to current winner but it's card ranks is higher
86
            if ($equalHandRank && $currentWinner['card_rank'] < $currentChallenger['card_rank']) {
87
                return $challenger;
88
            }
89
90
            // Players are equaly ranked, it's a dead heat. We return both players
91
            if ($equalHandRank && $currentWinner['card_rank'] == $currentChallenger['card_rank']) {
92
                return array_merge($currentWinners, $challenger);
93
            }
94
        }
95
96
        return false;
97
    }
98
}
99