Cheney.php

<< Click to Display Table of Contents >>

Navigation:  Outros > Projeto Cheney >

Cheney.php

Previous pageReturn to chapter overviewNext page

<?php
 
class Cheney {
 
    private $baralho;
    public $PrimeiraCarta;
    public $QuintaCarta;
 
    const PMG = 1;
    const PGM = 2;
    const MPG = 3;
    const MGP = 4;
    const GPM = 5;
    const GMP = 6;
 
    public function __construct() {
        $this->baralho = new Baralho();
    }
 
    private function getDif(): int {
        // se a primeira carta for maior que a ultima e a diferença for até 6, OK
        if ($this->PrimeiraCarta->valor > $this->QuintaCarta->valor) {
            return Carta::K - $this->PrimeiraCarta->valor + $this->QuintaCarta->valor;
        } else {
            return $this->QuintaCarta->valor - $this->PrimeiraCarta->valor;
        }
    }
 
    public function getCincoCartas(): array {
        $this->baralho->Misturar();
 
        $ret = [];
        for ($i = 0$i < 5$i++) {
            array_push($ret$this->baralho->GetCarta($i));
        }
 
        return $ret;
    }
 
    private function separarPrimeiraEQuintaCarta($lista): void {
 
        // cria uma matriz e adiciona só os naipes nela
        $lista = $this->getCincoCartas();
 
        $arr = [];
        foreach ($lista as $carta) {
            array_push($arr$carta->naipe);
        }
 
        // agrupa e conta
        $conta = array_count_values($arr);
 
        // ordena pelo que tem mais em cima
        arsort($conta);
 
        // retorna o primeiro naipe da contagem (tem mais)
        $naipeQueRepete = array_key_first($conta);
 
        // primeio passo, a carta deve ter mesmo naipe da quinta
        unset($this->PrimeiraCarta);
        unset($this->QuintaCarta);
 
        // primeiro vamos localizar a quinta carta e a primeira
        foreach ($lista as $c) {
 
            if ($c->naipe != $naipeQueRepete) {
                continue;
            }
 
            // achou naipe igual! entao primeiro colocamos a quinta carta
            if (!isset($this->QuintaCarta)) {
                $this->QuintaCarta = $c;
            } else {
                // vamos colocar a primeira carta e sair do looping (pode ter 3, 4 ou 5 naipes iguais)
                $this->PrimeiraCarta = $c;
                break;
            }
        }
    }
 
    public function GetDistanciaEntreCartas($primeira$segunda$terceira): int {
        // PMG   
        if ($primeira->IsMenorQue($segunda) && $segunda->IsMenorQue($terceira) && $primeira->IsMenorQue($terceira)) {
            return 1;
        }
 
        // PGM
        if ($primeira->IsMenorQue($segunda) && $segunda->IsMaiorQue($terceira) && $primeira->IsMenorQue($terceira)) {
            return 2;
        }
 
        // MPG
        if ($primeira->IsMaiorQue($segunda) && $segunda->IsMenorQue($terceira) && $primeira->IsMenorQue($terceira)) {
            return 3;
        }
 
        // MGP
        if ($primeira->IsMenorQue($segunda) && $segunda->IsMaiorQue($terceira) && $primeira->IsMaiorQue($terceira)) {
            return 4;
        }
 
        // GPM
        if ($primeira->IsMaiorQue($segunda) && $segunda->IsMenorQue($terceira) && $primeira->IsMaiorQue($terceira)) {
            return 5;
        }
 
        // GMP
        //if ($primeira->IsMaiorQue($segunda) && $segunda->IsMaiorQue($terceira) && $primeira->IsMaiorQue($terceira))
        return 6;
    }
 
    public function TenteAdivinhar($listaUser): Carta {
 
        $this->PrimeiraCarta = $listaUser[0];
        $SegundaCarta = $listaUser[1];
        $TerceiraCarta = $listaUser[2];
        $QuartaCarta = $listaUser[3];
        unset($this->QuintaCarta); // computador não sabe qual é
        // vamos usar a 2, 3, 4 para descobrir quantidade a somar
        $distancia = $this->GetDistanciaEntreCartas($SegundaCarta$TerceiraCarta$QuartaCarta);
 
        $valor = $this->PrimeiraCarta->valor + $distancia;
        if ($valor > Carta::K) {
            $valor -= Carta::K;
        }
 
        // com distancia localizamos a quinta carta
        foreach ($listaUser as $c) {
            if ($c->Igual($this->PrimeiraCarta)) {
                continue;
            }
 
            if ($c->naipe == $this->PrimeiraCarta->naipe && $c->valor == $valor) {
                $this->QuintaCarta = $c;
                break;
            }
        }
 
        if (isset($this->QuintaCarta)) {
            return $this->QuintaCarta;
        } else {
            return new Carta(00);
        }
    }
 
    public function MontarParaAcertar(): array {
 
        $lista = $this->GetCincoCartas();
        $this->SepararPrimeiraEQuintaCarta($lista);
 
        // a diferença será no máximo 6
        $dif = $this->GetDif();
 
        if ($dif > 6) {
            // faz um swap (inverte primeira e quinta)
            $terceira = new Carta($this->PrimeiraCarta->naipe$this->PrimeiraCarta->valor);
            $this->PrimeiraCarta = $this->QuintaCarta;
            $this->QuintaCarta = $terceira;
 
            // atualiza diferenca
            $dif = $this->GetDif();
        }
 
        // a diferenca é que vai determinar a ordem das últimas 3
        // vamos pegar a Pequena, Media e Grande 
        $Pequena = new Carta(99999);
        $Grande = new Carta(00);
 
        foreach ($lista as $c) {
            // primeira e quinta ignora
            if ($c->Igual($this->PrimeiraCarta) || $c->Igual($this->QuintaCarta)) {
                continue;
            }
 
            if ($c->valor < $Pequena->valor) {
                $Pequena = $c;
            }
 
            if ($c->valor == $Pequena->valor && $c->naipe < $Pequena->naipe) {
                $Pequena = $c;
            }
 
            if ($c->valor > $Grande->valor) {
                $Grande = $c;
            }
 
            if ($c->valor == $Grande->valor && $c->naipe > $Grande->naipe) {
                $Grande = $c;
            }
        }
 
        // a média é a que sobrou
        $Media = new Carta(00);
 
        foreach ($lista as $c) {
            // vamos achar a carta que não é nem a primeira, quinta, menor e maior
            if ($c->Igual($this->PrimeiraCarta) || $c->Igual($this->QuintaCarta) || $c->Igual($Pequena) || $c->Igual($Grande)) {
                continue;
            }
 
            $Media = $c;
            break;
        }
 
        // saída final
        $retorno = [];
        array_push($retorno$this->PrimeiraCarta);
 
        switch ($dif) {
            case Cheney::PMG:
                array_push($retorno$Pequena);
                array_push($retorno$Media);
                array_push($retorno$Grande);
                break;
            case Cheney::PGM:
                array_push($retorno$Pequena);
                array_push($retorno$Grande);
                array_push($retorno$Media);
                break;
            case Cheney::MPG:
                array_push($retorno$Media);
                array_push($retorno$Pequena);
                array_push($retorno$Grande);
                break;
            case Cheney::MGP:
                array_push($retorno$Media);
                array_push($retorno$Grande);
                array_push($retorno$Pequena);
                break;
            case Cheney::GPM:
                array_push($retorno$Grande);
                array_push($retorno$Pequena);
                array_push($retorno$Media);
                break;
            case Cheney::GMP:
                array_push($retorno$Grande);
                array_push($retorno$Media);
                array_push($retorno$Pequena);
                break;
        }
        array_push($retorno$this->QuintaCarta);
 
        return $retorno;
    }
 
}