1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16 #define _GNU_SOURCE
17 #include <math.h>
18
19
20 #include <gtk/gtk.h>
21 #include <glib/gi18n.h>
22 #include "select.h"
23 #include "throw.h"
24 #include "position.h"
25 #include "set.h"
26 #include "game.h"
27 #include "free.h"
28 #include "draw.h"
29 #include "callback.h"
30 #include "list.h"
31 #include "def.h"
32
33 /* game_play_ia: play automagically. That's
34 * what we call Artificial Intelligence.
35 * Indeed that's not intelligent at all.
36 */
game_play_ia(struct _prog * prog_data)37 void game_play_ia(struct _prog *prog_data)
38 {
39 while(prog_data->player != 2
40 && prog_data->players[prog_data->player] != NULL
41 && prog_data->player != prog_data->hashand)
42 {
43 game_turn(prog_data, NULL);
44 }
45 }
46
47 /* game_middle_position: set the position (x,y)
48 * of each card in the list represented at the
49 * center of the game area (the table).
50 */
game_middle_position(struct _prog * prog_data)51 void game_middle_position(struct _prog *prog_data)
52 {
53 GList *ptr;
54
55 struct _card *data;
56
57 int player = prog_data->hashand;
58
59 if(player != -1)
60 {
61 for(ptr = g_list_last(prog_data->waiting); ptr; ptr = ptr->prev)
62 {
63 data = ptr->data;
64
65 game_position_middle(data, prog_data, player);
66
67 select_player_next(&player);
68
69 }
70 }
71 }
72
73 /* game_hand_position: set the position (x,y)
74 * of the cards in each player hand.
75 */
game_hand_position(struct _prog * prog_data,int player)76 void game_hand_position(struct _prog *prog_data, int player)
77 {
78 int x, y, w, h;
79 enum eposition ep;
80
81 int coef, start, max;
82
83 if(prog_data->back)
84 {
85 gdk_drawable_get_size(prog_data->back, &w, &h);
86 /*
87 w = gdk_pixbuf_get_width(prog_data->back);
88 h = gdk_pixbuf_get_height(prog_data->back);
89 */
90 if(player == -1)
91 {
92 start = 0;
93 max = 4;
94 }
95 else
96 {
97 start = player;
98 max = player+1;
99 }
100
101 for(player = start; player < max; player++)
102 {
103
104 switch(player)
105 {
106 case 0:
107 y = 10;
108 coef = 1;
109 /*x = (prog_data->area->allocation.width - w) / 3;*/
110 x = prog_data->area->allocation.width/2;
111 ep = EP_HORIZONTAL;
112 break;
113
114 case 1:
115 x = prog_data->area->allocation.width - w -10;
116 coef = 1;
117 /*y = (prog_data->area->allocation.height - h) / 2;*/
118 y = prog_data->area->allocation.height/2;
119 ep = EP_VERTICAL;
120 break;
121
122 case 2:
123 y = prog_data->area->allocation.height - h -10;
124 coef = -1;
125 /*x = (prog_data->area->allocation.width - w)*2 / 3;*/
126 x = prog_data->area->allocation.width/2;
127 ep = EP_HORIZONTAL;
128 break;
129
130 case 3:
131 x = 10;
132 coef = -1;
133 /*y = (prog_data->area->allocation.height - h)*2 / 3;*/
134 y = prog_data->area->allocation.height/2;
135 ep = EP_VERTICAL;
136 break;
137 }
138
139 position_list(prog_data->players[player],
140 x, y, ep, coef*prog_data->space, prog_data, w, h);
141
142 }
143 }
144 }
145
146 /* game_send: distributing cards function.
147 * This will send cards from one list to
148 * players list. Each player will take
149 * [the value of mod] cards.
150 *
151 * int mod: how many cards per player.
152 *
153 * int max: how many cards we want to send
154 * (total)
155 *
156 * GList *ptr: the list where we take the
157 * cards.
158 */
game_send(struct _prog * prog_data,int mod,int max,GList * ptr)159 GList* game_send(struct _prog *prog_data, int mod, int max,
160 GList *ptr)
161 {
162 int player = prog_data->distributer;
163 int i, modifier;
164 GList *last;
165
166 select_player_next(&player);
167
168 for(modifier = 0, i = 1; i <= max; i++)
169 {
170 if(ptr != NULL)
171 {
172 throw_to(&prog_data->players[player],
173 (struct _card*) ptr->data);
174
175 if(player == 2)
176 {
177 ((struct _card*) ptr->data)->draw_face = TRUE;
178 }
179
180 /* at the second distribution phase,
181 * we need to send three cards to each player
182 * except the one that choose the trump family.
183 * This one will take only two cards.
184 * That's why we do i++ here, so we won't be
185 * distributing [the value of mod] cards to him,
186 * but instead [[the value of mod]-1] cards. */
187 if(player == prog_data->master && modifier == 0)
188 {
189 i++;
190 modifier = 1;
191 }
192
193 if(i % mod == 0)
194 {
195 select_player_next(&player);
196 }
197
198
199 last = ptr;
200 ptr = ptr->next;
201
202 prog_data->pile = g_list_remove(prog_data->pile,
203 last->data);
204
205 }
206 else i = max+1;
207 }
208
209 return(ptr);
210 }
211
212 /* game_distribute_phase1 : send five cards to
213 * each player. (Three first, and two)
214 */
game_distribute_phase1(struct _prog * prog_data)215 void game_distribute_phase1(struct _prog *prog_data)
216 {
217 if(prog_data->players && prog_data->pile)
218 {
219 prog_data->pile = game_send(prog_data, 3, 12,
220 prog_data->pile);
221
222 prog_data->pile = game_send(prog_data, 2, 8,
223 prog_data->pile);
224
225 game_hand_position(prog_data, -1);
226 }
227 }
228
229 /* game_distribute_phase2 : send remaining card in
230 * the pile to the players. The card which was
231 * proposed is to be sent to the master player.
232 */
game_distribute_phase2(struct _prog * prog_data)233 void game_distribute_phase2(struct _prog *prog_data)
234 {
235 if(prog_data->players && prog_data->pile)
236 {
237 prog_data->pile = game_send(prog_data, 3, 12,
238 prog_data->pile);
239
240 if(prog_data->waiting)
241 {
242 struct _card *data_ptr = (struct _card*) prog_data->waiting->data;
243
244 if(prog_data->master != 2)
245 data_ptr->draw_face = FALSE;
246
247 data_ptr->moveable = FALSE;
248
249 throw_to(&prog_data->players[prog_data->master],
250 data_ptr);
251
252 prog_data->waiting = g_list_remove(prog_data->waiting,
253 data_ptr);
254 }
255
256 /*game_hand_position(prog_data, -1);*/
257 }
258 }
259
260 /* game_finish_phase1 : just take one card from
261 * the pile and put it on the top of the pile,
262 * with the value displayed to the user.
263 * This is the proposed trump card.
264 */
game_finish_phase1(struct _prog * prog_data)265 void game_finish_phase1(struct _prog *prog_data)
266 {
267 GList *pile = prog_data->pile;
268
269 if(pile != NULL)
270 {
271 struct _card *data_ptr = (struct _card*) pile->data;
272
273 throw_to(&prog_data->waiting,
274 data_ptr);
275
276 data_ptr->draw_face = TRUE;
277 data_ptr->moveable = TRUE;
278
279 if(prog_data->output)
280 {
281 fprintf(prog_data->output,
282 _("Proposed card is ") );
283 game_print_card(prog_data->output, data_ptr);
284 fprintf(prog_data->output, "\n");
285
286 }
287
288 prog_data->pile = g_list_remove(prog_data->pile,
289 data_ptr);
290 }
291 }
292
293 /* game_drop_middle: there should be four
294 * cards on the table when calling this
295 * function. It means we need to know
296 * what team wins the turn, and send
297 * all of those cards to the winner team
298 * list.
299
300 * Note: indeed the winner player of
301 * this turn has already been determined,
302 * it's the 'menext' value in struct _prog
303 * That's why we don't need to find the
304 * winner team here, we know it already
305 * (it's [menext MODULO 2])
306 */
game_drop_middle(struct _prog * prog_data)307 void game_drop_middle(struct _prog *prog_data)
308 {
309 struct _card *data_ptr;
310 GList *ptr;
311 int winner = -1;
312
313 if(prog_data->menext >= 0)
314 {
315 winner = prog_data->menext % 2;
316
317 if(prog_data->output != NULL)
318 {
319 fprintf(prog_data->output, _("Team %d"), winner);
320 if(winner == 0)
321 fprintf(prog_data->output, _("(0 = top, 2 = you)") );
322 else
323 fprintf(prog_data->output, _("(1 = right, 3 = left)") );
324 fprintf(prog_data->output, _(" wins this turn\n") );
325 }
326
327 ptr = prog_data->waiting;
328
329 while( ptr )
330 {
331 data_ptr = (struct _card *)ptr->data;
332
333 data_ptr->blink = FALSE;
334 data_ptr->draw = FALSE;
335
336 throw_to(&prog_data->teams[winner], data_ptr);
337
338 ptr = ptr->next;
339
340 }
341
342 g_list_free(prog_data->waiting);
343
344 prog_data->waiting = NULL;
345 }
346 else if(prog_data->output != NULL)
347 {
348 fprintf(prog_data->output,
349 _("Unable to check who win this turn.\n") );
350 }
351 }
352
game_middle_offset_static(int player,int * midx,int * midy,int size)353 void game_middle_offset_static(int player, int *midx, int *midy, int size)
354 {
355 switch(player)
356 {
357 case 0:
358 *midy -= size;
359 break;
360
361 case 1:
362 *midx += size;
363 break;
364
365 case 2:
366 *midy += size;
367 break;
368
369 case 3:
370 *midx -= size;
371 break;
372 }
373
374 }
375
game_middle_offset_dynamic(int player,int * midx,int * midy,int w,int h,int cardw,int cardh)376 void game_middle_offset_dynamic(int player, int *midx, int *midy,
377 int w, int h, int cardw, int cardh)
378 {
379 switch(player)
380 {
381 case 0:
382 /**midy = cardh + 20;*/
383 *midy -= cardh;
384 if(*midy < cardh + 10)
385 *midy += (cardh+10)-(*midy);
386 break;
387
388 case 1:
389 /**midx = w - 2*cardw - 20;*/
390 *midx += cardw;
391 break;
392
393 case 2:
394 /**midy = h - 2*cardh - 20;*/
395 *midy += cardh;
396 if(*midy+cardh > h - cardh - 10)
397 *midy -= (*midy+cardh)-(h-cardh-10);
398 break;
399
400 case 3:
401 /**midx = cardw + 20;*/
402 *midx -= cardw;
403 break;
404 }
405
406 }
407
408
409 /* game_position_middle : set the position (x,y)
410 * of a card on the table. Each card is
411 * positionned in relation to the player
412 * who dropped it.
413 */
game_position_middle(struct _card * card,struct _prog * prog_data,int player)414 void game_position_middle(struct _card *card,
415 struct _prog *prog_data,
416 int player)
417 {
418 int midx, midy;
419
420 midx = (prog_data->area->allocation.width - card->dim.w)/2;
421 midy = (prog_data->area->allocation.height - card->dim.h)/2;
422
423 game_middle_offset_dynamic(player, &midx, &midy,
424 prog_data->area->allocation.width,
425 prog_data->area->allocation.height,
426 card->dim.w, card->dim.h);
427
428 if(card->dim.x != midx || card->dim.y != midy)
429 {
430 if(prog_data->animation)
431 position_move_card(card, midx, midy, prog_data);
432
433
434 card->dim.x = midx;
435 card->dim.y = midy;
436 draw_container(prog_data);
437 }
438 }
439
440 /* game_print_family: that's in french atm,
441 * feel free to translate.
442 */
game_print_family(FILE * stream,int family)443 void game_print_family(FILE *stream, int family)
444 {
445 switch(family)
446 {
447 case 0:
448 fprintf(stream, _("diamond") );
449 break;
450 case 1:
451 fprintf(stream, _("spade") );
452 break;
453 case 2:
454 fprintf(stream, _("heart") );
455 break;
456 case 3:
457 fprintf(stream, _("club") );
458 break;
459 }
460
461 }
462
463 /* game_print_card: print the card as
464 * a nominative value.
465 * Example: ace of diamond
466 * Feel free to translate.
467 */
game_print_card(FILE * stream,struct _card * card)468 void game_print_card(FILE *stream, struct _card *card)
469 {
470 switch(card->num)
471 {
472 case 0:
473 fprintf(stream, _("ace") );
474 break;
475
476 case 6:
477 case 7:
478 case 8:
479 case 9:
480 fprintf(stream, "%d", card->num+1);
481 break;
482
483 case 10:
484 fprintf(stream, _("jack") );
485 break;
486
487 case 11:
488 fprintf(stream, _("queen") );
489 break;
490
491 case 12:
492 fprintf(stream, _("king") );
493 break;
494 }
495
496 fprintf(stream, _(" of ") );
497
498 game_print_family(stream, card->family);
499 }
500
501 /* game_get_family_best: what is the most
502 * powerfull card we get on a GList in
503 * a particular family only.
504 */
game_get_family_best(int family,GList * lst)505 int game_get_family_best(int family, GList *lst)
506 {
507 int nb = -1, i, best = 0;
508
509 struct _card *data;
510
511 for(i=0; lst; i++)
512 {
513
514 data = (struct _card*)lst->data;
515
516 if(data->family == family)
517 {
518 if(data->points > best)
519 {
520 best = data->points;
521 nb = i;
522 }
523 }
524
525 lst = lst->next;
526 }
527
528 return(nb);
529 }
530
game_find_card(int family,int num,GList * lst)531 gboolean game_find_card(int family, int num, GList *lst)
532 {
533 gboolean found = FALSE;
534 struct _card *data;
535
536 while(lst)
537 {
538 data = lst->data;
539
540 if(data->family == family
541 && data->num == num)
542 {
543 found = TRUE;
544 lst = NULL;
545 }
546 else
547 lst = lst->next;
548 }
549
550 return(found);
551 }
552
553 /* game_get_best: what is the most
554 * powerful card on a list, related
555 * to a family, but not only.
556 * If we found a trump card, it will
557 * probably be better than something
558 * else. That's what majorfamily is
559 * all about.
560 *
561 * Note: if the family value is -1,
562 * then the first card family is
563 * taken as a reference to find more
564 * powerfull cards. Don't forget
565 * that if majorfamily is set (other
566 * than -1), and if it's different
567 * than the value of family, any
568 * card of the majorfamily is better
569 * then the first card.
570 *
571 * That function is heavily used to
572 * find if a card dropped on the
573 * table is better than others.
574 *
575 * We just find what is the best
576 * card on the table. Then we check
577 * this card against the one to be
578 * dropped.
579 */
game_get_best(int * best,int * family,int majorfamily,GList * lst)580 struct _card* game_get_best(int *best, int *family,
581 int majorfamily, GList *lst)
582 {
583 struct _card *data, *first = NULL;
584
585 lst = g_list_last(lst);
586
587 while(lst)
588 {
589
590 data = (struct _card*)lst->data;
591
592 if(*family == -1)
593 {
594 first = data;
595 *best = data->points;
596 *family = data->family;
597 }
598 else
599 if(data->family == *family)
600 {
601 if(data->points > *best)
602 *best = data->points;
603 }
604 else
605 if(data->family == majorfamily)
606 {
607 *best = data->points;
608 *family = data->family;
609 }
610
611 lst = lst->prev;
612 }
613
614 return(first);
615 }
616
617 /* game_check_cardisbetter: check if a card
618 * is more powerfull than the most powerfull
619 * card on a GList
620 */
game_check_cardisbetter(struct _card * card,GList * lst,int majorfamily)621 gboolean game_check_cardisbetter(struct _card *card, GList *lst,
622 int majorfamily)
623 {
624 int best = 0, family = -1;
625 gboolean better = FALSE;
626
627 struct _card *first;
628
629 first = game_get_best(&best, &family, majorfamily, lst);
630
631 if(best > 0)
632 {
633 if(card->family == family)
634 {
635 if(card->points > best)
636 better = TRUE;
637 }
638 else if(card->family == majorfamily)
639 {
640 better = TRUE;
641 }
642 }
643
644 return(better);
645 }
646
game_card_get_ordered(int family,int trump)647 int *game_card_get_ordered(int family, int trump)
648 {
649 int *nums = (int*)g_malloc(sizeof(int)*8);
650
651 if(nums != NULL)
652 {
653 if(family == trump)
654 {
655 nums[0] = 6;
656 nums[1] = 7;
657 nums[2] = 11;
658 nums[3] = 12;
659 nums[4] = 9;
660 nums[5] = 0;
661 nums[6] = 8;
662 nums[7] = 10;
663 }
664 else
665 {
666 nums[0] = 6;
667 nums[1] = 7;
668 nums[2] = 8;
669 nums[3] = 10;
670 nums[4] = 11;
671 nums[5] = 12;
672 nums[6] = 9;
673 nums[7] = 0;
674 }
675 }
676 return nums;
677 }
678
game_card_is_best_remaining(struct _prog * prog_data,struct _card * card)679 gboolean game_card_is_best_remaining(struct _prog *prog_data, struct _card *card)
680 {
681 gboolean best = TRUE, list1, list2;
682 int num, i;
683
684 int *numequivalent;
685
686 numequivalent = game_card_get_ordered(card->family, prog_data->family);
687
688 if(numequivalent)
689 {
690 num = game_card_get_ordered_num(card, prog_data->family);
691
692 for(i = num+1; i < 8; i++)
693 {
694 list1 = game_find_card(card->family, numequivalent[i], prog_data->teams[0]);
695 list2 = game_find_card(card->family, numequivalent[i], prog_data->teams[1]);
696
697 if(!list1 && !list2)
698 {
699 i = 10;
700 best = FALSE;
701 }
702 else if (prog_data->output)
703 fprintf(prog_data->output, _("num(0,7): %d ; family %d\n"), i, card->family);
704 }
705
706 g_free(numequivalent);
707 }
708 else
709 best = FALSE;
710
711 return(best);
712 }
713
game_ia_choose_any(struct _prog * prog_data)714 struct _card* game_ia_choose_any(struct _prog *prog_data)
715 {
716 struct _card *data_ptr, *lowest = NULL, *besttrump=NULL;
717
718 GList *tmp;
719
720 int lowpts = 1000;
721
722 for(tmp = prog_data->players[prog_data->player];
723 tmp; tmp = tmp->next)
724 {
725 data_ptr = tmp->data;
726
727 if(data_ptr->points < lowpts &&
728 data_ptr->family != prog_data->family )
729 {
730 lowpts = data_ptr->points;
731 lowest = data_ptr;
732 }
733
734 if(data_ptr->family == prog_data->family
735 && (!besttrump || besttrump->points < data_ptr->points) )
736 {
737 besttrump = data_ptr;
738 }
739 }
740
741 if(!lowest)
742 {
743 if(game_card_is_best_remaining(prog_data, besttrump) )
744 lowest = besttrump;
745 else
746 {
747 tmp = prog_data->players[prog_data->player];
748 lowest = tmp->data;
749 }
750 }
751
752 return(lowest);
753 }
754
755
game_ia_choose_first(struct _prog * prog_data)756 struct _card* game_ia_choose_first(struct _prog *prog_data)
757 {
758 struct _card *card = NULL, *data_ptr, *lowest = NULL;
759
760 GList *tmp;
761
762 int lowpts = 1000;
763
764 if(prog_data->output)
765 fprintf(prog_data->output,
766 _("Player %d to start\n") ,
767 prog_data->player);
768
769 for(tmp = prog_data->players[prog_data->player];
770 tmp; tmp = tmp->next)
771 {
772 data_ptr = tmp->data;
773
774 if(data_ptr->points < lowpts)
775 {
776 lowpts = data_ptr->points;
777 lowest = data_ptr;
778 }
779
780 if(game_card_is_best_remaining(prog_data, data_ptr))
781 {
782 /* TODO: need to check if this is a trump
783 * and there are no trump left on other
784 * players, then advice what to do. */
785 if(prog_data->output)
786 fprintf(prog_data->output,
787 _("This is the best of this family: num%d family%d points%d \n"),
788 data_ptr->num, data_ptr->family, data_ptr->points);
789
790 card = data_ptr;
791 }
792 }
793
794 if(!card)
795 card = lowest;
796
797 return card;
798 }
799
game_get_cards(GList * from,int family,int betterthan)800 GList *game_get_cards(GList *from, int family, int betterthan)
801 {
802 GList *tmp;
803 GList *to = NULL;
804 struct _card *card;
805
806 for(tmp = from; tmp; tmp = tmp->next)
807 {
808 card = tmp->data;
809
810 if(card->family == family &&
811 card->points > betterthan )
812 to = g_list_prepend(to, (gpointer) card);
813 }
814
815 return(to);
816 }
817
get_card_num_trump(int num)818 int get_card_num_trump(int num)
819 {
820 switch(num)
821 {
822 case 10:
823 num = 7;
824 break;
825
826 case 8:
827 num = 6;
828 break;
829
830 case 0:
831 num = 5;
832 break;
833
834 case 9:
835 num = 4;
836 break;
837
838 case 11:
839 case 12:
840 num -= 9;
841 break;
842
843 case 6:
844 case 7:
845 num -= 6;
846 break;
847 }
848
849 return(num);
850 }
851
get_card_num_nottrump(int num)852 int get_card_num_nottrump(int num)
853 {
854 if(num > 9)
855 num -= 7;
856 else if(num == 9)
857 num = 6;
858 else if(num == 0)
859 num = 7;
860 else
861 num -= 6;
862
863 return(num);
864 }
865
game_card_get_ordered_num(struct _card * card,int family)866 int game_card_get_ordered_num(struct _card *card, int family)
867 {
868 int num;
869
870 if(card->family == family)
871 {
872 num = get_card_num_trump(card->num);
873 }
874 else
875 {
876 num = get_card_num_nottrump(card->num);
877 }
878
879 return(num);
880 }
881
game_ia_choose_last_or_first(GList * from,struct _prog * prog_data)882 struct _card* game_ia_choose_last_or_first(GList *from, struct _prog *prog_data)
883 {
884 struct _card *theone = NULL, *first = g_list_first(prog_data->waiting)->data;
885
886 gboolean best = FALSE;
887
888 int n = g_list_length(prog_data->waiting);
889
890 theone = g_list_last(from)->data;
891
892 if(theone)
893 best = game_card_is_best_remaining(prog_data, theone);
894
895 switch(n)
896 {
897 case 1:
898 if(theone->family != first->family)
899 {
900 if(best)
901 theone = g_list_first(from)->data;
902 }
903 else
904 if(!best)
905 theone = g_list_first(from)->data;
906 break;
907
908 case 2:
909 if(theone->family != first->family)
910 {
911 if(best == TRUE || game_check_cardisbetter(theone,
912 prog_data->waiting,
913 prog_data->family) == FALSE)
914 theone = g_list_first(from)->data;
915 }
916 else
917 /* We don't have the best card */
918 if(best == FALSE)
919 {
920 best = game_card_is_best_remaining(prog_data, first);
921
922 if(best == FALSE)
923 theone = g_list_first(from)->data;
924 }
925 else
926 {
927 best = game_check_cardisbetter(theone, prog_data->waiting,
928 prog_data->family);
929
930 if(!best)
931 theone = g_list_first(from)->data;
932 }
933 break;
934
935 case 3:
936 /* We need to drop a trump on a non-trump hand */
937 if(theone->family != first->family)
938 {
939 /* If we have the best of remaining trumps,
940 * then play the lowest allowed trump we have.
941 * That means we win the hand anyway. */
942 if(best)
943 theone = g_list_first(from)->data;
944 /* Otherwise play the best trump we have. */
945 }
946 else
947 {
948 best = game_check_cardisbetter(theone, prog_data->waiting,
949 prog_data->family);
950
951 if(best == FALSE && prog_data->menext%2 != prog_data->player%2)
952 theone = g_list_first(from)->data;
953 }
954 break;
955
956 }
957
958 return(theone);
959 }
960
game_get_valid_cards(struct _prog * prog_data)961 GList * game_get_valid_cards(struct _prog *prog_data)
962 {
963 GList *good = NULL;
964 gboolean trumpforce;
965
966 int best = 0, family = -1;
967 struct _card *first = NULL;
968
969 first = game_get_best(&best, &family,
970 prog_data->family,
971 prog_data->waiting);
972
973 if(first && first->family >= 0)
974 {
975 if(prog_data->output)
976 fprintf(prog_data->output,
977 _("player %d, trump %d, family of the first card: %d\n"),
978 prog_data->player,
979 prog_data->family,
980 first->family);
981
982 /* Get a list of cards allowed to
983 * be dropped by the rules.
984 * The first card is not a trump one. */
985 if(first->family != prog_data->family)
986 {
987 good = game_get_cards(prog_data->players[prog_data->player],
988 first->family, 0);
989
990 if(good && prog_data->output)
991 fprintf(prog_data->output, _("Not a trump card\n") );
992 }
993
994 if(good == NULL)
995 {
996 trumpforce = first->family == prog_data->family ||
997 prog_data->menext%2!= prog_data->player%2;
998 /* We must play a trump card,
999 * because we don't have any
1000 * card from the first card
1001 * family, or the first card
1002 * family is a trump one. */
1003 if(family == prog_data->family && trumpforce == TRUE)
1004 {
1005 /* The best card is a trump card,
1006 * we must play bigger */
1007 good = game_get_cards(prog_data->players[prog_data->player],
1008 family, best);
1009
1010 if(good && prog_data->output)
1011 fprintf(prog_data->output, _("A bigger trump\n") );
1012 }
1013
1014 if(!good && trumpforce == TRUE )
1015 {
1016 /* we don't have any bigger
1017 * trump or don't have to
1018 * play bigger, drop any
1019 * trump */
1020 good = game_get_cards(prog_data->players[prog_data->player],
1021 prog_data->family, 0);
1022
1023 if(good && prog_data->output)
1024 fprintf(prog_data->output, _("A lower trump\n") );
1025 }
1026
1027 }
1028
1029 }
1030
1031 return(good);
1032 }
1033
1034
1035 /* game_ia_select_card: what the computer should
1036 * play. This is where every decision should be
1037 * made.
1038 *
1039 *
1040 * Note: the rules of the game should be excluded
1041 * from here and put on another function, because
1042 * the human player is also affected by the rules.
1043 * --Need to be Fixed--
1044 */
game_ia_select_card(struct _prog * prog_data)1045 struct _card* game_ia_select_card(struct _prog *prog_data)
1046 {
1047 int nb=0;
1048
1049 struct _card *theone = NULL;
1050
1051 GList *good = NULL;
1052
1053
1054 if(prog_data->waiting != NULL)
1055 {
1056 good = game_get_valid_cards(prog_data);
1057
1058 if(good)
1059 {
1060 good = g_list_sort(good, list_sort);
1061
1062 theone = game_ia_choose_last_or_first(good, prog_data);
1063
1064 g_list_free(good);
1065 }
1066 else
1067 {
1068 /* Any card is good */
1069 if(prog_data->output)
1070 fprintf(prog_data->output, _("Anything\n") );
1071
1072 theone = game_ia_choose_any(prog_data);
1073
1074 }
1075
1076 }
1077 else
1078 {
1079 theone = game_ia_choose_first(prog_data);
1080 }
1081
1082
1083 return(theone);
1084 }
1085
1086 /* game_start: makes the main list
1087 * of cards, called the pile.
1088 * That's where we take care of
1089 * preparing that pile and the
1090 * status of each card before
1091 * starting a new round.
1092 */
game_start(struct _prog * prog_data)1093 void game_start(struct _prog *prog_data)
1094 {
1095 int i;
1096
1097 for(i = 0; i<2; i++)
1098 prog_data->declarations[i] = 0;
1099
1100 throw_card_list( prog_data->all );
1101
1102 throw_cards(prog_data);
1103
1104 prog_data->state = READY_PILE;
1105
1106 prog_data->turn = 8;
1107
1108 gtk_button_set_label(GTK_BUTTON(prog_data->allwidgets[2]),
1109 _("Start") );
1110
1111 gtk_image_set_from_pixbuf(GTK_IMAGE(prog_data->allwidgets[5]),
1112 prog_data->icons[4]);
1113
1114 gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[7]), _("N/a") );
1115 gtk_label_set_text( GTK_LABEL(prog_data->allwidgets[8]), _("None") );
1116
1117 gtk_label_set_text(
1118 GTK_LABEL(prog_data->allwidgets[18]), NULL);
1119
1120 gtk_label_set_text(
1121 GTK_LABEL(prog_data->allwidgets[19]), NULL);
1122
1123 gtk_label_set_text( GTK_LABEL(prog_data->allwidgets[3]), NULL);
1124 gtk_label_set_text( GTK_LABEL(prog_data->allwidgets[4]), NULL);
1125
1126 gtk_label_set_text( GTK_LABEL(prog_data->allwidgets[20]), NULL);
1127 gtk_label_set_text( GTK_LABEL(prog_data->allwidgets[21]), NULL);
1128
1129 gtk_widget_set_sensitive(prog_data->allwidgets[2], TRUE);
1130
1131 for(i =0; i< 4; i++)
1132 gtk_widget_set_sensitive(prog_data->allwidgets[10+i], FALSE);
1133 }
1134
game_points_carre(int num)1135 int game_points_carre(int num)
1136 {
1137 int points = 0;
1138
1139 switch(num)
1140 {
1141 case 12:
1142 case 11:
1143 case 9:
1144 case 0:
1145 points = 100;
1146 break;
1147
1148 case 10:
1149 points = 200;
1150 break;
1151
1152 case 8:
1153 points = 150;
1154 break;
1155
1156 }
1157
1158 return(points);
1159 }
1160
game_check_carre(GList * lst,int num)1161 int game_check_carre(GList *lst, int num)
1162 {
1163 int points = 0, i;
1164
1165 for(i=0;lst;lst = lst->next)
1166 {
1167 if( ((struct _card *)lst->data)->num == num )
1168 i++;
1169 }
1170
1171 if(i == 4)
1172 {
1173 points = game_points_carre(num);
1174 }
1175
1176 return(points);
1177 }
1178
game_check_sequence_valid(GList ** plst,int cards,int higher,int family)1179 void game_check_sequence_valid(GList **plst, int cards, int higher, int family)
1180 {
1181 struct _sequence *sequence = NULL;
1182
1183 if(cards > 2)
1184 {
1185 sequence = (struct _sequence *)g_malloc(sizeof(struct _sequence) );
1186
1187 if(sequence)
1188 {
1189 sequence->hinum = higher;
1190 sequence->family = family;
1191
1192 if(cards >= 5)
1193 {
1194 sequence->points = 100;
1195 }
1196 else
1197 if(cards == 4)
1198 sequence->points = 50;
1199 else
1200 sequence->points = 20;
1201
1202 *plst = g_list_prepend(*plst, (gpointer) sequence);
1203
1204
1205 /* a sequence of 8 cards is counted as a
1206 * quint (five cards) and a tierce (three) */
1207 if(cards == 8)
1208 {
1209 struct _sequence *onemore = (struct _sequence *)
1210 g_malloc(sizeof(struct _sequence) );
1211
1212 if(onemore)
1213 {
1214 onemore->hinum = higher-5;
1215 onemore->family = family;
1216 onemore->points = 20;
1217 *plst = g_list_prepend(*plst, (gpointer) onemore);
1218 }
1219 }
1220 }
1221 }
1222
1223
1224 }
1225
game_check_sequence(GList * lst,GList ** seqlist)1226 void game_check_sequence(GList *lst, GList **seqlist)
1227 {
1228 int bits[4][8] = { {0} }, num;
1229
1230 struct _card *data;
1231
1232 for(;lst; lst=lst->next)
1233 {
1234 data = lst->data;
1235
1236 if(data->num == 0)
1237 num = 7;
1238 else
1239 num = data->num-6;
1240
1241 bits[data->family][num] = 1;
1242 }
1243
1244 int i, j, cards, higher;
1245
1246 for(j = 0; j < 4; j++)
1247 {
1248 cards = 0;
1249 higher = 0;
1250
1251 for(i = 7; i>= 0; i--)
1252 {
1253 if(bits[j][i] == 1)
1254 {
1255 if(i > higher)
1256 higher = i;
1257
1258 cards++;
1259 }
1260 else
1261 {
1262 game_check_sequence_valid(seqlist, cards, higher, j);
1263
1264 higher = 0;
1265 cards = 0;
1266 }
1267 }
1268
1269 game_check_sequence_valid(seqlist, cards, higher, j);
1270 }
1271
1272 }
1273
game_check_carre_x(GList ** players,int num)1274 int game_check_carre_x(GList **players, int num)
1275 {
1276 int i;
1277
1278 for(i = 0; i< 4; i++)
1279 {
1280 if(game_check_carre(players[i], num) > 0)
1281 return(i);
1282 }
1283
1284 return(-1);
1285 }
1286
game_show_seqcards(GList * seqlist,GList * player)1287 void game_show_seqcards(GList *seqlist, GList *player)
1288 {
1289 GList *tmp;
1290
1291 struct _sequence *data;
1292
1293 int ncards, i, num, cardnum;
1294
1295 for(tmp = seqlist; tmp; tmp = tmp->next)
1296 {
1297 data = (struct _sequence*) tmp->data;
1298
1299 switch(data->points)
1300 {
1301 case 20:
1302 ncards = 3;
1303 break;
1304
1305 case 50:
1306 ncards = 4;
1307 break;
1308
1309 case 100:
1310 ncards = 5;
1311 break;
1312
1313 default:
1314 ncards = 0;
1315 }
1316
1317 num = data->hinum + 6;
1318
1319 for(i = 0; i < ncards; i++)
1320 {
1321 if(num-i == 13)
1322 cardnum = 0;
1323 else
1324 cardnum = num-i;
1325
1326 set_draw_face_x(player, TRUE, data->family, cardnum);
1327 }
1328 }
1329 }
1330
game_check_declarations(struct _prog * prog_data)1331 void game_check_declarations(struct _prog *prog_data)
1332 {
1333
1334 int p, points[4] = {0}, bestteam = -1;
1335
1336 /* Four Jacks */
1337 p = game_check_carre_x(prog_data->players, 10);
1338
1339 if(p > -1)
1340 {
1341 if(bestteam == -1)
1342 bestteam = p%2;
1343
1344 if(prog_data->output)
1345 fprintf(prog_data->output,
1346 _("Four Jacks (%d)\n"), p);
1347 points[p] += game_points_carre(10);
1348
1349 if(bestteam == p%2)
1350 set_show_carre(prog_data->players[p], TRUE, 10);
1351 }
1352
1353 /* Four Nines */
1354 p = game_check_carre_x(prog_data->players, 8);
1355
1356 if(p > -1)
1357 {
1358 if(bestteam == -1)
1359 bestteam = p%2;
1360
1361 if(prog_data->output)
1362 fprintf(prog_data->output,
1363 _("Quads of Nines (%d)\n"), p);
1364 points[p] += game_points_carre(8);
1365
1366 if(bestteam == p%2)
1367 set_show_carre(prog_data->players[p], TRUE, 8);
1368 }
1369
1370 /* Four Aces */
1371 p = game_check_carre_x(prog_data->players, 0);
1372
1373 if(p > -1)
1374 {
1375 if(bestteam == -1)
1376 bestteam = p%2;
1377
1378 if(prog_data->output)
1379 fprintf(prog_data->output,
1380 _("Quads of Aces (%d)\n"), p);
1381 points[p] += game_points_carre(0);
1382
1383 if(bestteam == p%2)
1384 set_show_carre(prog_data->players[p], TRUE, 0);
1385 }
1386
1387 /* Four Kings */
1388 p = game_check_carre_x(prog_data->players, 12);
1389
1390 if(p > -1)
1391 {
1392 if(bestteam == -1)
1393 bestteam = p%2;
1394
1395 if(prog_data->output)
1396 fprintf(prog_data->output,
1397 _("Quads of Kings (%d)\n"), p);
1398 points[p] += game_points_carre(12);
1399
1400 if(bestteam == p%2)
1401 set_show_carre(prog_data->players[p], TRUE, 12);
1402 }
1403
1404 /* Four Queens */
1405 p = game_check_carre_x(prog_data->players, 11);
1406
1407 if(p > -1)
1408 {
1409 if(bestteam == -1)
1410 bestteam = p%2;
1411
1412 if(prog_data->output)
1413 fprintf(prog_data->output,
1414 _("Quads of Queens (%d)\n"), p);
1415 points[p] += game_points_carre(11);
1416
1417 if(bestteam == p%2)
1418 set_show_carre(prog_data->players[p], TRUE, 11);
1419 }
1420
1421 /* Four Tens */
1422 p = game_check_carre_x(prog_data->players, 9);
1423
1424 if(p > -1)
1425 {
1426 if(bestteam == -1)
1427 bestteam = p%2;
1428
1429 if(prog_data->output)
1430 fprintf(prog_data->output,
1431 _("Quads of Tens (%d)\n"), p);
1432 points[p] += game_points_carre(9);
1433
1434 if(bestteam == p%2)
1435 set_show_carre(prog_data->players[p], TRUE, 9);
1436 }
1437
1438
1439 /* List of sequences now */
1440
1441 GList *seqlist[4] = {NULL};
1442 int i;
1443
1444 for(i = 0; i<4; i++)
1445 game_check_sequence(prog_data->players[i], &seqlist[i]);
1446
1447 /* Check results */
1448 GList *tmp;
1449 struct _sequence *data;
1450 int bestpoints=0, bestseqfamily = -1, higher = 0, tmpteam = -1;
1451
1452 for(i=0; i<4 ; i++)
1453 {
1454 for(tmp = seqlist[i]; tmp; tmp = tmp->next)
1455 {
1456 data = (struct _sequence*) tmp->data;
1457
1458 if(prog_data->output)
1459 {
1460 fprintf(prog_data->output,
1461 _("Player %d has a straight (points: %d, color: %d, higher: %d)\n"),
1462 i, data->points, data->family, data->hinum);
1463 }
1464
1465 points[i] += data->points;
1466
1467 if(data->points > bestpoints)
1468 {
1469 bestpoints = data->points;
1470 bestseqfamily = data->family;
1471 tmpteam = i%2;
1472 higher = data->hinum;
1473 }
1474 else if(data->points == bestpoints)
1475 {
1476 if(data->hinum > higher)
1477 {
1478 higher = data->hinum;
1479 bestseqfamily = data->family;
1480 tmpteam = i%2;
1481 }
1482 else if(data->hinum == higher)
1483 {
1484 /* Higher Trump */
1485 if(data->family == prog_data->family)
1486 {
1487 bestpoints = data->points;
1488 bestseqfamily = data->family;
1489 tmpteam = i%2;
1490 }
1491 /* Equality canceled */
1492 else if(tmpteam == !(i%2))
1493 tmpteam = -1;
1494 }
1495 }
1496
1497 }
1498 }
1499
1500 if(bestteam!=-1)
1501 tmpteam = bestteam;
1502
1503 if(tmpteam !=-1)
1504 {
1505 char text[10];
1506
1507 prog_data->declarations[tmpteam] = points[tmpteam] + points[tmpteam+2];
1508
1509 g_sprintf(text, "+%d", prog_data->declarations[tmpteam]);
1510
1511 gtk_label_set_text(
1512 GTK_LABEL(prog_data->allwidgets[18 + tmpteam]),
1513 text);
1514
1515 if(prog_data->output)
1516 fprintf(prog_data->output,
1517 _("Team %d has the best declaration(s)\n"),
1518 tmpteam);
1519
1520 prog_data->hide = TRUE;
1521
1522 if(tmpteam == 0)
1523 game_show_seqcards(seqlist[0], prog_data->players[0]);
1524 else
1525 {
1526 game_show_seqcards(seqlist[1], prog_data->players[1]);
1527 game_show_seqcards(seqlist[3], prog_data->players[3]);
1528 }
1529 }
1530
1531 /* Clear all */
1532
1533 for(i = 0; i< 4; i++)
1534 {
1535 free_generic_list(&seqlist[i]);
1536
1537 }
1538 }
1539
1540 /* game_totalcards: calculate the
1541 * total value of points in a GList.
1542 */
game_totalcards(GList * lst)1543 int game_totalcards(GList *lst)
1544 {
1545 int total = 0;
1546
1547 struct _card *data;
1548
1549 while(lst)
1550 {
1551 data = lst->data;
1552
1553 /* Warning: the points value of cards
1554 * are not set to the real value
1555 * of the card in the game, but at
1556 * a more powerfull value.
1557 * The real value is [value/10] */
1558 total += data->points/10;
1559
1560 lst = lst->next;
1561 }
1562
1563 return(total);
1564 }
1565
1566 /* game_restart: reset state and int values
1567 * of the game before each new rounds.
1568 */
game_restart(struct _prog * prog_data)1569 void game_restart(struct _prog *prog_data)
1570 {
1571 prog_data->state = LOADING;
1572 prog_data->player = -1;
1573 prog_data->master = -1;
1574 prog_data->family = -1;
1575
1576 prog_data->hashand = -1;
1577 prog_data->menext = -1;
1578
1579 prog_data->belote = -1;
1580
1581
1582 }
1583
1584 /* game_turn: so complicated.
1585 * --Need to be simplified--
1586 */
game_turn(struct _prog * prog_data,struct _card * card)1587 void game_turn(struct _prog *prog_data, struct _card *card)
1588 {
1589 int cardnb;
1590
1591 if(prog_data->player == prog_data->hashand)
1592 {
1593 if(prog_data->waiting != NULL)
1594 {
1595 char str[10];
1596
1597 if(prog_data->output)
1598 fprintf(prog_data->output, _("dropping the cards on the middle\n") );
1599
1600 clear_blink(prog_data);
1601
1602 g_sprintf(str, "%d/8", (9-prog_data->turn) );
1603
1604 gtk_label_set_text(
1605 GTK_LABEL(prog_data->allwidgets[8]), str);
1606
1607 game_drop_middle(prog_data);
1608
1609 g_sprintf(str, "%d", game_totalcards(prog_data->teams[0]) );
1610
1611 gtk_label_set_text( GTK_LABEL(prog_data->allwidgets[20]), str);
1612
1613 g_sprintf(str, "%d", game_totalcards(prog_data->teams[1]) );
1614
1615 gtk_label_set_text( GTK_LABEL(prog_data->allwidgets[21]), str);
1616
1617 if(prog_data->menext >= 0)
1618 {
1619 prog_data->hashand = prog_data->menext;
1620 prog_data->player = prog_data->menext;
1621 }
1622 }
1623 }
1624
1625 if(prog_data->turn > 0)
1626 {
1627 if(card == NULL && prog_data->player != 2)
1628 {
1629 card = game_ia_select_card(prog_data);
1630
1631 }
1632
1633
1634
1635 if(card != NULL)
1636 {
1637 if(prog_data->output != NULL)
1638 {
1639 fprintf(prog_data->output,
1640 _("Player %d drop card "),
1641 prog_data->player);
1642 game_print_card(prog_data->output, card);
1643 fprintf(prog_data->output, "\n");
1644 }
1645
1646 if(prog_data->waiting != NULL
1647 && game_check_cardisbetter(card, prog_data->waiting,
1648 prog_data->family))
1649 {
1650 if(prog_data->output != NULL)
1651 fprintf(prog_data->output,
1652 _("Player %d has the hand\n"),
1653 prog_data->player);
1654
1655 prog_data->menext = prog_data->player;
1656 }
1657
1658 throw_to(&prog_data->waiting, card);
1659
1660 card->draw_face = TRUE;
1661 card->moveable = FALSE;
1662
1663 if(card->family == prog_data->family)
1664 {
1665 if(card->points == 40)
1666 {
1667 /* Look for the trump queen,
1668 * because this player just dropped
1669 * the trump king.
1670 * If he got both, then it's a "Belote"
1671 * and 20 points goes to the team. */
1672 if(game_find_card(card->family, 11,
1673 prog_data->players[prog_data->player]) == TRUE)
1674 {
1675 gtk_label_set_text( GTK_LABEL(
1676 prog_data->allwidgets[3+(prog_data->player%2)]),
1677 "+20");
1678 gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[6]),
1679 _("Belote!"));
1680
1681 prog_data->belote = prog_data->player;
1682 }
1683 }
1684 else
1685 if(card->points == 30)
1686 {
1687 if( prog_data->belote == prog_data->player)
1688 gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[6]),
1689 _("Rebelote!"));
1690
1691 }
1692 }
1693
1694 prog_data->players[prog_data->player] = g_list_remove(
1695 prog_data->players[prog_data->player],
1696 (gconstpointer) card);
1697
1698 game_hand_position(prog_data, prog_data->player);
1699
1700
1701
1702 game_position_middle(card, prog_data, prog_data->player);
1703
1704 select_player_next(&prog_data->player);
1705
1706 if(prog_data->player == 2)
1707 {
1708 set_player_hand_moveable(prog_data);
1709 }
1710 else
1711 {
1712 set_moveable(prog_data->players[2], FALSE);
1713 }
1714
1715 if(prog_data->player == prog_data->hashand)
1716 {
1717 struct _card *card = NULL;
1718 int player;
1719 int i;
1720
1721 if(prog_data->menext == 2)
1722 {
1723 set_moveable(prog_data->players[2], TRUE);
1724 }
1725 else
1726 {
1727 set_moveable(prog_data->players[2], FALSE);
1728 }
1729
1730 if(prog_data->waiting)
1731 {
1732
1733 /* now find the number of the card (from 0 to 3)
1734 * which is the best card in the list.
1735 * This is pretty hard to know :
1736 * Get the player who dropped the first
1737 * card and increment i till player == menext
1738 * Because menext is the winner player
1739 * of this turn. */
1740
1741 player = prog_data->hashand;
1742 select_player_prev(&player);
1743 if(prog_data->output)
1744 fprintf(prog_data->output,
1745 "hashand %d, menext %d\n", prog_data->hashand, prog_data->menext);
1746 for(i = 0; player != prog_data->menext ; i++)
1747 {
1748 select_player_prev(&player);
1749 }
1750
1751 card = throw_card_x(prog_data->waiting, i);
1752
1753 if(card && !prog_data->copy)
1754 {
1755 card->blink = TRUE;
1756 card->draw = FALSE;
1757
1758 draw_copy(prog_data);
1759
1760 prog_data->blinkid = g_timeout_add(800,
1761 event_blink, (gpointer)prog_data);
1762 }
1763
1764
1765 }
1766
1767 prog_data->turn--;
1768
1769 if(prog_data->turn <= 0)
1770 {
1771 gtk_widget_set_sensitive(prog_data->allwidgets[2], TRUE);
1772 gtk_button_set_label(GTK_BUTTON(prog_data->allwidgets[2]), "Finish");
1773 }
1774 }
1775 }
1776 }
1777 else
1778 {
1779 int Pts[2];
1780 char str[5];
1781 GtkWidget *cell;
1782 int masterteam = prog_data->master%2;
1783
1784 prog_data->state = ENDGAME;
1785
1786 set_moveable(prog_data->players[2], FALSE);
1787
1788 Pts[0] = game_totalcards(prog_data->teams[0]);
1789 Pts[1] = game_totalcards(prog_data->teams[1]);
1790
1791 /* Belote */
1792 if( prog_data->belote != -1 )
1793 {
1794 if(prog_data->output != NULL)
1795 fprintf(prog_data->output, _("Team %d wins 20 points for Belote/Rebelote\n"),
1796 (prog_data->belote%2));
1797 Pts[prog_data->belote%2] += 20;
1798 }
1799
1800
1801 /* Declarations */
1802 if(prog_data->withdeclaration == TRUE)
1803 {
1804 if(prog_data->output)
1805 {
1806 fprintf(prog_data->output,
1807 _("Your team wins %d points for declarations\n"), prog_data->declarations[0]);
1808 fprintf(prog_data->output,
1809 _("The other team wins %d points for declarations\n"), prog_data->declarations[1]);
1810 }
1811 if(Pts[0] > 0)
1812 Pts[0] += prog_data->declarations[0];
1813 if(Pts[1] > 0)
1814 Pts[1] += prog_data->declarations[1];
1815 }
1816
1817 /* Final turn winner's team wins Ten points */
1818 Pts[prog_data->menext%2] += 10;
1819
1820 if(prog_data->output != NULL)
1821 {
1822 fprintf(prog_data->output,
1823 _("Total: [0,2] %d (your) versus (them) %d [1,3]\n"),
1824 Pts[0],
1825 Pts[1]);
1826
1827 fprintf(prog_data->output,
1828 _("master was %d, menext is %d\n"),
1829 (prog_data->master),
1830 prog_data->menext );
1831 }
1832
1833 int Totals[2]={Pts[0], Pts[1]};
1834
1835 Pts[0] = (int)roundf(Pts[0]/(float)10);
1836 Pts[1] = (int)roundf(Pts[1]/(float)10);
1837
1838
1839 if(Totals[masterteam] >= Totals[!masterteam])
1840 {
1841 /* Points of the master team are reported */
1842 if(Totals[masterteam] == Totals[!masterteam])
1843 {
1844 if(prog_data->output)
1845 {
1846 fprintf(prog_data->output,
1847 _("Equality. Points of the master team(%d) are reported.\n%d points, (%d total)\n"),
1848 prog_data->master,
1849 Pts[masterteam],
1850 prog_data->report);
1851 }
1852
1853 prog_data->report += Pts[masterteam];
1854
1855 Pts[masterteam] = 0;
1856 }
1857
1858 /* If the other team is Capot! */
1859 if(Pts[!masterteam] == 0)
1860 {
1861 Pts[masterteam] += 9 +prog_data->report ;
1862
1863 prog_data->report = 0;
1864 }
1865 }
1866 /* Couille ! */
1867 else
1868 {
1869 /* Do we have to add all the points to the winning team,
1870 * even the "Belote/Rebelote" thing ?*/
1871 Pts[!masterteam] += prog_data->report +
1872 Pts[masterteam];
1873
1874 Pts[masterteam] = 0;
1875 prog_data->report = 0;
1876 }
1877
1878 prog_data->points[0] += Pts[0];
1879 prog_data->points[1] += Pts[1];
1880
1881 prog_data->row++;
1882
1883 gtk_table_resize(GTK_TABLE(prog_data->allwidgets[9]),
1884 prog_data->row, 2);
1885
1886 g_sprintf(str, "%d", prog_data->points[0]);
1887 cell = gtk_label_new(str);
1888
1889 prog_data->cells = g_list_prepend(prog_data->cells,
1890 (gpointer) cell );
1891
1892 gtk_table_attach_defaults(GTK_TABLE(prog_data->allwidgets[9]),
1893 cell,
1894 0, 1, prog_data->row-1, prog_data->row);
1895
1896 g_sprintf(str, "%d", prog_data->points[1]);
1897 cell = gtk_label_new(str);
1898
1899 prog_data->cells = g_list_prepend(prog_data->cells,
1900 (gpointer) cell );
1901
1902 gtk_table_attach_defaults(GTK_TABLE(prog_data->allwidgets[9]),
1903 cell,
1904 1, 2, prog_data->row-1, prog_data->row);
1905
1906 GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(
1907 GTK_SCROLLED_WINDOW(prog_data->allwidgets[1]) );
1908
1909 gtk_adjustment_set_value(adjustment,
1910 adjustment->upper);
1911
1912 if(Pts[0] > Pts[1])
1913 gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[6]), "You Win");
1914 else
1915 gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[6]), "Computer Wins");
1916
1917
1918 gtk_widget_show_all(prog_data->allwidgets[0]);
1919
1920 if((prog_data->points[0] > 100 || prog_data->points[1] > 100)
1921 && prog_data->points[0] != prog_data->points[1])
1922 {
1923 GtkWidget *dialog;
1924 char winstr[50];
1925
1926 if(prog_data->points[0] > prog_data->points[1])
1927 g_stpcpy(winstr, _("Congratulation, you won this game!"));
1928 else
1929 g_stpcpy(winstr, _("Sorry, you have lost this game!"));
1930
1931 if(prog_data->output)
1932 fprintf(prog_data->output,
1933 _("\nEnd of the game !!\n\n\n"));
1934
1935 dialog = gtk_message_dialog_new(
1936 GTK_WINDOW(prog_data->allwidgets[0]),
1937 GTK_DIALOG_MODAL,
1938 GTK_MESSAGE_INFO,
1939 GTK_BUTTONS_CLOSE,
1940 winstr, NULL);
1941
1942 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(dialog_response_event), prog_data);
1943
1944 gtk_widget_show_all(dialog);
1945
1946 }
1947
1948
1949
1950 if(prog_data->allwidgets && prog_data->allwidgets[5])
1951 {
1952 if(gtk_image_get_pixbuf(GTK_IMAGE(prog_data->allwidgets[5])))
1953 gtk_image_clear(GTK_IMAGE(prog_data->allwidgets[5]) );
1954 }
1955 gtk_label_set_text( GTK_LABEL(prog_data->allwidgets[8]), "None");
1956 free_clear(prog_data);
1957 game_restart(prog_data);
1958 game_start(prog_data);
1959
1960 }
1961 }
1962
game_count_cards(GList * lst,int family,int * pointstrump,int * pointsnottrump,int * counttrump,int * countnottrump,int * best)1963 void game_count_cards(GList *lst, int family,
1964 int *pointstrump, int *pointsnottrump,
1965 int *counttrump, int *countnottrump,
1966 int *best)
1967 {
1968 struct _card *card;
1969 int points;
1970
1971 while(lst)
1972 {
1973 card = (struct _card *)lst->data;
1974
1975 if( card->family == family)
1976 {
1977 points = set_master_points(card->num);
1978 if(points > *best)
1979 *best = points;
1980 *pointstrump += points;
1981 (*counttrump)++;
1982 }
1983 else
1984 {
1985 *pointsnottrump += set_notmaster_points(card->num);
1986 (*countnottrump)++;
1987 }
1988
1989 lst = lst->next;
1990 }
1991
1992 }
1993
game_ia_select_second(struct _prog * prog_data,int player,int * family)1994 gboolean game_ia_select_second(struct _prog *prog_data, int player, int *family)
1995 {
1996 gboolean select = FALSE;
1997 struct _card *card = ((struct _card*)prog_data->waiting->data);
1998 int pointstrump = 0, pointsnottrump = 0,
1999 counttrump = 0, countnottrump = 0, best = 0, i;
2000
2001 for(i=0; i<4; i++)
2002 {
2003 if(i != card->family)
2004 {
2005 pointstrump = 0;
2006 pointsnottrump = 0;
2007 counttrump = 0;
2008 countnottrump = 0;
2009 best = 0;
2010
2011 game_count_cards(prog_data->players[player],
2012 i, &pointstrump, &pointsnottrump,
2013 &counttrump, &countnottrump, &best);
2014
2015 if(counttrump > 1)
2016 {
2017 pointsnottrump += set_notmaster_points(card->num);
2018
2019 /* from 140 to 225
2020 * lesser means more crazyness */
2021 if(pointstrump >= 225)
2022 {
2023 if(prog_data->output)
2024 fprintf(prog_data->output, "Player %d is susceptible to choose the family %d [%d, %d]\n", prog_data->player, i, pointsnottrump, pointstrump);
2025
2026 if( pointsnottrump+pointstrump > 270
2027 && (pointsnottrump/countnottrump) + (pointstrump/counttrump) >= 60
2028 && best >= 110)
2029 {
2030 *family = i;
2031 select = TRUE;
2032 i = 3;
2033 }
2034 }
2035 }
2036 }
2037 }
2038
2039
2040 return(select);
2041 }
2042 /*
2043 */
game_ia_select_trump(struct _prog * prog_data,int player)2044 gboolean game_ia_select_trump(struct _prog *prog_data, int player)
2045 {
2046 gboolean select = FALSE;
2047 struct _card *card = ((struct _card*)prog_data->waiting->data);
2048 int pointstrump = 0, pointsnottrump = 0,
2049 counttrump = 0, countnottrump = 0, best = 0;
2050
2051 game_count_cards(prog_data->players[player],
2052 card->family, &pointstrump, &pointsnottrump,
2053 &counttrump, &countnottrump, &best);
2054
2055 if(counttrump > 1)
2056 {
2057 pointstrump += set_master_points(card->num);
2058
2059 /* from 140 to 225
2060 * lesser means more crazyness */
2061 if(pointstrump >= 225)
2062 {
2063 if(prog_data->output)
2064 fprintf(prog_data->output, "Player %d is susceptible to take the card [%d],[%d]\n", prog_data->player, pointsnottrump, pointstrump);
2065
2066 if( pointsnottrump+pointstrump > 270
2067 && (pointsnottrump/countnottrump) + (pointstrump/counttrump) >= 60
2068 && best >= 110)
2069 {
2070 select = TRUE;
2071 }
2072 }
2073 }
2074
2075 return(select);
2076 }
2077
2078 /*
2079 */
game_choose_trump_next(struct _prog * prog_data)2080 void game_choose_trump_next(struct _prog *prog_data)
2081 {
2082 gboolean play = FALSE;
2083 int player, trump, i, family;
2084
2085 select_player_next(&prog_data->player);
2086
2087 for(i =0; i< 4; i++)
2088 {
2089 if(prog_data->player != prog_data->menext)
2090 {
2091 if(prog_data->output != NULL)
2092 {
2093 fprintf(prog_data->output,
2094 "Computer turn to choose (%d)\n", prog_data->player);
2095 }
2096 if(prog_data->state == READY_DISTRIB1)
2097 play = game_ia_select_trump(prog_data, prog_data->player);
2098 else
2099 play = game_ia_select_second(prog_data, prog_data->player, &family);
2100
2101 if(play == TRUE)
2102 {
2103 player = prog_data->player;
2104
2105 if(prog_data->state == READY_DISTRIB1)
2106 trump = ((struct _card *)prog_data->waiting->data)->family;
2107 else
2108 trump = family;
2109 i = 3;
2110 }
2111 else
2112 select_player_next(&prog_data->player);
2113 }
2114 else
2115 i = 3;
2116 }
2117
2118 if(play == TRUE)
2119 {
2120 click_selectmaster(prog_data, player, trump);
2121 }
2122 else
2123 {
2124 if(prog_data->state == READY_DISTRIB1)
2125 {
2126 if(prog_data->output != NULL)
2127 {
2128 fprintf(prog_data->output,
2129 "No one want this trump, second pass\n");
2130 }
2131
2132 prog_data->state = EGS_SECOND;
2133 game_choose_trump(prog_data);
2134 }
2135 else
2136 {
2137 if(prog_data->output != NULL)
2138 {
2139 fprintf(prog_data->output,
2140 "No one seems to want this card, restart!\n");
2141 }
2142 free_clear(prog_data);
2143 game_restart(prog_data);
2144 game_start(prog_data);
2145
2146 }
2147
2148 }
2149 }
2150
2151 /* game_choose_trump : first phase of the game,
2152 * we need to select the trump.
2153 */
game_choose_trump(struct _prog * prog_data)2154 void game_choose_trump(struct _prog *prog_data)
2155 {
2156 int i, j, trump, family;
2157
2158 if(prog_data->output != NULL)
2159 {
2160 fprintf(prog_data->output,
2161 "Please choose trump\n");
2162 }
2163
2164 trump = ((struct _card*)prog_data->waiting->data)->family;
2165
2166
2167 for(i = 0; i < 4; i++)
2168 {
2169 if(prog_data->player == 2)
2170 {
2171 i = 5;
2172 if(prog_data->output != NULL)
2173 {
2174 fprintf(prog_data->output,
2175 "It's your turn to choose!\n");
2176 }
2177
2178 if(prog_data->state == READY_DISTRIB1)
2179 {
2180 gtk_widget_set_sensitive(prog_data->allwidgets[2], TRUE);
2181 gtk_widget_set_sensitive(prog_data->allwidgets[10+trump], TRUE);
2182 }
2183 else
2184 {
2185 for(j=0; j<4; j++)
2186 {
2187 if(j != trump)
2188 gtk_widget_set_sensitive(prog_data->allwidgets[10+j], TRUE);
2189 }
2190 }
2191
2192 }
2193 else
2194 {
2195 if(prog_data->output != NULL)
2196 {
2197 fprintf(prog_data->output,
2198 "Computer turn to choose (%d)\n", prog_data->player);
2199 }
2200 if( prog_data->state == READY_DISTRIB1 &&
2201 game_ia_select_trump(prog_data, prog_data->player) == TRUE)
2202 {
2203 click_selectmaster(prog_data, prog_data->player, trump);
2204 i=5;
2205 }
2206 else if( prog_data->state == EGS_SECOND &&
2207 game_ia_select_second(prog_data, prog_data->player, &family) == TRUE )
2208 {
2209
2210 click_selectmaster(prog_data, prog_data->player, family);
2211 i=5;
2212 }
2213 else
2214 select_player_next(&prog_data->player);
2215 }
2216 }
2217 }
2218