Advertisement
Guest User

cardgame.php

a guest
Jan 25th, 2018
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.04 KB | None | 0 0
  1. <?php
  2.  
  3.     // Lazy poker (5 card)
  4.     // bet money (by default you get 500)
  5.     // password saves money
  6.     // data stored to cookie (?)
  7.     // lol none of the above happened
  8.     /*
  9.         Settings
  10.     */
  11.     define('NUM_CARDS',  5);
  12.     define('MAX_LOSSES', 3);
  13.     $cipher = 'LSAPOJKYMB';
  14.    
  15.     // Change the rest at your own peril!
  16.     if (NUM_CARDS > 25) die("Setting this higher than 25 will cause an infinite loop.");
  17.     /*
  18.         Defines
  19.     */
  20.     define('SPADES'     , 0b00);
  21.     define('CLUBS'      , 0b01);
  22.     define('HEARTS'     , 0b10);
  23.     define('DIAMONDS'   , 0b11);
  24.     define('NO_CARD'    , 0b111111); // Value used to mark that there's no card
  25.     $deck = ['A',2,3,4,5,6,7,8,9,10,'J','Q','K'];
  26.     $cards_given = [56]; // Initialize the list of given cards with an out of range value
  27.     $wins = $losses = $highscore = 0;
  28.     // Max value for card (13) is 1101
  29.    
  30.     // CARD FORMAT
  31.     // NNNNTT
  32.    
  33.     $act = isset($_GET['act']) ? $_GET['act'] : "";
  34.     $output = "";
  35.    
  36.     switch ($act) {
  37.         case "": // Init
  38.             $output = "<a href='?act=play'>Start game</a>\n\n<a href='?act=code'>Enter code</a>";
  39.             $currentstats = "";
  40.             break;
  41.         // Password
  42.         case 'code':
  43.             if (!isset($_POST['code'])) {
  44.                 $output = "<form method='POST' action='?act=code'>".
  45.                 "Enter code: <input type='text' name='code' maxlength=10 size=20> <input type='submit' name='go' value='OK'>".
  46.                 "</form>";
  47.                 $currentstats = "";
  48.             } else {
  49.                 $output = decode_password($_POST['code']);
  50.                 // HACK: The wins and losses are set to a random value since normally they would be 0
  51.                 // set them to 0 since we always start from after a game over
  52.                 //$wins = $losses = 0;
  53.                 $currentstats = print_scores($wins, $losses, $highscore);
  54.             }
  55.            
  56.             break;
  57.         case 'play':
  58.             // Main game
  59.             $status = load_scores();
  60.             $losses     = $status[0];
  61.             $wins       = $status[1];
  62.             $highscore  = $status[2];
  63.            
  64.             if (isset($_POST['deck0'])){
  65.                 $cards = load_deck();
  66.                 // changed marked cards
  67.                 for ($i = 0; $i < NUM_CARDS; $i++){
  68.                     if (isset($_POST["c$i"])) $cards[$i] = shuffle_deck(1, true);
  69.                     $decoded[] = decode_card($cards[$i]);
  70.                 }
  71.                 $check = false; // Checkbox to change cards
  72.                 // Scoring system crap
  73.                 $score = doscoring($decoded);
  74.                 // Change wins to score?
  75.                 switch ($score) {
  76.                     case S_ROYAL_FLUSH:     $x = "a Royal Flush"; break;
  77.                     case S_STRAIGHT_FLUSH:  $x = "a Straight Flush"; break;
  78.                     case S_POKER:           $x = "4 of a kind"; break;
  79.                     case S_FULL_HOUSE:      $x = "a Full house"; break;
  80.                     case S_FLUSH:           $x = "a Flush"; break;
  81.                     case S_STRAIGHT:        $x = "a Straight"; break;
  82.                     case S_THREE_OF_A_KIND: $x = "3 of a kind"; break;
  83.                     case S_TWO_PAIR:        $x = "2 pairs"; break;
  84.                     case S_ONE_PAIR:        $x = "1 pair"; break;
  85.                     case S_NOTHING:         $x = "nothing"; break;
  86.                 }
  87.                 $output = "\n\nYou got $x!";
  88.                 if (!$score){
  89.                     $losses++;
  90.                     $output .= " YOU LOSE!";
  91.                 } else {
  92.                     $wins++;
  93.                 }
  94.                 if ($losses <= MAX_LOSSES) {
  95.                     $output .= "\n<center><input type='submit' name='go' value='Continue'></center>";
  96.                 } else {
  97.                     $output .= "\n\n<big>OAME GVER</big>";
  98.                     if ($wins > $highscore){
  99.                         $highscore = $wins;
  100.                         $output .= "\nNew high score: $highscore!";
  101.                     }
  102.                     // HACK: Wins and Losses are always reset to 0 after a game over
  103.                     // since it would be a waste, just set them to a random 8bit value
  104.                     //$wins     = mt_rand(0, 255);
  105.                     //$losses = mt_rand(0, 255);
  106.                     $output .= "\nYour code is: ".encode_password($wins, $losses, $highscore)."\n\n<center><input type='submit' name='go' value='Restart'></center>";
  107.                     $wins = $losses = 0;
  108.                 }
  109.                
  110.             } else {
  111.                 $cards = shuffle_deck(NUM_CARDS);
  112.                 $check = true;
  113.             }
  114.            
  115.            
  116.             $output = print_deck($cards, $check).$output.pack_scores($wins, $losses, $highscore);
  117.             $currentstats = print_scores($wins, $losses, $highscore);
  118.             break;
  119.        
  120.     }
  121.    
  122.    
  123. ?><!doctype html>
  124. <html>
  125.     <head>
  126.         <title>Lazy poker game</title>
  127.         <style type="text/css">
  128.             body {
  129.                 background: #000;
  130.                 color:      #FFF;
  131.             }
  132.             .red    {color: #F00;}
  133.             .black  {color: #000;}
  134.             .card {
  135.                 width: 50px;
  136.                 background:     #FFF;
  137.                 border-top:     1px solid #FFF;
  138.                 border-left:    1px solid #EEE;
  139.                 border-bottom:  1px solid #BBB;
  140.                 border-right:   1px solid #CCC;
  141.                 border-radius:  3px;
  142.                
  143.                 box-shadow:     8px 8px 0px #555;
  144.                 line-height:    100%;
  145.             }
  146.             .status {
  147.                 border:         3px double #FFF;
  148.             }
  149.             .statushead {
  150.                 text-align:     center;
  151.                 background:     #FFF;
  152.                 color:          #000;
  153.             }
  154.             .statuscontainer {
  155.                 padding-left:   30px;
  156.                 padding-top:    50px;
  157.                 vertical-align: top;
  158.             }
  159.             .l {text-align: left;}
  160.             .c {text-align: center;}
  161.             .r {text-align: right;}
  162.             a  {color: #AFA;}
  163.         </style>
  164.     </head>
  165.     <body><table style='border-spacing: 0px'><tr><td style='min-width: 284px; vertical-align: top'>
  166. <pre>***********
  167. * <b>L</b> A Z Y *
  168. * C <b>A</b> R D *
  169. * G A <b>M</b> <b>E</b> *
  170. ***********
  171.  
  172. <?php echo $output ?></pre></td><td class='statuscontainer'><pre><?php echo $currentstats ?></pre></td></table>
  173.     </body>
  174. </html><?php
  175.  
  176. function drawcard($type, $num){
  177.     global $deck;
  178.    
  179.     switch ($type) {
  180.         case SPADES   : $class = 'black'; $char = '&#9824;'; break;
  181.         case CLUBS    : $class = 'black'; $char = '&#9827;'; break;
  182.         case HEARTS   : $class = 'red';   $char = '&#9829;'; break;
  183.         case DIAMONDS : $class = 'red';   $char = '&#9830;'; break;
  184.         default: die(header("Location: ?"));//die("Invalid card type. ($type)");
  185.     }
  186.    
  187.     if (!isset($deck[$num])) {
  188.         die(header("Location: ?"));//die("Invalid card number. ($num)");
  189.     }
  190.     return "".
  191.         "<table class='card $class'>".
  192.         "<tr><td class='l'>{$deck[$num]}<small><br>$char</small></td></tr>".
  193.         "<tr><td class='c'><big>$char</big>\n</td></tr>".
  194.         "<tr><td class='r'><small>$char<br></small>{$deck[$num]}</td></tr>".
  195.         "</table>";
  196. }
  197.  
  198. // Get 5 random cards
  199. function shuffle_deck($times, $single = false){
  200.     global $cards_given;
  201.     for($i = 0; $i < $times; $i++){
  202.         for($val = 56; in_array($val, $cards_given); $val = mt_rand(0, 51));
  203.         if ($single) return $val;
  204.         $cards_given[] = $val;
  205.         $deck[] = $val; // Your deck
  206.     }
  207.     return $deck;
  208. }
  209.  
  210. function print_deck($deck, $check = false){
  211.     $cnt = count($deck);
  212.     for ($t = $c = "", $i = 0; $i < $cnt; $i++){
  213.         if ($deck[$i] == NO_CARD) continue;
  214.         $card = decode_card($deck[$i]);
  215.         $t .= "<td style='padding-left: 3px'>".drawcard($card[0], $card[1])."</td>";
  216.         $c .= "<td style='padding-top: 6px' class='c'><input type='checkbox' name='c$i'></td>";
  217.     }
  218.    
  219.     return "<form method='POST' action='?act=play'><table><tr>$t</tr>".($check ? "<tr>$c</tr><tr><td class='c' colspan='$cnt'><input type='submit' name='go' value='Discard'>".pack_deck($deck, true)."</td></tr>" : "")."</table>";
  220. }
  221.  
  222. // Receives packed data and returns array
  223. function load_deck(){
  224.     global $cards_given;
  225.     for ($i = 0; isset($_POST["deck$i"]); $i++){
  226.         $deck[] = ($_POST["deck$i"]      ) & 0b111111; // CARD 0
  227.         $deck[] = ($_POST["deck$i"] >> 6 ) & 0b111111; // CARD 1 ...
  228.         $deck[] = ($_POST["deck$i"] >> 12) & 0b111111;
  229.         $deck[] = ($_POST["deck$i"] >> 18) & 0b111111;
  230.         $deck[] = ($_POST["deck$i"] >> 24) & 0b111111;
  231.     }
  232.     for($i = 0; $i < NUM_CARDS; $i++) $cards_given[] = $deck[$i];
  233.     return $deck;
  234. }
  235.  
  236. // Receives array and returns packed data
  237. function pack_deck($deck, $htmlout){
  238.     $cnt = count($deck);
  239.     for ($i = 0; $i < $cnt; $i++){//6*5 = 30bits
  240.         $x = $i * 5; // Current multiplier
  241.         for ($j = $x; $j < 5 + $x; $j++) if (!isset($deck[$j])) $deck[$j] = 0b111111; // check if slots for this int have cards or are empty. in the latter fill with 1111
  242.         $pack[] = $deck[$x] | $deck[$x+1] << 6 | $deck[$x+2] << 12 | $deck[$x+3] << 18 | $deck[$x+4] << 24;
  243.     }
  244.     if ($htmlout) {
  245.         $total = ceil($cnt / 5);
  246.         for ($i = 0, $o = ''; $i < $total; $i++){
  247.             $o .= "<input type='hidden' name='deck$i' value={$pack[$i]}>";
  248.             //print "COMPRESSED #$i = {$pack[$i]}\n";
  249.         }
  250.         return $o;
  251.     } else {
  252.         return $pack;
  253.     }
  254. }
  255.  
  256. function decode_card($card){
  257.     $type   = $card & 0b000011;
  258.     $num    = $card >> 2;
  259.     return [$type, $num];
  260. }
  261.  
  262. function encode_card($type, $num){
  263.     return $type | ($num << 2);
  264. }
  265.  
  266. // Highscore, Wins, Losses
  267. function decode_password($code){
  268.     global $cipher, $wins, $losses, $highscore;
  269.    
  270.     // decoding here
  271.     // decoding end
  272.     $code = (string) $code;
  273.     $len = strlen($code);
  274.     for($i = 0; $i < $len; $i++){
  275.         $code[$i] = strpos($cipher, $code[$i]);
  276.         if ($code[$i] === false) die(header("Location: ?"));
  277.     }
  278.    
  279.     $_POST['status'] = $code;
  280.     $stat = load_scores();
  281.    
  282.     // for the status screen function
  283.     $highscore  = $stat[2];
  284.     $wins       = $stat[1];
  285.     $losses     = $stat[0];
  286.    
  287.     // Success!
  288.     return "The code is valid.\nYour high score has been preserved.\n\n".
  289.     "<form method='POST' action='?act=play'>".pack_scores(0,0,$highscore)."<input type='submit' name='a' value='Continue game'></form>";
  290. }
  291. function encode_password($wins, $losses, $highscore){
  292.     global $cipher;
  293.     $code = pack_scores($wins, $losses, $highscore, true);
  294.     // Encoding here
  295.     $code = (string) $code;
  296.     $len = strlen($code);
  297.     for($i = 0; $i < $len; $i++){
  298.         $code[$i] = $cipher[$code[$i]];
  299.     }
  300.    
  301.     // Encoding end
  302.     return $code;
  303. }
  304.  
  305. function pack_scores($wins, $losses, $highscore, $print = false){
  306.    
  307.     $checksum   = 0b10101010 | $highscore ^ ($wins &~ $losses);
  308.     // do whatever load_scores does, in reverse
  309.     $wins_e      = $wins ^ 0b11110000;
  310.     $losses_e    = $losses ^ 0b10010110;
  311.     $highscore_e = $highscore ^ 0b11000011;
  312.     $checksum_e  = $checksum ^ 0b11001100;
  313.    
  314.     // high values << x - 4
  315.     // low values  << x
  316.     $result =
  317.         (($checksum_e & 0b11110000) << 24) | (($losses_e    & 0b1111    ) << 24) |
  318.         (($wins_e     & 0b1111    ) << 20) | (($highscore_e & 0b11110000) << 12) |
  319.         (($wins_e     & 0b11110000) <<  8) | (($checksum_e  & 0b1111    ) <<  8) |
  320.         (($losses_e   & 0b11110000)      ) | (($highscore_e & 0b1111    )      );
  321.     //print "W$wins_e<br>L$losses_e<br>H$highscore_e<br>C$checksum_e<br>R$result";
  322.    
  323.     if ($print) return $result;
  324.     return "<input type='hidden' name='status' value=$result>";
  325. }
  326. function load_scores(){
  327.     /*  SETTINGS: 32 bit int
  328.          2    1  1    2   2   1  2    1
  329.         CCCCLLLLWWWWHHHHWWWWCCCCLLLLHHHH
  330.       >>  28  24  20  16  12   8   4
  331.         C - Checksum
  332.         L - Losses
  333.         W - Wins
  334.         H - Max wins
  335.     */
  336.     if (!isset($_POST['status'])) return [0,0,0];
  337.    
  338.     //              block high                                      block low
  339.     $wins       = ((($_POST['status'] >>  8) & 0b11110000) | (($_POST['status'] >> 20) & 0b1111)) ^ 0b11110000;
  340.     $losses     = ((($_POST['status']      ) & 0b11110000) | (($_POST['status'] >> 24) & 0b1111)) ^ 0b10010110;
  341.     $highscore  = ((($_POST['status'] >> 12) & 0b11110000) | (($_POST['status']      ) & 0b1111)) ^ 0b11000011;
  342.     $checksum   = ((($_POST['status'] >> 24) & 0b11110000) | (($_POST['status'] >>  8) & 0b1111)) ^ 0b11001100;
  343.    
  344.     $checksumc  = 0b10101010 | $highscore ^ ($wins &~ $losses);
  345.     //print "W$wins<br>L$losses<br>H$highscore<br>C$checksum<br>C$checksumc<br>R".$_POST['status']."<br>";
  346.     if ($checksum != $checksumc) die(header("Location: ?"));//die("Checksum failed"); //return [0,0,0];
  347.     else return [$losses, $wins, $highscore];
  348. }
  349.  
  350. function print_scores($wins, $losses, $highscore){
  351.     return "".
  352.         "<table class='status'>".
  353.             "<tr><td class='statushead'>S T A T U S</td></tr>".
  354.             "<tr><td> High Score: $highscore</td></tr>".
  355.             "<tr><td> ===================== </td></tr>".
  356.             "<tr><td> Wins:   $wins</td></tr>".
  357.             "<tr><td> Losses: $losses</td></tr>".
  358.         "</table>";
  359. }
  360.  
  361. function doscoring($decoded){
  362.    
  363.     define('S_ROYAL_FLUSH'      , 0b1001);
  364.     define('S_STRAIGHT_FLUSH'   , 0b1000);
  365.     define('S_POKER'            , 0b0111);
  366.     define('S_FULL_HOUSE'       , 0b0110);
  367.     define('S_FLUSH'            , 0b0101);
  368.     define('S_STRAIGHT'         , 0b0100);
  369.     define('S_THREE_OF_A_KIND'  , 0b0011);
  370.     define('S_TWO_PAIR'         , 0b0010);
  371.     define('S_ONE_PAIR'         , 0b0001);
  372.     define('S_NOTHING'          , 0b0000); // You lose
  373.    
  374.    
  375.     $num  = array_fill(0, 13, 0);
  376.     $type = array_fill(0,  4, 0);
  377.    
  378.     // Count the amount of numbers and colors
  379.     foreach($decoded as $card){
  380.         $type[$card[0]]++;
  381.         $num[$card[1]]++;
  382.     }
  383.    
  384.     // Pre-calculated values useful for scoring checks
  385.     $straight   = continuous($num);
  386.     $flush      = in_array(5, $type);
  387.     $poker      = in_array(4, $num);
  388.     $three      = in_array(3, $num);
  389.     $two        = in_array(2, $num);
  390.    
  391.     if ($straight && $flush && $num[0] && $num[12]) {return S_ROYAL_FLUSH;}
  392.     if ($straight && $flush)                        {return S_STRAIGHT_FLUSH;}
  393.     if ($poker)                                     {return S_POKER;}
  394.     if ($three && $two)                             {return S_FULL_HOUSE;}
  395.     if ($flush)                                     {return S_FLUSH;}
  396.     if ($straight)                                  {return S_STRAIGHT;}
  397.     if ($three)                                     {return S_THREE_OF_A_KIND;}
  398.     if (alternated($num, 2,2))                      {return S_TWO_PAIR;}
  399.     if ($two)                                       {return S_ONE_PAIR;}
  400.     else                                            {return S_NOTHING;}
  401.    
  402. }
  403.  
  404. function continuous($num){
  405.     $num[13] = $num[0];
  406.     for($i = $c = 0; $i < 14; $i++){
  407.         if ($num[$i]){
  408.             $c++; // Every time a value is present we increase the C. when it reaches 5 we declare it good
  409.             if ($c == 5) return true;
  410.         } else {
  411.             $c = 0;
  412.         }
  413.     }
  414.     return false;
  415. }
  416.  
  417. // Find $val at least $times times in a deck
  418. function alternated($num, $val, $times){
  419.     for($i = $c = 0; $i < 13; $i++){
  420.         if ($num[$i] == $val){
  421.             $c++;
  422.             if ($c == $times) return true;
  423.         }
  424.     }
  425.     return false;
  426. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement