NEW FEATURE: added admin name and email address to be configurable
[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 card_value($card)
287 {
288   switch($card)
289     {
290     case 3:     /* clubes */     
291     case 4:                      
292     case 5:     /* spades */     
293     case 6:                      
294     case 7:     /* hearts */     
295     case 8:                      
296     case 9:     /* diamonds */   
297     case 10:                     
298       return 3;
299     case 11:    /* clubes */     
300     case 12:                     
301     case 13:    /* spades */     
302     case 14:                     
303     case 15:    /* hearts */     
304     case 16:                     
305     case 17:    /* diamonds */   
306     case 18:
307       return 2;                  
308     case 19:    /* diamonds */ 
309     case 20:                   
310     case 27:    /* clubs */    
311     case 28:                   
312     case 35:    /* spades */   
313     case 36:                   
314     case 43:    /* hearts */   
315     case 44:                   
316       return 11;
317     case 1:      /* heart */
318     case 2:
319     case 21:    /* diamonds */    
320     case 22:
321     case 29:    /* clubs */
322     case 30:
323     case 37:    /* spades */
324     case 38:
325       return 10;
326     case 23:    /* diamonds */ 
327     case 24:                   
328     case 31:    /* clubs */    
329     case 32:                   
330     case 39:    /* spades */   
331     case 40:                   
332     case 45:    /* hearts */   
333     case 46:                   
334       return 4;
335     case 25:    /* diamonds */   
336     case 26:                   
337     case 33:    /* clubs */    
338     case 34:                   
339     case 41:    /* spades */   
340     case 42:                   
341     case 47:    /* hearts */   
342     case 48:                   
343       return 0;
344     default:
345       myerror("something went wrong, please contact $ADMIN_NAME at $ADMIN_EMAIL. ErrorCode: 2 - $card<br>");
346       echo "something went wrong, please contact $ADMIN_NAME at $ADMIN_EMAIL. ErrorCode: 2 - $card<br>";
347       return 0;
348     }
349 }
350
351
352 function  create_array_of_random_numbers($useridA,$useridB,$useridC,$useridD)
353 {
354   global $debug;
355
356   $r = array();
357   
358   if($debug)
359     {
360       $r[ 0]=1;     $r[12]=47;   $r[24]=13;       $r[36]=37;
361       $r[ 1]=2;     $r[13]=48;   $r[25]=14;       $r[37]=38;
362       $r[ 2]=3;     $r[14]=27;   $r[26]=15;       $r[38]=39;
363       $r[ 3]=4;     $r[15]=16;   $r[27]=28;       $r[39]=40;
364       $r[ 4]=5;     $r[16]=17;   $r[28]=29;       $r[40]=41;
365       $r[ 5]=18;    $r[17]=6;    $r[29]=30;       $r[41]=42;
366       $r[ 6]=19;    $r[18]=7;    $r[30]=31;       $r[42]=43;
367       $r[ 7]=20;    $r[19]=8;    $r[31]=32;       $r[43]=44;
368       $r[ 8]=45;    $r[20]=9;    $r[32]=21;       $r[44]=33;
369       $r[ 9]=46;    $r[21]=10;   $r[33]=22;       $r[45]=34;
370       $r[10]=35;    $r[22]=11;   $r[34]=23;       $r[46]=25;
371       $r[11]=36;    $r[23]=12;   $r[35]=24;       $r[47]=26;
372     }
373   else
374     {
375       /* check if we can find a game were non of the player was involved and return 
376        * cards insted 
377        */
378       $userstr = implode(",",array($useridA,$useridB,$useridC,$useridD));
379       $randomnumbers = DB_get_unused_randomnumbers($userstr);
380       $randomnumbers = explode(":",$randomnumbers);
381       
382       if(sizeof($randomnumbers)==48)
383         return $randomnumbers;
384       
385       /* need to create new numbers */
386       for($i=0;$i<48;$i++)
387         $r[$i]=$i+1;
388       
389       shuffle($r); 
390     };
391
392   return $r;
393 }
394
395
396
397
398 function display_cards($me,$myturn)
399 {
400   return;
401 }
402
403 function return_timezone($offset)
404 {
405   switch($offset)
406     {
407     case '1':
408       $zone = "Europe/Berlin";
409       break;
410     case '-8':
411       $zone = "America/Vancouver";
412       break;
413     case '13':
414       $zone = "Pacific/Auckland";
415       break;
416     default:
417       $zone = "Europe/London";
418     }
419   
420   return $zone;
421 }
422
423 function have_suit($cards,$c)
424 {
425   global $CARDS;
426   $suite = array();
427
428   if(in_array($c,$CARDS["trump"]))
429     $suite = $CARDS["trump"];
430   else if(in_array($c,$CARDS["clubs"]))
431     $suite = $CARDS["clubs"];
432   else if(in_array($c,$CARDS["spades"]))
433     $suite = $CARDS["spades"];
434   else if(in_array($c,$CARDS["hearts"]))
435     $suite = $CARDS["hearts"];
436   else if(in_array($c,$CARDS["diamonds"]))
437     $suite = $CARDS["diamonds"];
438
439   foreach($cards as $card)
440     {
441       if(in_array($card,$suite))
442         return 1;
443     }
444
445   return 0;
446 }
447
448 function same_type($card,$c)
449 {
450   global $CARDS;
451   $suite = "";
452
453   /* figure out what kind of card c is */
454   if(in_array($c,$CARDS["trump"]))
455     $suite = $CARDS["trump"];
456   else if(in_array($c,$CARDS["clubs"]))
457     $suite = $CARDS["clubs"];
458   else if(in_array($c,$CARDS["spades"]))
459     $suite = $CARDS["spades"];
460   else if(in_array($c,$CARDS["hearts"]))
461     $suite = $CARDS["hearts"];
462   else if(in_array($c,$CARDS["diamonds"]))
463     $suite = $CARDS["diamonds"];
464
465   /* card is the same suid return 1 */ 
466   if(in_array($card,$suite))
467     return 1;
468   
469   return 0;
470 }
471
472 function set_gametype($gametype)
473 {
474   global $CARDS;
475   global $RULES;
476
477   switch($gametype)
478     {
479     case "normal":
480     case "wedding":
481     case "poverty":
482     case "dpoverty":
483     case "trump":
484     case "silent":
485       $CARDS["trump"]    = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
486                                  '17','18','19','20','21','22','23','24','25','26');
487       $CARDS["diamonds"] = array();
488       $CARDS["clubs"]    = array('27','28','29','30','31','32','33','34');
489       $CARDS["spades"]   = array('35','36','37','38','39','40','41','42');
490       $CARDS["hearts"]   = array('43','44','45','46','47','48');
491       $CARDS["foxes"]    = array('19','20');
492       if($RULES["dullen"]=='none')
493         {
494           $CARDS["trump"]    = array('3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
495                                      '17','18','19','20','21','22','23','24','25','26');
496           $CARDS["hearts"]   = array('43','44','1','2','45','46','47','48');
497         }
498       break;
499     case "queen":
500       $CARDS["trump"]    = array('3','4','5','6','7','8','9','10');
501       $CARDS["clubs"]    = array('27','28','29','30','31','32','11','12','33','34');
502       $CARDS["spades"]   = array('35','36','37','38','39','40','13','14','41','42');
503       $CARDS["hearts"]   = array('43','44', '1', '2','45','46','15','16','47','48');
504       $CARDS["diamonds"] = array('19','20','21','22','23','24','17','18','25','26');
505       $CARDS["foxes"]    = array();
506       break;
507     case "jack":
508       $CARDS["trump"]    = array('11','12','13','14','15','16','17','18');
509       $CARDS["clubs"]    = array('27','28','29','30','31','32','3', '4','33','34');
510       $CARDS["spades"]   = array('35','36','37','38','39','40','5', '6','41','42');
511       $CARDS["hearts"]   = array('43','44', '1', '2','45','46','7', '8','47','48');
512       $CARDS["diamonds"] = array('19','20','21','22','23','24','9','10','25','26');
513       $CARDS["foxes"]    = array();
514       break;
515     case "trumpless":
516       $CARDS["trump"]    = array();
517       $CARDS["clubs"]    = array('27','28','29','30','31','32','3', '4','11','12','33','34');
518       $CARDS["spades"]   = array('35','36','37','38','39','40','5', '6','13','14','41','42');
519       $CARDS["hearts"]   = array('43','44', '1', '2','45','46','7', '8','15','16','47','48');
520       $CARDS["diamonds"] = array('19','20','21','22','23','24','9','10','17','18','25','26');
521       $CARDS["foxes"]    = array();
522       break;
523     case "club":
524       $CARDS["trump"]    = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
525                                  '17','18','27','28','29','30','31','32','33','34');
526       $CARDS["clubs"]    = array();
527       $CARDS["spades"]   = array('35','36','37','38','39','40','41','42');
528       $CARDS["hearts"]   = array('43','44','45','46','47','48');
529       $CARDS["diamonds"] = array('19','20','21','22','23','24','25','26');
530       $CARDS["foxes"]    = array();
531       if($RULES["dullen"]=='none')
532         {
533           $CARDS["trump"]    = array('3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
534                                      '17','18','27','28','29','30','31','32','33','34');
535           $CARDS["hearts"]   = array('43','44','1','2','45','46','47','48');
536         }
537       break;
538     case "spade":
539       $CARDS["trump"]    = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
540                                  '17','18','35','36','37','38','39','40','41','42');
541       $CARDS["clubs"]    = array('27','28','29','30','31','32','33','34');
542       $CARDS["spades"]   = array();
543       $CARDS["hearts"]   = array('43','44','45','46','47','48');
544       $CARDS["diamonds"] = array('19','20','21','22','23','24','25','26');
545       $CARDS["foxes"]    = array();
546       if($RULES["dullen"]=='none')
547         {
548           $CARDS["trump"]    = array('3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
549                                      '17','18','35','36','37','38','39','40','41','42');
550           $CARDS["hearts"]   = array('43','44','1','2','45','46','47','48');
551         }
552       break;
553     case "heart":
554       $CARDS["trump"]    = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
555                                  '17','18','43','44','45','46','47','48');
556       $CARDS["clubs"]    = array('27','28','29','30','31','32','33','34');
557       $CARDS["spades"]   = array('35','36','37','38','39','40','41','42');
558       $CARDS["hearts"]   = array();
559       $CARDS["diamonds"] = array('19','20','21','22','23','24','25','26');
560       $CARDS["foxes"]    = array();
561       if($RULES["dullen"]=='none')
562         {
563           $CARDS["trump"]    = array('3','4','5','6','7','8','9','10','11','12','13','14','15','16', 
564                             '17','18','43','44','1','2','45','46','47','48');
565         }
566       break;
567     }
568 }
569
570 function mysort($cards,$gametype)
571 {
572   usort ( $cards, "sort_comp" );
573   return $cards;
574 }
575
576 function sort_comp($a,$b)
577 {
578   global $CARDS;
579
580   $ALL = array();
581   $ALL = array_merge($CARDS["trump"],$CARDS["diamonds"],$CARDS["clubs"],
582                      $CARDS["hearts"],$CARDS["spades"],$CARDS["diamonds"]);
583
584   return pos_array($a,$ALL)-pos_array($b,$ALL);
585 }
586
587 function can_call($what,$hash)
588 {
589   global $RULES;
590
591   /*TODO: check if this already has been call by teammate */
592   
593   $gameid   = DB_get_gameid_by_hash($hash);
594   $gametype = DB_get_gametype_by_gameid($gameid);
595
596   $NRcards  = count(DB_get_hand($hash));
597   
598   $NRallcards = 0;
599   for ($i=1;$i<5;$i++)
600     {
601       $user         = DB_get_hash_from_game_and_pos($gameid,$i);
602       $NRallcards  += count(DB_get_hand($user));
603     };
604   
605   /* in case of a wedding, everything will be delayed by an offset */
606   $offset = 0;
607   if($gametype=="wedding")
608     {
609       $offset = DB_get_sickness_by_gameid($gameid); 
610       if ($offset <0) /* not resolved */
611         return 0;
612     };
613
614   switch ($RULES["call"])
615     {
616     case "1st-own-card":
617       if( 4-($what/30) >= 12 - ($NRcards + $offset))
618         return 1;
619       break;
620     case "5th-card":
621       if( 27+4*($what/30) <= $NRallcards + $offset*4)
622         return 1;
623       break;
624     case "9-cards":
625       if( ($what/10) <= $NRcards + $offset)
626         return 1;
627       break;
628     }
629
630   return 0;
631 }
632
633 ?>