NEW FEATURE: use a better random generator
[e-DoKo.git] / functions.php
1 <?php
2
3 function mymail($To,$Subject,$message,$header="")
4 {  
5   global $debug;
6
7   if($debug)
8     {
9       $message = str_replace("\n","<br />\n",$message);
10       $message = ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]",
11                      "<a href=\"\\0\">\\0</a>", $message);
12       
13       echo "<br />To: $To<br />";
14       if($header != "") 
15         echo $header."<br />";
16       echo "Subject: $Subject <br />$message<br />\n";
17     }
18   else
19     if($header != "")
20       mail($To,$Subject,$message,$header);
21     else
22       mail($To,$Subject,$message);
23   return;
24 }
25
26 function myisset()
27 {
28   /* returns 1 if all names passed as args are defined by a GET or POST statement,
29    * else return 0
30    */
31   
32   $ok   = 1;
33   $args = func_get_args();
34   
35   foreach($args as $arg)
36     {
37       $ok = $ok * isset($_REQUEST[$arg]);
38       /*echo "$arg: ok = $ok <br />";
39        */ 
40     }
41   return $ok;
42 }
43
44 function myerror($message)
45 {
46   echo "<span class=\"error\">".htmlspecialchars($message)."</span>\n";
47   mymail($ADMIN_EMAIL,$EmailName." Error in Code",$message);
48   return;
49 }
50
51 function pos_array($c,$arr)
52 {
53   $ret = 0;
54   
55   $i   = 0;
56   foreach($arr as $a)
57     {
58       $i++;
59       if($a == $c)
60         {
61           $ret = $i;
62           break;
63         }
64     }
65   return $ret;
66 }
67
68 function is_trump($c) 
69
70   global $CARDS;
71
72   if(in_array($c,$CARDS["trump"]))
73     return 1;
74   else 
75     return 0;
76 }
77
78 function is_same_suite($c1,$c2) 
79 {
80   global $CARDS;
81   
82   if(in_array($c1,$CARDS["trump"]   ) && in_array($c2,$CARDS["trump"]   ) ) return 1;
83   if(in_array($c1,$CARDS["clubs"]   ) && in_array($c2,$CARDS["clubs"]   ) ) return 1;
84   if(in_array($c1,$CARDS["hearts"]  ) && in_array($c2,$CARDS["hearts"]  ) ) return 1;
85   if(in_array($c1,$CARDS["spades"]  ) && in_array($c2,$CARDS["spades"]  ) ) return 1;
86   if(in_array($c1,$CARDS["diamonds"]) && in_array($c2,$CARDS["diamonds"]) ) return 1;
87   
88   return 0;
89 }
90
91 function compare_cards($a,$b,$game)
92 {
93   /* if "a" is higher than "b" return 1, else 0, "a" being the card first played */
94
95   global $CARDS;
96   global $RULES;
97   global $GAME;
98
99   /* first map all cards to the odd number, 
100    * this insure that the first card wins the trick 
101    * if they are the same card
102    */
103   if( $a/2 - (int)($a/2) != 0.5)
104     $a--;
105   if( $b/2 - (int)($b/2) != 0.5)
106     $b--;
107
108   /* some special cases */
109   switch($game)
110     {
111     case "normal":
112     case "silent":
113       if($RULES["schweinchen"]=="both" && $GAME["schweinchen"])
114         {
115           if($a == 19 || $a == 20 )
116             return 1;
117           if($b == 19 || $b == 20 )
118             return 0;
119         };
120       if($RULES["schweinchen"]=="second" && $GAME["schweinchen"]==3)
121         {
122           if($a == 19 || $a == 20 )
123             return 1;
124           if($b == 19 || $b == 20 )
125             return 0;
126         };
127     case "trump":
128     case "heart":
129     case "spade":
130     case "club":
131       if($RULES["dullen"]=="secondwins")
132         if($a==1 && $b==1) /* both 10 of hearts */
133           return 0;        /* second one wins.*/
134     }
135   
136   /* normal case */
137   if(is_trump($a) && is_trump($b) && $a<=$b)
138     return 1;
139   else if(is_trump($a) && is_trump($b) )
140     return 0;
141   else 
142     { /*$a is not a trump */
143       if(is_trump($b))
144         return 0;
145       else
146         { /* both no trump */
147
148           /* both clubs? */
149           $posA = pos_array($a,$CARDS["clubs"]);
150           $posB = pos_array($b,$CARDS["clubs"]);
151           if($posA && $posB)
152             if($posA <= $posB)
153               return 1;
154             else
155               return 0;
156
157           /* both spades? */
158           $posA = pos_array($a,$CARDS["spades"]);
159           $posB = pos_array($b,$CARDS["spades"]);
160           if($posA && $posB)
161             if($posA <= $posB)
162               return 1;
163             else
164               return 0;
165
166           /* both hearts? */
167           $posA = pos_array($a,$CARDS["hearts"]);
168           $posB = pos_array($b,$CARDS["hearts"]);
169           if($posA && $posB)
170             if($posA <= $posB)
171               return 1;
172             else
173               return 0;
174
175           /* both diamonds? */
176           $posA = pos_array($a,$CARDS["diamonds"]);
177           $posB = pos_array($b,$CARDS["diamonds"]);
178           if($posA && $posB)
179             if($posA <= $posB)
180               return 1;
181             else
182               return 0;
183           
184           /* not the same suit and no trump: a wins */
185           return 1;
186         }         
187     }
188
189
190 function get_winner($p,$mode)
191 {
192   /* get all 4 cards played in a trick, in the order they are played */
193   $tmp = $p[1];
194   $c1    = $tmp["card"];
195   $c1pos = $tmp["pos"]; 
196
197   $tmp = $p[2];
198   $c2    = $tmp["card"];
199   $c2pos = $tmp["pos"]; 
200
201   $tmp = $p[3];
202   $c3    = $tmp["card"];
203   $c3pos = $tmp["pos"]; 
204
205   $tmp = $p[4];
206   $c4    = $tmp["card"];
207   $c4pos = $tmp["pos"]; 
208
209   /* first card is better than all the rest */
210   if( compare_cards($c1,$c2,$mode) && compare_cards($c1,$c3,$mode) && compare_cards($c1,$c4,$mode) )
211     return $c1pos; 
212
213   /* second card is better than first and better than the rest */
214   if( !compare_cards($c1,$c2,$mode) &&  compare_cards($c2,$c3,$mode) && compare_cards($c2,$c4,$mode) )
215     return $c2pos;
216
217   /* third card is better than first card and better than last */
218   if( !compare_cards($c1,$c3,$mode) &&  compare_cards($c3,$c4,$mode) )
219     /* if second card is better than first, third card needs to be even better */
220     if( !compare_cards($c1,$c2,$mode) && !compare_cards($c2,$c3,$mode) )
221       return $c3pos;
222     /* second is worse than first, e.g. not following suite */
223     else if (compare_cards($c1,$c2,$mode) )
224       return $c3pos;
225
226   /* non of the above */
227   return $c4pos;
228 }
229
230 function count_nines($cards)
231 {
232   $nines = 0;
233
234   foreach($cards as $c)
235     {
236       if($c == "25" || $c == "26") $nines++;
237       else if($c == "33" || $c == "34") $nines++;
238       else if($c == "41" || $c == "42") $nines++;
239       else if($c == "47" || $c == "48") $nines++;
240     }
241   
242   return $nines;
243 }
244
245 function check_wedding($cards)
246 {
247
248   if( in_array("3",$cards) && in_array("4",$cards) )
249     return 1;
250
251   return 0;
252 }
253
254 function count_trump($cards)
255 {
256   global $RULES;
257
258   $trump = 0;
259
260   /* count each trump */
261   foreach($cards as $c)
262     if( (int)($c) <27) 
263       $trump++;
264
265   switch($RULES["schweinchen"])
266     {
267     case "none":
268       break;
269     case "second":
270     case "secondaftercall":
271       /* add one, in case the player has both foxes (schweinchen) */
272       if( in_array("19",$cards) && in_array("20",$cards) )
273         $trump++;
274     case "both":
275       /* subtract foxes */
276       if( in_array("19",$cards))
277         $trump--;
278       if( in_array("20",$cards) )
279         $trump--;
280       break;
281     }
282
283   return $trump;
284 }
285
286 function  create_array_of_random_numbers($useridA,$useridB,$useridC,$useridD)
287 {
288   global $debug;
289
290   $r = array();
291   
292   if($debug)
293     {
294       $r[ 0]=1;     $r[12]=47;   $r[24]=13;       $r[36]=37;
295       $r[ 1]=2;     $r[13]=48;   $r[25]=14;       $r[37]=38;
296       $r[ 2]=3;     $r[14]=27;   $r[26]=15;       $r[38]=39;
297       $r[ 3]=4;     $r[15]=16;   $r[27]=28;       $r[39]=40;
298       $r[ 4]=5;     $r[16]=17;   $r[28]=29;       $r[40]=41;
299       $r[ 5]=18;    $r[17]=6;    $r[29]=30;       $r[41]=42;
300       $r[ 6]=19;    $r[18]=7;    $r[30]=31;       $r[42]=43;
301       $r[ 7]=20;    $r[19]=8;    $r[31]=32;       $r[43]=44;
302       $r[ 8]=45;    $r[20]=9;    $r[32]=21;       $r[44]=33;
303       $r[ 9]=46;    $r[21]=10;   $r[33]=22;       $r[45]=34;
304       $r[10]=35;    $r[22]=11;   $r[34]=23;       $r[46]=25;
305       $r[11]=36;    $r[23]=12;   $r[35]=24;       $r[47]=26;
306     }
307   else
308     {
309       /* check if we can find a game were non of the player was involved and return 
310        * cards insted 
311        */
312       $userstr = "'".implode("','",array($useridA,$useridB,$useridC,$useridD))."'";
313       $randomnumbers = DB_get_unused_randomnumbers($userstr);
314       $randomnumbers = explode(":",$randomnumbers);
315       
316       if(sizeof($randomnumbers)==48)
317         return $randomnumbers;
318       
319       /* need to create new numbers */
320       for($i=0;$i<48;$i++)
321         $r[$i]=$i+1;
322       
323       /* shuffle using a better random generator than the standard one */
324       for ($i = 0; $i <48; $i++)
325         {
326           $j = @mt_rand(0, $i);
327           $tmp = $r[$i];
328           $r[$i] = $r[$j];
329           $r[$j] = $tmp;
330         }
331     };
332
333   return $r;
334 }
335
336
337
338
339 function display_cards($me,$myturn)
340 {
341   return;
342 }
343
344 function return_timezone($offset)
345 {
346   switch($offset)
347     {
348     case '1':
349       $zone = "Europe/Berlin";
350       break;
351     case '-8':
352       $zone = "America/Vancouver";
353       break;
354     case '13':
355       $zone = "Pacific/Auckland";
356       break;
357     default:
358       $zone = "Europe/London";
359     }
360   
361   return $zone;
362 }
363
364 function have_suit($cards,$c)
365 {
366   global $CARDS;
367   $suite = array();
368
369   if(in_array($c,$CARDS["trump"]))
370     $suite = $CARDS["trump"];
371   else if(in_array($c,$CARDS["clubs"]))
372     $suite = $CARDS["clubs"];
373   else if(in_array($c,$CARDS["spades"]))
374     $suite = $CARDS["spades"];
375   else if(in_array($c,$CARDS["hearts"]))
376     $suite = $CARDS["hearts"];
377   else if(in_array($c,$CARDS["diamonds"]))
378     $suite = $CARDS["diamonds"];
379
380   foreach($cards as $card)
381     {
382       if(in_array($card,$suite))
383         return 1;
384     }
385
386   return 0;
387 }
388
389 function same_type($card,$c)
390 {
391   global $CARDS;
392   $suite = "";
393
394   /* figure out what kind of card c is */
395   if(in_array($c,$CARDS["trump"]))
396     $suite = $CARDS["trump"];
397   else if(in_array($c,$CARDS["clubs"]))
398     $suite = $CARDS["clubs"];
399   else if(in_array($c,$CARDS["spades"]))
400     $suite = $CARDS["spades"];
401   else if(in_array($c,$CARDS["hearts"]))
402     $suite = $CARDS["hearts"];
403   else if(in_array($c,$CARDS["diamonds"]))
404     $suite = $CARDS["diamonds"];
405
406   /* card is the same suid return 1 */ 
407   if(in_array($card,$suite))
408     return 1;
409   
410   return 0;
411 }
412
413 function set_gametype($gametype)
414 {
415   global $CARDS;
416   global $RULES;
417
418   switch($gametype)
419     {
420     case "normal":
421     case "wedding":
422     case "poverty":
423     case "dpoverty":
424     case "trump":
425     case "silent":
426       $CARDS["trump"]    = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
427                                  '17','18','19','20','21','22','23','24','25','26');
428       $CARDS["diamonds"] = array();
429       $CARDS["clubs"]    = array('27','28','29','30','31','32','33','34');
430       $CARDS["spades"]   = array('35','36','37','38','39','40','41','42');
431       $CARDS["hearts"]   = array('43','44','45','46','47','48');
432       $CARDS["foxes"]    = array('19','20');
433       if($RULES["dullen"]=='none')
434         {
435           $CARDS["trump"]    = array('3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
436                                      '17','18','19','20','21','22','23','24','25','26');
437           $CARDS["hearts"]   = array('43','44','1','2','45','46','47','48');
438         }
439       break;
440     case "queen":
441       $CARDS["trump"]    = array('3','4','5','6','7','8','9','10');
442       $CARDS["clubs"]    = array('27','28','29','30','31','32','11','12','33','34');
443       $CARDS["spades"]   = array('35','36','37','38','39','40','13','14','41','42');
444       $CARDS["hearts"]   = array('43','44', '1', '2','45','46','15','16','47','48');
445       $CARDS["diamonds"] = array('19','20','21','22','23','24','17','18','25','26');
446       $CARDS["foxes"]    = array();
447       break;
448     case "jack":
449       $CARDS["trump"]    = array('11','12','13','14','15','16','17','18');
450       $CARDS["clubs"]    = array('27','28','29','30','31','32','3', '4','33','34');
451       $CARDS["spades"]   = array('35','36','37','38','39','40','5', '6','41','42');
452       $CARDS["hearts"]   = array('43','44', '1', '2','45','46','7', '8','47','48');
453       $CARDS["diamonds"] = array('19','20','21','22','23','24','9','10','25','26');
454       $CARDS["foxes"]    = array();
455       break;
456     case "trumpless":
457       $CARDS["trump"]    = array();
458       $CARDS["clubs"]    = array('27','28','29','30','31','32','3', '4','11','12','33','34');
459       $CARDS["spades"]   = array('35','36','37','38','39','40','5', '6','13','14','41','42');
460       $CARDS["hearts"]   = array('43','44', '1', '2','45','46','7', '8','15','16','47','48');
461       $CARDS["diamonds"] = array('19','20','21','22','23','24','9','10','17','18','25','26');
462       $CARDS["foxes"]    = array();
463       break;
464     case "club":
465       $CARDS["trump"]    = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
466                                  '17','18','27','28','29','30','31','32','33','34');
467       $CARDS["clubs"]    = array();
468       $CARDS["spades"]   = array('35','36','37','38','39','40','41','42');
469       $CARDS["hearts"]   = array('43','44','45','46','47','48');
470       $CARDS["diamonds"] = array('19','20','21','22','23','24','25','26');
471       $CARDS["foxes"]    = array();
472       if($RULES["dullen"]=='none')
473         {
474           $CARDS["trump"]    = array('3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
475                                      '17','18','27','28','29','30','31','32','33','34');
476           $CARDS["hearts"]   = array('43','44','1','2','45','46','47','48');
477         }
478       break;
479     case "spade":
480       $CARDS["trump"]    = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
481                                  '17','18','35','36','37','38','39','40','41','42');
482       $CARDS["clubs"]    = array('27','28','29','30','31','32','33','34');
483       $CARDS["spades"]   = array();
484       $CARDS["hearts"]   = array('43','44','45','46','47','48');
485       $CARDS["diamonds"] = array('19','20','21','22','23','24','25','26');
486       $CARDS["foxes"]    = array();
487       if($RULES["dullen"]=='none')
488         {
489           $CARDS["trump"]    = array('3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
490                                      '17','18','35','36','37','38','39','40','41','42');
491           $CARDS["hearts"]   = array('43','44','1','2','45','46','47','48');
492         }
493       break;
494     case "heart":
495       $CARDS["trump"]    = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
496                                  '17','18','43','44','45','46','47','48');
497       $CARDS["clubs"]    = array('27','28','29','30','31','32','33','34');
498       $CARDS["spades"]   = array('35','36','37','38','39','40','41','42');
499       $CARDS["hearts"]   = array();
500       $CARDS["diamonds"] = array('19','20','21','22','23','24','25','26');
501       $CARDS["foxes"]    = array();
502       if($RULES["dullen"]=='none')
503         {
504           $CARDS["trump"]    = array('3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
505                             '17','18','43','44','1','2','45','46','47','48');
506         }
507       break;
508     }
509 }
510
511 function mysort($cards,$gametype)
512 {
513   usort ( $cards, "sort_comp" );
514   return $cards;
515 }
516
517 function sort_comp($a,$b)
518 {
519   global $CARDS;
520
521   $ALL = array();
522   $ALL = array_merge($CARDS["trump"],$CARDS["diamonds"],$CARDS["clubs"],
523                      $CARDS["hearts"],$CARDS["spades"],$CARDS["diamonds"]);
524
525   return pos_array($a,$ALL)-pos_array($b,$ALL);
526 }
527
528 function can_call($what,$hash)
529 {
530   global $RULES;
531
532   /*TODO: check if this already has been call by teammate */
533   
534   $gameid   = DB_get_gameid_by_hash($hash);
535   $gametype = DB_get_gametype_by_gameid($gameid);
536
537   $NRcards  = count(DB_get_hand($hash));
538   
539   $NRallcards = 0;
540   for ($i=1;$i<5;$i++)
541     {
542       $user         = DB_get_hash_from_game_and_pos($gameid,$i);
543       $NRallcards  += count(DB_get_hand($user));
544     };
545   
546   /* in case of a wedding, everything will be delayed by an offset */
547   $offset = 0;
548   if($gametype=="wedding")
549     {
550       $offset = DB_get_sickness_by_gameid($gameid); 
551       if ($offset <0) /* not resolved */
552         return 0;
553     };
554
555   switch ($RULES["call"])
556     {
557     case "1st-own-card":
558       if( 4-($what/30) >= 12 - ($NRcards + $offset))
559         return 1;
560       break;
561     case "5th-card":
562       if( 27+4*($what/30) <= $NRallcards + $offset*4)
563         return 1;
564       break;
565     case "9-cards":
566       if( ($what/10) <= $NRcards + $offset)
567         return 1;
568       break;
569     }
570
571   return 0;
572 }
573
574 ?>