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