<< Click to Display Table of Contents >> Cheney.php |
![]() ![]() ![]() |
<?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(0, 0);
}
}
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(999, 99);
$Grande = new Carta(0, 0);
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(0, 0);
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;
}
}