game related functions moved to briskin5
[brisk.git] / web / briskin5 / Obj / briskin5.phh
1 <?php
2 define(BRISKIN5_PLAYERS_N, 3);
3 define(BRISKIN5_MAX_PLAYERS, BRISKIN5_PLAYERS_N);
4 // define(BRISKIN5_SHM_MIN, (50000 * BRISKIN5_MAX_PLAYERS));
5 define(BRISKIN5_SHM_MIN, 32768);
6 define(BRISKIN5_SHM_MAX, (BRISKIN5_SHM_MIN + 1048576));
7 define(BRISKIN5_SHM_DLT, 32768);
8
9 $table_wellarr = Array ( 'Benvenuto al tavolo. Se almeno tre giocatori non sbloccano l\'uscita cliccando il lucchetto, chi esce non pu&ograve; risedersi a un qualunque tavolo per '.floor(BAN_TIME/60).' minuti.');
10
11
12 class Briskin5 {
13   var $user;
14   var $table;
15   var $table_idx;
16   var $table_token;
17
18   var $comm; // commands for many people
19   var $step; // current step of the comm array
20   var $garbage_timeout;
21
22   var $the_end;
23   
24   var $tok;
25   var $shm_sz;
26
27   function Briskin5 (&$room, $table_idx, $table_token) {
28     $this->user = array();
29     $this->table = array();
30
31     $this->the_end = FALSE;
32     $this->shm_sz = BRISKIN5_SHM_MIN;
33     if (($this->tok = @ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) {
34       echo "FTOK FAILED";
35       exit;
36     }
37
38     $user  =& $room->user;
39     $table =& $room->table[$table_idx];
40
41     log_wr("Briskin5 constructor");
42
43     for ($i = 0 ; $i < $table->player_n ; $i++) {
44       $user[$table->player[$i]]->table_token = $table_token;
45       $this->user[$i] =& User::spawn(&$user[$table->player[$i]], 0, $i);
46     }
47     $this->table[0] =& Table::spawn(&$table);
48     $this->table_idx = $table_idx;
49     $this->table_token = $table_token;
50     $this->garbage_timeout = 0;
51     
52     log_wr("Briskin5 constructor end");
53   }
54
55
56   function &get_user($sess, &$idx)
57   {
58     GLOBAL $PHP_SELF, $G_false;
59
60     if (validate_sess($sess)) {
61       for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) {
62         if (strcmp($sess, $this->user[$i]->sess) == 0) {
63           // find it
64           $idx = $i;
65           $ret = &$this->user[$i];
66           return ($ret);
67         }
68       }
69       log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
70       // for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) 
71       // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
72     }
73     else {
74       log_main(sprintf("get_user: Wrong strlen [%s]",$sess));
75     }
76
77     return ($G_false);
78   }
79
80
81   function garbage_manager($force)
82   {
83     
84     /* Garbage collector degli utenti in timeout */
85     $ismod = FALSE;
86     $curtime = time();
87     if ($force || $this->garbage_timeout < $curtime) {
88       
89       for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) {
90         $user_cur = &$this->user[$i];
91         if ($user_cur->sess == "" || 
92             ($user_cur->stat == 'table' && ($user_cur->subst == 'shutdowned' || $user_cur->subst == 'shutdowner')))
93           continue;
94         
95         if ($user_cur->lacc + EXPIRE_TIME_RD < $curtime) { // Auto logout dell'utente
96           log_rd2($user_cur->sess." bin5 AUTO LOGOUT.");
97
98           if ($user_cur->stat == 'table') {
99             log_auth($user_cur->sess," bin5 Autologout session.");
100
101             /* SI DELEGA AL garbage_manager principale LA RIMOZIONE DELL'UTENTE 
102
103             $tmp_sess = $user_cur->sess;
104             $user_cur->sess = "";
105             step_unproxy($tmp_sess);
106             $user_cur->name = "";
107             $user_cur->the_end = FALSE;
108             
109             */
110
111             $this->table_wakeup(&$user_cur);
112           }
113         }
114       }
115       log_rd2($user_cur->sess." GARBAGE UPDATED!");
116       
117       $this->garbage_timeout = $curtime + GARBAGE_TIMEOUT;
118       $ismod = TRUE;
119     }
120
121     return ($ismod);
122   }
123
124
125
126
127   //
128   //  static functions
129   //
130   function &load_data($table_idx, $table_token = "") 
131   {
132     GLOBAL $G_false, $sess;
133     $doexit = FALSE;
134     $shm = FALSE;
135
136     log_wr("TABLE_IDX ".FTOK_PATH."/table".$table_idx);
137     
138     do {
139       if (($tok = @ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) {
140         log_main("ftok failed");
141         $doexit = TRUE;
142         break;
143       }
144
145       if (($shm_sz = sharedmem_sz($tok)) == -1) {
146         log_main("shmop_open failed");
147         break;
148       }
149         
150       if (($shm = shm_attach($tok, $shm_sz)) == FALSE)
151         break;
152
153       if (($bri = @shm_get_var($shm, $tok)) == FALSE) 
154         break;
155
156       if ($table_token != "" && $bri->table_token != $table_token) {
157         log_wr("bri->table_token: ".$bri->table_token."table_token: ".$table_token);
158         
159         break;
160       }
161       $bri->tok = $tok;
162
163       shm_detach($shm);
164         
165       $ret = &$bri;
166       return ($ret); 
167     } while (FALSE);
168
169     if ($shm != FALSE)
170       shm_detach($shm);
171
172     log_wr("briskin5 load_data failed");
173     if ($doexit)
174       exit();
175     
176     return ($G_false);
177   }
178   
179
180
181   function save_data(&$bri) 
182   {
183     GLOBAL $sess;
184     
185     $ret =   FALSE;
186     $shm =   FALSE;
187     
188     log_main("SAVE BRISKIN5 DATA");
189     
190     if (!isset($bri->tok))
191       return (FALSE);
192     
193     while ($bri->shm_sz < BRISKIN5_SHM_MAX) {
194       if (($shm = shm_attach($bri->tok, $bri->shm_sz)) == FALSE)
195         break;
196       
197       if (@shm_put_var($shm, $bri->tok, $bri) != FALSE) {
198         shm_detach($shm);
199         return (TRUE);
200       }
201       if (shm_remove($shm) === FALSE) {
202         log_only("REMOVE FALLITA");
203         break;
204       }
205       shm_detach($shm);
206       $bri->shm_sz += BRISKIN5_SHM_DLT;
207     } 
208
209     log_crit("save data failed!");
210
211     if ($shm)
212       shm_detach($shm);
213     
214     return ($ret);
215   }
216
217
218
219   function destroy_data($table_idx) 
220   {
221     GLOBAL $sess;
222
223     $ret =   FALSE;
224     $shm =   FALSE;
225     log_main("DESTROY BRISKIN5 DATA");
226     
227     do {
228       log_main("DESTROY2 BRISKIN5 DATA");
229
230       if (($tok = @ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) 
231         break;
232
233       if (($shm = @shmop_open($tok, 'a', 0, 0)) == FALSE)
234         break;
235       
236       if (shmop_delete($shm) == 0) {
237         log_only("REMOVE FALLITA ");
238         break;
239       }
240    
241       $shm = FALSE;
242       log_main("DESTROY2 BRISKIN5 DATA SUCCESS");
243       
244       // log_main("QUI CI ARRIVA [".$bri->user[0]->name."]");
245       $ret = TRUE;
246     } while (0);
247     
248     if ($shm)
249       shm_detach($shm);
250     
251     return ($ret);
252   }
253
254   function lock_data($table_idx)
255   {
256     GLOBAL $sess; 
257     
258     log_wr("LOCK_DATA ".FTOK_PATH."/table".$table_idx);
259     //  echo "LOCK: ".FTOK_PATH."/main";
260     //  exit;
261     // WARNING monitor this step
262     if (($tok = @ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) {
263       return (FALSE);
264     }
265     // WARNING monitor this step
266     if (($res = @sem_get($tok)) == FALSE) {
267       return (FALSE);
268     }
269     if (sem_acquire($res)) {   
270       log_lock("LOCK table ".$table_idx."[res: ".$res."]");
271       return ($res);
272     }
273     else {
274       log_lock("LOCK table ".$table_idx.":FAILED");
275       return (FALSE);
276     }
277   }
278   
279   function unlock_data($res)
280   {
281     GLOBAL $sess; 
282     
283     log_lock("UNLOCK table [res: ".$res."]");
284
285     return (sem_release($res));
286   }
287
288
289   function chatt_send(&$user, $mesg)
290   {
291     if ($user->stat == 'table') {
292       $table = &$this->table[$user->table];
293     }
294     
295     $user_mesg = substr($mesg,6);
296     
297     $curtime = time();
298     
299     $dt = date("H:i ", $curtime);
300     if (strncmp($user_mesg, "/nick ", 6) == 0) {
301       log_main($user->sess." chatt_send BEGIN");
302
303       if (($name_new = validate_name(substr($user_mesg, 6))) == FALSE) {
304           $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
305           $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s", [2, "%s"],"Il nickname deve contenere almeno una lettera dell\'alfabeto o una cifra.");', $dt, NICKSERV);
306           $user->step_inc();
307
308           return;
309       }
310       $user_mesg = "COMMAND ".$user_mesg;
311       // Search dup name
312       // change
313       // update local graph
314       // update remote graphs
315       for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) {
316         $user_cur = &$this->user[$i];
317         //      if ($user_cur->sess == '' || $user_cur->stat != 'room')
318         if ($user_cur->sess == '')
319           continue;
320         if ($user_cur->name == $name_new) {
321           $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
322           $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s", [2, "%s"],"Nickname <b>%s</b> gi&agrave; in uso.%d");', $dt, NICKSERV, xcape($name_new), $this->table[$user->table]->auth_only == TRUE);
323           $user->step_inc();
324           break;
325         }
326       }
327       if ($i == BRISKIN5_MAX_PLAYERS) {
328         if ($user->flags & USER_FLAG_AUTH && strcasecmp($user->name,$name_new) != 0) {
329           if ($this->table[$user->table]->auth_only == TRUE) {
330             $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
331             $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s", [2, "%s"],"<b>Non puoi cambiare nick a un tavolo per soli autenticati.</b>");', $dt, NICKSERV);
332             $user->step_inc();
333             return;
334           }
335           else {
336             $user->flags &= ~USER_FLAG_AUTH; // Remove auth if name changed
337           }
338         }
339     
340         $user->name = $name_new;
341
342         log_main($user->sess." chatt_send start set");
343         
344
345         for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) {
346           log_main($user->sess." chatt_send set loop");
347           
348           $user_cur = &$this->user[$i];
349           if ($user_cur->sess == '')
350             continue;
351           if ($user_cur->stat == 'room') {
352             if ($user->stat == 'room' && $user->subst == 'standup') {
353               $this->standup_update(&$user);
354             }
355             else if ($user->stat == 'room' && $user->subst == 'sitdown' ||
356                      $user->stat == 'table') {
357               log_main($user->sess." chatt_send pre table update");
358
359               $this->table_update(&$user);
360
361               log_main($user->sess." chatt_send post table update");
362             }
363           }
364           else if ($user_cur->stat == 'table' && $user_cur->table == $user->table) {
365             $table = &$this->table[$user->table];
366             
367             $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
368             $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('set_names([%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"]); ',
369                       $this->user[$table->player[($user_cur->table_pos) % BRISKIN5_PLAYERS_N]]->flags,
370                       xcape($this->user[$table->player[($user_cur->table_pos) % BRISKIN5_PLAYERS_N]]->name),
371
372                       $this->user[$table->player[($user_cur->table_pos+1) % BRISKIN5_PLAYERS_N]]->flags,
373                       xcape($this->user[$table->player[($user_cur->table_pos+1) % BRISKIN5_PLAYERS_N]]->name),
374
375                       $this->user[$table->player[($user_cur->table_pos+2) % BRISKIN5_PLAYERS_N]]->flags,
376                       xcape($this->user[$table->player[($user_cur->table_pos+2) % BRISKIN5_PLAYERS_N]]->name),
377
378                       (BRISKIN5_PLAYERS_N == 3 ? 0:  $this->user[$table->player[($user_cur->table_pos+3) % BRISKIN5_PLAYERS_N]]->flags),
379                       (BRISKIN5_PLAYERS_N == 3 ? "" :  xcape($this->user[$table->player[($user_cur->table_pos+3) % BRISKIN5_PLAYERS_N]]->name)),
380
381                       (BRISKIN5_PLAYERS_N == 3 ? 0:  $this->user[$table->player[($user_cur->table_pos+4) % BRISKIN5_PLAYERS_N]]->flags),
382                       (BRISKIN5_PLAYERS_N == 3 ? "" :  xcape($this->user[$table->player[($user_cur->table_pos+4) % BRISKIN5_PLAYERS_N]]->name)));
383             if ($user_cur == $user) {
384               $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
385               $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
386               $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>";', 
387                                                                    $itin, xcape($user->name,ENT_COMPAT,"UTF-8"), $itou);
388             }
389             $user_cur->step_inc();
390           }
391         }
392       }
393     }
394     else {
395       for ($i = 0 ; $i < ($user->stat == 'room' ? BRISKIN5_MAX_PLAYERS : BRISKIN5_PLAYERS_N) ; $i++) {
396         if ($user->stat == 'room') {
397           $user_cur = &$this->user[$i];
398           if ($user_cur->sess == '' || $user_cur->stat != 'room')
399             continue;
400         }
401         else {
402           $user_cur = &$this->user[$table->player[$i]];
403         }
404         
405         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
406         $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('chatt_sub("%s", [%d, "%s"],"%s");',
407                                                              $dt, $user->flags, xcape($user->name), xcape($user_mesg));
408         $user_cur->step_inc();
409       }
410       log_legal($curtime, $user, ($user->stat == 'room' ? 'room' : 'table '.$user->table),$user_mesg);
411     }
412   }
413
414   function table_wakeup(&$user)
415   {
416     $table = &$this->table[0];
417
418     log_main("BRISKIN5_WAKEUP begin function table  stat: ".$user->stat."  subst: ".$user->subst);
419
420     $curtime = time();
421
422     log_main("BRISKIN5_WAKEUP from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
423     
424     for ($i = 0 ; $i < $table->player_n ; $i++) {
425       $user_cur = &$this->user[$i];
426       log_main("PREIMPOST INLOOP name: ".$user_cur->name);
427       
428       if ($user_cur == $user)
429         $user_cur->subst = "shutdowner";
430       else
431         $user_cur->subst = "shutdowned";
432       $user_cur->laccwr = $curtime;
433
434       $ret = "gst.st = ".($user_cur->step+1)."; ";
435       $ret .= 'gst.st_loc++; the_end=true; window.onbeforeunload = null; window.onunload = null; document.location.assign("../index.php");|';
436
437       log_wr($user_cur->sess." BRISKIN5_WAKEUP: ".$ret);
438       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
439       $user_cur->step_inc();
440     }
441
442     $this->the_end = TRUE;
443   }
444   
445   /*
446    *  If all players are freezed the room garbage_manager clean up table and users.
447    */ 
448   function is_abandoned() 
449   {
450     $is_ab = TRUE;
451     $curtime = time();
452
453     $table = &$this->table[0];
454
455     for ($i = 0 ; $i < $table->player_n ; $i++) {
456       $user_cur = &$this->user[$i];
457
458       if ($user_cur->lacc + (EXPIRE_TIME_RD * 2) >= $curtime) { 
459         $is_ab = FALSE;
460         break;
461       }
462     }
463
464     return ($is_ab);
465   }
466 } // end class Briskin5
467
468 function locshm_exists($tok)
469 {
470   // return (TRUE);
471
472   if (($id = @shmop_open($tok,"a", 0, 0)) == FALSE) {
473     log_main($tok." SHM NOT exists");
474
475     return (FALSE);
476   }
477   else {
478     shmop_close($id);
479     log_main($tok." SHM exists");
480
481     return (TRUE);
482   }
483     
484 }
485
486
487 function calculate_points(&$table)
488 {
489   GLOBAL $G_all_points; 
490
491   $pro = 0;
492
493   if ($table->asta_pnt == 60)
494     $table->asta_pnt = 61;
495
496   $table->old_reason = "";
497   $table->old_win = $table->asta_win;
498   $table->old_friend = $table->friend;
499   $table->old_asta_pnt = $table->asta_pnt;
500
501   for ($i = 0 ; $i < 40 ; $i++) {
502     $ctt = $table->card[$i]->value % 10;
503     $own = $table->card[$i]->owner;
504     if ($own == $table->asta_win || $own == $table->friend) 
505       $pro += $G_all_points[$ctt];
506   }
507
508   log_wr(sprintf("PRO: [%d]", $pro));
509
510   
511   if ($table->asta_pnt == 61 && $pro == 60) { // PATTA !
512     $table->points[$table->points_n % MAX_POINTS] = array();
513     for ($i = 0 ; $i < PLAYERS_N ; $i++) 
514       $table->points[$table->points_n % MAX_POINTS][$i] = 0;
515     $table->points_n++;
516     $table->old_pnt = $pro;
517     $table->mult *= 2;
518
519     return;
520   }
521
522   if ($pro >= $table->asta_pnt) 
523     $sig = 1;
524   else
525     $sig = -1;
526
527   $table->points[$table->points_n % MAX_POINTS] = array();
528   for ($i = 0 ; $i < 5 ; $i++) {
529     if ($i == $table->asta_win) 
530       $pt = ($i == $table->friend ? 4 : 2);
531     else if ($i == $table->friend) 
532       $pt = 1;
533     else
534       $pt = -1;
535
536     log_wr(sprintf("PRO: pt[%d][%d] = %d", $table->points_n % MAX_POINTS, $i, $pt));
537
538     $pt = $pt * $sig * $table->mult * ($pro == 120 ? 2 : 1);
539
540     log_wr(sprintf("PRO:[%d][%d][%d]", $sig, $table->mult, ($pro == 120 ? 2 : 1)));
541     
542     $table->points[$table->points_n % MAX_POINTS][$i] = $pt;
543     $table->total[$i] += $pt;
544   }
545   $table->points_n++;
546   $table->old_pnt = $pro;
547   $table->mult = 1;
548 }
549
550 /* show table 
551 is_transition (is from room to table ?)
552 is_again      (is another game)
553
554 Examples                    of $is_transition, $is_again:
555   from reload of the page:              FALSE, FALSE
556   from sitdown in room:                  TRUE, FALSE
557   from table: asta cmd e tutti passano:  TRUE, TRUE
558   from table: fine partita:              TRUE, TRUE
559  */
560 function show_table(&$room, &$user, $sendstep, $is_transition, $is_again)
561 {
562   $table_idx = $user->table;
563   $table = &$room->table[$table_idx];
564   $table_pos = $user->table_pos;
565
566   $ret = "table_init();";
567   $ret .= $table->exitlock_show(&$room->user, $table_pos);
568   if (!$is_again) {
569     /* GENERAL STATUS */
570     $ret .= sprintf( 'gst.st = %d; stat = "%s"; subst = "%s"; table_pos = %d;',
571                      $sendstep, $user->stat, $user->subst, $table_pos);
572
573     log_rd(sprintf( 'SHOW_TABLE: gst.st = %d; stat = "%s"; subst = "%s"; table_pos = %d;', $sendstep, $user->stat, $user->subst, $table_pos));
574
575     /* BACKGROUND */
576     $ret .= "background_set();";
577     
578     /* USERS INFO */
579     $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
580     $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
581
582     $ret .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>";', $itin, xcape($user->name), $itou);
583     $ret .= sprintf('set_names([%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"]); ',
584                     $room->user[$table->player[($table_pos)%PLAYERS_N]]->flags,
585                     xcape($room->user[$table->player[($table_pos)%PLAYERS_N]]->name),
586
587                     $room->user[$table->player[($table_pos+1)%PLAYERS_N]]->flags,
588                     xcape($room->user[$table->player[($table_pos+1)%PLAYERS_N]]->name),
589
590                     $room->user[$table->player[($table_pos+2)%PLAYERS_N]]->flags,
591                     xcape($room->user[$table->player[($table_pos+2)%PLAYERS_N]]->name),
592
593                     (PLAYERS_N == 3 ? 0 : $room->user[$table->player[($table_pos+3)%PLAYERS_N]]->flags),
594                     (PLAYERS_N == 3 ? "" :  xcape($room->user[$table->player[($table_pos+3)%PLAYERS_N]]->name)),
595
596                     (PLAYERS_N == 3 ? 0 : $room->user[$table->player[($table_pos+4)%PLAYERS_N]]->flags),
597                     (PLAYERS_N == 3 ? "" :  xcape($room->user[$table->player[($table_pos+4)%PLAYERS_N]]->name)));
598   }
599   /* NOTIFY FOR THE CARD MAKER */
600   if ($is_transition) { //  && $user->subst ==  "asta" superfluo
601     $ret .= show_table_info(&$room, &$table, $table_pos);
602   }
603   if (!$is_again) 
604     $ret .= table_wellcome($user);
605
606   if ($is_transition && !$is_again) { // appena seduti al tavolo, play della mucca
607     $ret .= playsound("cow.mp3");
608   }
609
610
611   /* CARDS */
612   if ($is_transition) { //  && $user->subst ==  "asta" superfluo
613     $ret .= "|";
614     
615     for ($i = 0 ; $i < 8 ; $i++) {
616       for ($e = 0 ; $e < PLAYERS_N ; $e++) {
617         $ct = 0;
618         for ($o = 0 ; $o < 40 && $ct < $i+1 ; $o++) {
619           if ($table->card[$o]->owner == (($e + $table->gstart) % PLAYERS_N)) {
620             $ct++;
621             if ($ct == $i+1)
622               break;
623           }
624         }
625         log_rd("O ".$o." VAL ".$table->card[$o]->value." Owner: ".$table->card[$o]->owner);
626         
627         $ret .= sprintf( ' card_send(%d,%d,%d,%8.2f,%d);|', ($table->gstart + $e) % PLAYERS_N, 
628                          $i, ((($e + PLAYERS_N - $table_pos + $table->gstart) % PLAYERS_N) == 0 ?
629                               $table->card[$o]->value : -1), 
630                          ($i == 7 && $e == (PLAYERS_N - 1) ? 1 : 0.5),$i+1);
631       }
632     }    
633   }
634   else {
635     $taked  = array(0,0,0,0,0);
636     $inhand = array(0,0,0,0,0);
637     $ontabl  = array(-1,-1,-1,-1,-1);
638     $cards  = array();
639
640     for ($i = 0 ; $i < 40 ; $i++) {
641       if ($table->card[$i]->stat == 'hand') {
642         if ($table->card[$i]->owner == $table_pos) {
643           $cards[$inhand[$table->card[$i]->owner]] = $table->card[$i]->value;
644         }
645         $inhand[$table->card[$i]->owner]++;
646       }
647       else if ($table->card[$i]->stat == 'take') {
648         log_main("Card taked: ".$table->card[$i]->value."OWN: ".$table->card[$i]->owner);
649         $taked[$table->card[$i]->owner]++;
650       }
651       else if ($table->card[$i]->stat == 'table') {
652         $ontabl[$table->card[$i]->owner] = $i;
653       }
654     }
655     $logg = "\n";
656     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
657       $logg .= sprintf("INHAND: %d   IN TABLE %d   TAKED %d\n", $inhand[$i], $ontabl[$i], $taked[$i]);
658     }
659     log_main("Stat table: ".$logg);
660
661     /* Set ours cards. */
662     $oursarg = "";
663     for ($i = 0 ; $i < $inhand[$table_pos] ; $i++) 
664       $oursarg .= ($i == 0 ? "" : ", ").$cards[$i];
665     for ($i = $inhand[$table_pos] ; $i < 8 ; $i++) 
666       $oursarg .= ($i == 0 ? "" : ", ")."-1";
667     $ret .= sprintf('card_setours(%s);', $oursarg);
668
669     /* Dispose all cards */
670     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
671       /* Qui sotto al posto di + 1 c'era + ->gstart ... credo in modo errato */
672       $ret .= sprintf('cards_dispose(%d,%d,%d);', $i,
673                       $inhand[$i], $taked[$i]);
674
675       if ($ontabl[$i] != -1) {
676         $ret .= sprintf('card_place(%d,%d,%d,%d,%d);',$i, $inhand[$i], 
677                         $table->card[$ontabl[$i]]->value, 
678                         $table->card[$ontabl[$i]]->x, $table->card[$ontabl[$i]]->y);
679       }
680     }
681   }
682
683   /* Show auction */
684   if ($user->subst == 'asta') {
685
686     /* show users auction status */
687     $showst = "";
688     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
689       $user_cur = &$room->user[$table->player[$i]];
690       $showst .= sprintf("%s%d", ($i == 0 ? "" : ", "), 
691                          ($user_cur->asta_card < 9 ? $user_cur->asta_card : $user_cur->asta_pnt));
692     }
693     if (PLAYERS_N == 3)
694         $showst .= ",-2,-2";
695     $ret .= sprintf('show_astat(%s);', $showst);
696
697     if ($table->asta_win != -1 && $table->asta_win == $table_pos) {
698       /* show card chooser */
699       $ret .= sprintf('choose_seed(%s); $("astalascio").style.visibility = ""; $("asta").style.visibility = "hidden";',
700                       $table->asta_card);
701     }
702     else {
703       /* show auction */
704       if ($table_pos == ($table->gstart % PLAYERS_N) &&
705           $table->asta_win == -1) 
706         $ret .= sprintf('dispose_asta(%d,%d, %s);', 
707                         $table->asta_card + 1, $table->asta_pnt+1, ($user->handpt <= 2 ? "true" : "false"));
708       else
709         $ret .= sprintf('dispose_asta(%d,%d, %s);',
710                         $table->asta_card + 1, -($table->asta_pnt+1), ($user->handpt <= 2 ?  "true" : "false"));
711     }
712
713     /* Remark */
714     if ($table->asta_win == -1) { // auction case
715       if ($table_pos == ($table->gstart % PLAYERS_N)) 
716         $ret .= "remark_on();";
717       else
718         $ret .= "remark_off();";
719     }
720     else { // chooseed case
721       if ($table_pos == $table->asta_win) 
722         $ret .= "remark_on();";
723       else
724         $ret .= "remark_off();";
725     }
726   }
727   else if ($user->subst == 'game') {
728     /* HIGHLIGHT */
729     if (($table->gstart + $table->turn) % PLAYERS_N == $table_pos) 
730       $ret .= "is_my_time = true; remark_on();";
731     else
732       $ret .= "remark_off();";
733     
734     /* WHO CALL AND WATH */
735     $ret .= briscola_show($room, $table, $user);
736     
737   }
738   return ($ret);
739 } // end function show_table(...
740
741 function calculate_winner(&$table)
742 {
743   $briontab = FALSE;
744   $ontab = array();
745   $ontid = array();
746   $cur_win  =  -1;
747   $cur_val  = 100;
748   $cur_seed = $table->briscola - ($table->briscola % 10);
749
750   for ($i = 0 ; $i < 40 ; $i++) {
751     if ($table->card[$i]->stat != "table")
752       continue;
753
754     log_wr(sprintf("Card On table: [%d]", $i));
755
756     $v = $table->card[$i]->value; 
757     $ontab[$table->card[$i]->owner] = $v;
758     $ontid[$table->card[$i]->owner] = $i;
759     /* se briscola setto il flag */
760     if (($v - ($v % 10)) == $cur_seed)
761       $briontab = TRUE;
762   }
763
764   if ($briontab == FALSE) {
765     $cur_win  = $table->gstart;
766     $cur_val  = $ontab[$cur_win];
767     $cur_seed = $cur_val - ($cur_val % 10);
768   }
769
770   for ($i = 0 ; $i < PLAYERS_N ; $i++) {
771     if (($ontab[$i] - ($ontab[$i] % 10)) == $cur_seed) {
772       if ($ontab[$i] < $cur_val) {
773         $cur_val = $ontab[$i];
774         $cur_win = $i;
775       }
776     }
777   }
778
779   for ($i = 0 ; $i < PLAYERS_N ; $i++) {
780     $table->card[$ontid[$i]]->owner = $cur_win;
781     $table->card[$ontid[$i]]->stat =  "take"; // Card stat
782   }
783   return ($cur_win);
784 }
785
786 function show_table_info(&$room, &$table, $table_pos)
787 {
788   $ret = "";
789   $user = &$room->user[$table->player[$table_pos]];
790
791   $pnt_min = $table->points_n - MAX_POINTS < 0 ? 0 : $table->points_n - MAX_POINTS;
792   $noty = sprintf('<table class=\"points\"><tr><th></th>');
793   
794   // Names.
795   for ($i = 0 ; $i < PLAYERS_N ; $i++) 
796     $noty .= sprintf('<th class=\"td_points\">%s</th>', xcape($room->user[$table->player[$i]]->name));
797   $noty .= sprintf("</tr>");
798
799   // Points.
800   log_main("show_table_info: pnt_min: ".$pnt_min."   Points_n: ".$table->points_n);
801
802   for ($i = $pnt_min ; $i < $table->points_n ; $i++) {
803     $noty .= sprintf('<tr><th class=\"td_points\">%d</th>', $i+1);
804     for ($e = 0 ; $e < PLAYERS_N ; $e++) 
805       $noty .= sprintf('<td class=\"td_points\">%d</td>', $table->points[$i % MAX_POINTS][$e]);
806     $noty .= "</tr>";
807   }
808
809   // Total points.
810   $noty .= '<tr><th class=\"td_points\">Tot.</th>';
811   for ($e = 0 ; $e < PLAYERS_N ; $e++) 
812     $noty .= sprintf('<td class=\"td_points\">%d</td>', $table->total[$e]);
813   $noty .= "</tr></table>";
814
815   if ($table->old_reason != "") {
816     $noty .= sprintf("<hr><b>%s</b><br>", xcape($table->old_reason));
817   }
818
819   if ($table->old_win != -1) {
820     $win = $table->player[$table->old_win];
821     $fri = $table->player[$table->old_friend];
822
823     $wol = game_result($table->old_asta_pnt, $table->old_pnt);
824
825     if ($win != $fri) {
826       /* MLANG: "<hr>Nell'ultima mano ha chiamato <b>%s</b>, il socio era <b>%s</b>,<br>", "hanno fatto <b>cappotto</b> EBBRAVI!.<hr>", "dovevano fare <b>%s</b> punti e ne hanno fatti <b>%d</b>: hanno <b>%s</b>.<hr>", "<hr>Nell'ultima mano <b>%s</b> si &egrave; chiamato in mano,<br>", "ha fatto <b>cappotto</b> EBBRAVO!.<hr>", "doveva fare <b>%s</b> punti e ne ha fatti <b>%d</b>: ha <b>%s</b>.<hr>", ($table->old_asta_pnt > 61 ? "almeno ".$table->old_asta_pnt : 'pi&ugrave; di 60'), $table->old_pnt, ($wol == 1 ? "vinto" : ($wol == 0 ? "pareggiato" : "perso" */
827       $noty .= sprintf("<hr>Nell'ultima mano ha chiamato <b>%s</b>, il socio era <b>%s</b>,<br>", 
828                        xcape($room->user[$win]->name),
829                        xcape($room->user[$fri]->name));
830       if ($table->old_pnt == 120) {
831         $noty .= sprintf("hanno fatto <b>cappotto</b> EBBRAVI!.<hr>");
832       }
833       else {
834         $noty .= sprintf("dovevano fare <b>%s</b> punti e ne hanno fatti <b>%d</b>: hanno <b>%s</b>.<hr>",
835                          ($table->old_asta_pnt > 61 ? "almeno ".$table->old_asta_pnt :
836                           'pi&ugrave; di 60'), $table->old_pnt,
837                          ($wol == 1 ? "vinto" : ($wol == 0 ? "pareggiato" : "perso")));
838       }
839     }
840     else {
841       $noty .= sprintf("<hr>Nell'ultima mano <b>%s</b> si &egrave; chiamato in mano,<br>", 
842                        xcape($room->user[$win]->name));
843       if ($table->old_pnt == 120) {
844         $noty .= sprintf("ha fatto <b>cappotto</b> EBBRAVO!.<hr>");
845       }
846       else {
847         $noty .= sprintf("doveva fare <b>%s</b> punti e ne ha fatti <b>%d</b>: ha <b>%s</b>.<hr>",
848                          ($table->old_asta_pnt > 61 ? "almeno ".$table->old_asta_pnt :
849                           'pi&ugrave; di 60'), $table->old_pnt,
850                          ($wol == 1 ? "vinto" : ($wol == 0 ? "pareggiato" : "perso")));
851       }
852     }
853   }
854   /* MLANG: "Fai <b>tu</b> il mazzo,", "Il mazzo a <b>$unam</b>," */
855   if ($table->mazzo == $table_pos) 
856     $noty .= "Fai <b>tu</b> il mazzo,";
857   else {
858     $unam = xcape($room->user[$table->player[$table->mazzo]]->name);
859     $noty .= "Il mazzo a <b>$unam</b>,";
860   }
861
862   if ($user->subst == 'asta') {
863     if ($table->asta_win == -1)  // auction case
864       $curplayer = $table->gstart % PLAYERS_N;
865     else 
866       $curplayer = $table->asta_win;
867   }
868   else if ($user->subst == 'game') {
869     $curplayer = ($table->gstart + $table->turn) % PLAYERS_N;
870   }
871
872   /* MLANG: " tocca a <b>te</b> giocare.", " tocca a <b>$unam</b> giocare.", " La partita vale <b>%s</b>.", "torna alla partita" */
873   if ($curplayer == $table_pos) {
874     $noty .= " tocca a <b>te</b> giocare.";
875   }
876   else {
877     $unam = xcape($room->user[$table->player[$curplayer]]->name);
878     $noty .= " tocca a <b>$unam</b> giocare.";
879   }
880   
881   if ($table->mult > 1) {
882     $noty .= sprintf(" La partita vale <b>%s</b>.", multoval($table->mult));
883   }
884   $noty .= "<hr><br>";
885   $ret .= show_notify($noty, 3000, "torna alla partita", 500, 400);
886   /* NOTE: show_notify($noty, 3000, "torna alla partita", 500, 
887    *                   130 + ($table->points_n > 0 ? 50 : 0) + 
888    *                   (120 * ($table->points_n / MAX_POINTS)));
889    *       will be used when we refact notify js function following 
890    *       photoo class logic 
891    */ 
892   
893   return ($ret);
894 }
895
896 function table_wellcome($user)
897 {
898   GLOBAL $table_wellarr;
899   $ret = "";
900
901   for ($i = 0 ; $i < count($table_wellarr) ; $i++)
902     $ret .= sprintf('chatt_sub("%s", [2, "ChanServ: "],"%s");', "", str_replace('"', '\"', $table_wellarr[$i]));
903
904   return ($ret);
905 }
906
907
908 function briscola_show($room, $table, $user)
909 {
910   $ptnadd = "";
911   $ret = "";
912
913   if ($table->asta_card == 9) 
914     $ptnadd = sprintf("<br>con %d punti", $table->asta_pnt);
915   
916   /* text of caller cell */
917   if ($user->table_pos == $table->asta_win) 
918     $ret .= sprintf('$("callerinfo").innerHTML = "Chiami%s:";', $ptnadd);
919   else 
920     $ret .= sprintf('$("callerinfo").innerHTML = "Chiama %s%s:";', 
921                     xcape($room->user[$table->player[$table->asta_win]]->name), $ptnadd);
922
923   $ret .= sprintf('$("caller").style.backgroundImage = \'url("img/brisk_caller_sand%d.png")\';',
924                   $table->asta_win);
925   $ret .= sprintf('$("callerimg").src = "img/%02d.png";', $table->briscola);
926   $ret .= sprintf('$("caller").style.visibility = "visible";');
927   $ret .= sprintf('$("chooseed").style.visibility = "hidden";');
928   $ret .= sprintf('$("astalascio").style.visibility = "";');
929   $ret .= sprintf('$("asta").style.visibility = "hidden";');
930   $ret .= sprintf('show_astat(-2,-2,-2,-2,-2);');
931   
932   return ($ret);
933 }
934
935
936 function game_result($asta_pnt, $pnt)
937 {
938   if ($asta_pnt == 61) {
939     if ($pnt > 60)
940       return (1);
941     else if ($pnt == 60)
942       return (0);
943     else
944       return (-1);
945   }
946   else {
947     if ($pnt >= $asta_pnt)
948       return (1);
949     else
950       return (-1);
951   }
952 }
953
954 ?>