xploit Posted February 23, 2013 at 05:25 PM Report #496753 Posted February 23, 2013 at 05:25 PM Estou a desenvolver um jogo de poker, mais precisamente Poker Texas Hold'n, mas estou com dificuldades na parte principal do código, que é fazer a correspondência das mãos que saiem e definir assim qual a mão vencedora. Actualmente o código abaixo apresentado, já cria um baralho de cartas, com os ternos/cartas, e já faz a randomização das cartas, agora falta a parte lógica, como detectar as mãos e atribuir-lhes os valores.. poker.php <?php header('Content-Type: text/html; charset=utf-8'); /* ID's das cartas Ternos: -> Ouros = O -> Paus = P -> Corações = C -> Espadas = E Cartas de: -> Dois = 2 -> Três = 3 -> Quatro = 4 -> Cinco = 5 -> Seis = 6 -> Sete = 7 -> Oito = 8 -> Nove = 9 -> Valete = V -> Dama = D -> Rei = R -> Às = A Exemplo de descodificação de ids: ----------------------------- Output: array( "T"=>"O" , "C"=>"2" ) Igual a: Dois de Outros ----------------------------- */ function decode_type_name($type) { global $ternos; global $ternos_pt_lang; return (!$ternos_pt_lang[$type] ? "!invalid" : $ternos_pt_lang[$type]); } function decode_card_name($card) { global $cartas; global $cartas_pt_lang; return (!$cartas_pt_lang[$card] ? "!invalid" : $cartas_pt_lang[$card]); } $ternos = array ( "E", "C", "P", "O" ); $cartas = array ( "2", "3", "4", "5", "6", "7", "8", "9", "10", "V", "D", "R", "A" ); $ternos_pt_lang = array ( "E" => "Espadas", "C" => "Corações", "P" => "Paus", "O" => "Ouros", ); $cartas_pt_lang = array ( "2" => "Dois", "3" => "Três", "4" => "Quatro", "5" => "Cinco", "6" => "Seis", "7" => "Sete", "8" => "Oito", "9" => "Nove", "10"=> "Dez", "V" => "Valete", "D" => "Dama", "R" => "Rei", "A" => "Às", ); $baralho = array(); foreach ($cartas as $carta) { foreach ($ternos as $terno) { /* * T = tipo de carta (ex:E,C,O) * C = carta (ex:1,2,3,4,5,etc) */ $baralho[] = array ( "T"=>$terno, "C"=>$carta ); } } shuffle($baralho);// baralha todo o baralho $n=1; foreach($baralho as $dados) { $carta = decode_card_name($dados["C"]); // Descodifica o tipo de carta, ex: (Ás, Valete, etc) $terno = decode_type_name($dados["T"]); // Descodifica o tipo de terno, ex: (Ouros, Paus, Corações,etc) echo $n." - ".$carta."->".$terno."<br>"; $n++; } ?>
yoda Posted February 23, 2013 at 05:39 PM Report #496755 Posted February 23, 2013 at 05:39 PM O que entendes por "atribuir valores"? before you post, what have you tried? - http://filipematias.info sense, purpose, direction
xploit Posted February 23, 2013 at 06:02 PM Author Report #496758 Posted February 23, 2013 at 06:02 PM Atribuir valores, secalhar não foi a melhor frase para descrever o que pretendo, básicamente o que pretendo ,é fazer um sistema, baseado neste que comecei, em que seja possível detectar as mãos, ou seja detectar quando acontece um Royal Flush, um Straight, enfim todas as possiblidades que podem acontecer no Poker Texas, e após detectá-las, declarar o vencedor com a melhor mão. Isto requer um trabalho de lógica, só que eu estou "bloqueado" em como irei fazer esse processo todo..
yoda Posted February 23, 2013 at 07:25 PM Report #496766 Posted February 23, 2013 at 07:25 PM (edited) Terás de analisar todas as situações possíveis, provavelmente a tentativa e erro é o mais fácil para chegar lá. Precisas também definir a ordem das mãos, para determinar que mão é maior. Começa de cima (mão maior possível) e vai descartando hipóteses. Não tem nada de complicado. Edited February 23, 2013 at 07:26 PM by yoda before you post, what have you tried? - http://filipematias.info sense, purpose, direction
xploit Posted February 23, 2013 at 07:54 PM Author Report #496774 Posted February 23, 2013 at 07:54 PM Já é um bom começo, portanto começar pela mão maior, mas podes me dar um exemplo prático (Código) de como isso puderia ser feito? não estou a pedir o código completo obviamente, mas se me pudesses dar um exemplo prático de como seria esse processamento das informações do jogo para o próprio script conseguir decidir quem tem a maior mão, porque no poker existe a possiblidade de 2 jogares terem mãos de potência igual, as cartas para além das mãos têm valor, ou seja o 7 é maio que 6, enfim, são variáveis que não são propriamente líneares e é ai que me faz confusão
yoda Posted February 23, 2013 at 08:28 PM Report #496779 Posted February 23, 2013 at 08:28 PM (edited) Mais uma vez, é por tentativa e erro. Um jogador pode até ter mais que uma mão (por exemplo full house e four of a kind, isto para o motor de jogo claro), mas aquilo que interessa é identificar a maior mão do jogador. Portanto, podes começar por identificar a maior mão de cada jogador, de seguida comparas as mãos. Se existirem 2 ou mais jogadores com mãos idênticas, verificas se algum deles tem uma carta maior que desempate, ou, em caso de mãos como é o exemplo de pares / 2 pares / three of a kind, verificar qual delas é maior. Cada mão tem regras específicas, não perdes nada em ter uma função para tratar cada uma delas, fora o motor principal. Assim de cabeça, acho que podes identificar as mãos sob estas regras : - tipo de mão (straight, flush, pair, etc); - relevância da mão (maior ou menor); - cartas do jogador (para vias de desempate); À medida que vais validando cada mão do jogador, vais guardando o resultado num array, e cada vez que validas outro comparas nesse array se a mão desse jogador é maior que alguma das mãos dos outros já validadas. Edited February 23, 2013 at 08:31 PM by yoda before you post, what have you tried? - http://filipematias.info sense, purpose, direction
xploit Posted March 2, 2013 at 01:54 AM Author Report #497599 Posted March 2, 2013 at 01:54 AM Estive a estruturar o código, e já está mais próximo, neste momento o script já faz um baralho, dá as cartas aos jogadores, e aparece as cartas do board, o problema é o tal, como vou agora descobrir as mãos de cada jogar baseado no código que escrevi? Eu fiz upload dos arquivos, podem fazer o download aqui: http://www.filedropper.com/poker-engine Eu queria colocar isto em anexo ao post, mas não sei se é possível Obrigado
yoda Posted March 2, 2013 at 02:00 AM Report #497600 Posted March 2, 2013 at 02:00 AM Deves guardar a mão de cada um nalgum sítio seguro (base de dados por exemplo) enquanto o jogo decorre. before you post, what have you tried? - http://filipematias.info sense, purpose, direction
lordfokas Posted March 2, 2013 at 05:02 AM Report #497602 Posted March 2, 2013 at 05:02 AM Se tratares cada carta como um par de valores (naipe e numero), em que os numeros vão por exemplo de 2 a 14, podes juntar as cartas de cada jogador num array temporario, e passar uma cadeia if-else a verificar as condições, da maior mão para a menor. exemplo: function is_royalflush($cartas, &$kickers){ # verificar se é royal flush # ... se sim, preencher $kickers com as cartas restantes, por ordem de valor decrescente # return bool, é royal flush? } # ... código aqui pelo meio. possivelmente estas funções sao declaradas noutros ficheiros. if(is_royalflush($cartas, $kickers)){ $mao = ROYAL_FLUSH; }else if(is_fullhouse($cartas, $kickers, $valor)){ # o mesmo que is_royalflush, mas preenche $valor com o valor das cartas envolvidas, para desempatar maos iguais. $mao = FULL_HOUSE; }else if(is_3_of_a_kind($cartas, $kickers, $valor)){ $mao = THREE_OF_A_KIND; } Sendo que as constantes se referem a ao valor da mão, em que neste caso ROYAL_FLUSH tem o valor maior. Se houver uma mão de grande valor, todas as mãos menores são ignoradas. Podes comparar directamente as mãos ($mao1 > $mao2) para ver qual é maior; Podes desempatar com o valor da mão, se houver algum para essa mão. Se não houver, podemos meter o valor a -1, só para não passar sem ser declarado... Finalmente, podes desempatar mãos iguais com valores iguais através dos kickers. Por exemplo, é possivel dois jogadores terem par de Reis, ou Às, neste caso tens de recorrer ao kicker. É uma questão de teres a logica toda alinhada. Nota que os kickers são passados como uma referência a um valor (&$var). (funciona +/- como um ponteiro, se o termo te for familiar) Do meu ponto de vista, é uma forma bastante simples de comparar mãos, com poucas variaveis e o uso de algumas funções simples. Quanto a guardar os dados do jogo, e tal como o yoda disse, uma base de dados é uma optima opção, senão a melhor, sobretudo se esse motor for lidar com um numero indefinido de jogos simultaneamente e em tempo real...
xploit Posted March 2, 2013 at 11:46 AM Author Report #497608 Posted March 2, 2013 at 11:46 AM Sim esta Classe que estou a desenvolver será para um jogo a correr online-multiplayer, terá uma base de dados claro, mas isso agora para mim é o menos importanto, agora estou focado apenas no motor do jogo e é ai que o meu raciocínio congela, não sei se já fizeram o download do arquivo que deixei ai para darem uma olhadela e para me darem a vossa opinião da estrutura do código, eu acho que está boa, mas pronto para quem não fez o download, eu deixo aqui somente a classe: poker.php <?php header('Content-Type: text/html; charset=utf-8'); class Poker { var $language = "pt";// personaliza a língua, pt, es, br, etc. var $ternos = array ( "E", // E = Espadas "C", // C = Corações "P", // P = Paus "O" // O = Ouros ); var $hands = array ( "royal-flush" => 9, "straight-flush" => 8, "four-of-a-kind" => 7, "full-house" => 6, "flush" => 5, "straight" => 4, "three-of-a-kind" => 3, "two-pair" => 2, "one-pair" => 1 ); var $cartas = array ( "2" => 0.2, // Carta de 2 "3" => 0.3, // Carta de 3 "4" => 0.4, // Carta de 4 "5" => 0.5, // Carta de 5 "6" => 0.6, // Carta de 6 "7" => 0.7, // Carta de 7 "8" => 0.8, // Carta de 8 "9" => 0.9, // Carta de 9 "10"=> 1.0, // Carta de 10 "V" => 1.5, // Carta de Valete "D" => 2.0, // Carta de Dama "R" => 2.5, // Carta de Rei "A" => 10 // Carta de Ás ); var $players = array(); // Onde vai ficar os dados dos jogadores var $dealer_board = array(); // Onde vai ficar as cartas do dealer var $baralho = array(); // Onde vai ficar guardado o baralho var $cached_baralhos = array(); // Onde vai ficar guardado o baralho inicial, depois do dealer e depois dos jogadores var $cartas_lang = array(); // variável com o nome das cartas var $ternos_lang = array(); // variável com o nome dos ternos var $hands_lang = array(); // variável com o nome das várias mãos function __construct($lang=null) { define("POKER_ENGINE","ON"); if(!$lang) $lang = $this->language; include("lang/".$lang.".php"); $this->cartas_lang = $cartas_lang; $this->ternos_lang = $ternos_lang; $this->hands_lang = $hands_lang ; $this->CriarBaralho(); } function CriarBaralho() { foreach ($this->cartas as $carta=>$carta_value) { foreach ($this->ternos as $terno) { /* * T = tipo de carta (ex:E,C,O) * C = carta (ex:1,2,3,4,5,etc) * P = valor da carta em números décimais (ex:1.0,0.5,etc) */ $this->baralho[] = array( "T"=>$terno, "C"=>$carta, "P"=>$carta_value ); } } shuffle($this->baralho); $this->cached_baralhos["first_deck"] = $this->baralho; $this->MakeDealerCards(); } function MakeDealerCards() { $cards=array( rand(0,10), rand(11,21), rand(22,35), rand(36,45), rand(46,51) ); shuffle($cards); foreach ($cards as $card_id){ $this->dealer_board[]=$this->baralho[$card_id]; unset($this->baralho[$card_id]); } $this->baralho=array_values($this->baralho); /* TEMPORÁRIO */ foreach($this->dealer_board as $dados) { $carta = $this->__DecodeCartaName($dados["C"]); // Descodifica o tipo de carta, ex: (Ás, Valete, etc) $terno = $this->__DecodeTernoName($dados["T"]); // Descodifica o tipo de terno, ex: (Ouros, Paus, Corações,etc) echo "<div style='float:left; margin-left:20px; text-align:center; font-size:11px;' > <img src='img/cards/".$dados["T"]."_".$dados["C"].".png' /> <br /> ".$carta."[".$terno."] - ".$dados["P"]." </div>"; $n++; } echo "<br clear='all' /><br /><br />"; /* TEMPORÁRIO */ $this->cached_baralhos["after_dealer_deck"]=$this->baralho; } function AssignPlayers($players_array) { if(!is_array($players_array)) die("PKCLASS_9782345H"); if( count($players_array)> 8 || count($players_array) < 2) die("PKCLASS_978UJK"); foreach($players_array as $player) { $cards = $this->__GetPlayerCards(); $total = ($cards[0]["P"] + $cards[1]["P"]); $this->players["$player"]["cards"] = $cards; $this->players["$player"]["hand"] = $this->__GetPlayerHand($cards); $this->players["$player"]["total"] = $total; /* TEMPORÁRIO */ echo " <div style='float:left; margin-left:40px;text-align:center; border:1px #666 solid; padding:10px;' > $player - ".$total." <br/><br/> <img src='img/cards/".$cards[0]["T"]."_".$cards[0]["C"].".png' width='40' align='left' /> <img src='img/cards/".$cards[1]["T"]."_".$cards[1]["C"].".png' width='40' align='left' /> <br clear='all' /><br/> | ".$this->players["$player"]["hand"]." |<br /> </div>"; } echo "<br clear='all' /><br clear='all' /><br clear='all' /><br clear='all' />"; /* TEMPORÁRIO */ $this->cached_baralhos["after_players_deck"]=$this->baralho; } /* TEMPORÁRIO */ /* function PrintBaralho() { $n=1; foreach($this->baralho as $dados) { $carta = $this->__DecodeCartaName($dados["C"]); // Descodifica o tipo de carta, ex: (Ás, Valete, etc) $terno = $this->__DecodeTernoName($dados["T"]); // Descodifica o tipo de terno, ex: (Ouros, Paus, Corações,etc) echo $n." - <img src='img/cards/".$dados["T"]."_".$dados["C"].".png' /><br />".$carta."[".$terno."] - ".$dados["P"]." valor.<br><br />"; $n++; } } /* TEMPORÁRIO */ function __DecodeTernoName($terno) { return (!$this->ternos_lang[$terno] ? "!invalid" : $this->ternos_lang[$terno]); } function __DecodeCartaName($card) { return (!$this->cartas_lang[$card] ? "!invalid" : $this->cartas_lang[$card]); } function __GetNumberPlayers() { if(!isset($this->players[0])) die("PKCLASS_34554K"); return count($this->players); } function __GetPlayerCards() { $baralho_do_jogo = $this->baralho; shuffle($baralho_do_jogo); // baralha as cartas $cards = array( $baralho_do_jogo[0] , $baralho_do_jogo[1] ); // Seleciona 2 cartas unset( $baralho_do_jogo[0] , $baralho_do_jogo[1] ); // Remove as duas cartas do baralho shuffle($baralho_do_jogo); // baralha novamente as cartas $this->baralho=array_values($baralho_do_jogo); // actualiza o baralho ordenando o seu INDEX return $cards ; } function __GetPlayerHand($hand) { $hand_name = null; if($hand_name = $this->__Hand_RoyalFlush($hand)) return $hand_name; if($hand_name = $this->__Hand_StraightFlush($hand)) return $hand_name; if($hand_name = $this->__Hand_FourOfaKind($hand)) return $hand_name; if($hand_name = $this->__Hand_FullHouse($hand)) return $hand_name; if($hand_name = $this->__Hand_Flush($hand)) return $hand_name; if($hand_name = $this->__Hand_Straight($hand)) return $hand_name; if($hand_name = $this->__Hand_ThreeOfaKind($hand)) return $hand_name; if($hand_name = $this->__Hand_TwoPair($hand)) return $hand_name; if($hand_name = $this->__Hand_OnePair($hand)) return $hand_name; return "nohand"; } function __Hand_RoyalFlush($hand) { $this->dealer_board; // as cartas do dealer /* * Agora como faço a comparação???? * */ } function __Hand_StraightFlush($hand) { } function __Hand_FourOfaKind($hand) { } function __Hand_FullHouse($hand) { } function __Hand_Flush($hand) { } function __Hand_Straight($hand) { } function __Hand_ThreeOfaKind($hand) { } function __Hand_TwoPair($hand) { } function __Hand_OnePair($hand) { } /* function __PrintBaralho() { foreach($this->baralho as $key=>$dados) { echo $key."<br />"; } } */ } $jogo_1= new Poker(); $players=array("jogador-1","jogador-2","jogador-3","jogador-4","jogador-5","jogador-6","jogador-7","jogador-8"); $jogo_1->AssignPlayers($players); //$jogo_1->PrintBaralho(); para isto funcionar bem, a classe, façam o download, que traz as imagens das cartas, e o ficheiro de língua PT.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now