Beispiel #1
0
void
board_set_declarer (seat declarer)
{
	board *b = CUR_BOARD;
	if (declarer == b->declarer)
		return;

	if (b->n_played_cards > 0) {
		board_statusbar (_("Cannot change declarer while cards are in play"));
		PROTECT_BEGIN;
		show_board(b, REDRAW_CONTRACT);
		PROTECT_END;
		return;
	}

	PROTECT_BEGIN;
	b->declarer = declarer;
	b->current_turn = seat_mod(declarer + 1);
	invalidate_dd_scores (b);
	show_board(b, REDRAW_CONTRACT | REDRAW_TRICKS | REDRAW_HANDS | REDRAW_NAMES | REDRAW_BOARD_LIST);
	PROTECT_END;
}
Beispiel #2
0
void
on_menu_file_web_activate ()
{
	board *b = CUR_BOARD;
	GString *url = g_string_new ("http://www.bridgebase.com/tools/handviewer.html?");

	/* non-lin interface
	int h;

	g_string_append_printf (url, "d=%c", seat_lc[b->dealer]);
	g_string_append_printf (url, "&v=%c", vuln_lc[b->vuln[0] + 2 * b->vuln[1]]);
	g_string_append_printf (url, "&n=%d", b->n + 1); // TODO: real board number

	for (h = west; h <= south; h++) {
		if (*b->hand_name[h - 1]->str)
			g_string_append_printf (url, "&%cn=%s", seat_lc[h], b->hand_name[h - 1]->str);

		g_string_append_printf (url, "&%c=", seat_lc[h]);
		int s;
		for (s = club; s <= spade; s++) {
			g_string_append_printf (url, "%s", trump_str_char[s]);
			int c;
			for (c = s * 13 + 12; c >= (int)s * 13; c--)
				if (b->dealt_cards[c] == h)
					g_string_append_printf(url, "%c", rank_char(RANK(c)));
		}
	}

	if (b->n_bids) {
		g_string_append_printf (url, "&a=");
		int i;
		for (i = 0; i < b->n_bids; i++)
			g_string_append_printf (url, "%s", lin_bid (b->bidding[i]));
	}

	if (b->n_played_cards) {
		g_string_append_printf (url, "&p=");
		int i;
		for (i = 0; i < b->n_played_cards; i++)
			g_string_append_printf (url, "%s%c",
					trump_str_char[SUIT(b->played_cards[i])], rank_char(RANK(b->played_cards[i])));
		if (b->played_cards[b->n_played_cards] = claim_rest)
			g_string_append_printf (url, "&c=%d", b->declarer_tricks);
	}
	*/

	int i;

	// TODO: merge with code from board_save_lin
	g_string_append_printf (url, "lin=pn|%s,%s,%s,%s|",
			b->hand_name[south-1]->str, b->hand_name[west-1]->str,
			b->hand_name[north-1]->str, b->hand_name[east-1]->str);
	g_string_append_printf (url, "st||");
	g_string_append_printf (url, "md|%d%s|", seat_mod(b->dealer + 1), lin_card_string(b)); // TODO: end positions
	g_string_append_printf (url, "rh||");
	g_string_append_printf (url, "ah|%s|", b->name->str);
	g_string_append_printf (url, "sv|%c|", b->vuln[0] ? (b->vuln[1] ? 'b' : 'n')
			: (b->vuln[1] ? 'e' : 'o'));
	for (i = 0; i < b->n_bids; i++) {
		g_string_append_printf (url, "mb|%s|", lin_bid(b->bidding[i]));
		if (b->alerts[i])
			g_string_append_printf (url, "an|%s|", *b->alerts[i] ? b->alerts[i] : "!");
	}
	for (i = 0; i < 52; i++) {
		if (i % 4 == 0)
			g_string_append_printf (url, "pg||");
		card c = b->played_cards[i];
		if (c < 0)
			break;
		if (c == claim_rest) {
			g_string_append_printf (url, "mc|%d|",
					b->declarer_tricks >= 0 ? b->declarer_tricks : 0);
			break;
		}
		g_string_append_printf (url, "pc|%c%c|", "CDHS"[SUIT(c)], rank_char(RANK(c)));
	}
	g_string_append_printf (url, "pg||\n");

	printf ("%s\n", url->str);

	GError *error = NULL;
	gtk_show_uri (gdk_screen_get_default (), url->str, GDK_CURRENT_TIME, &error);
	if (error) {
		printf ("%s\n", error->message);
		g_error_free (error);
	}
	g_string_free (url, TRUE);
}
Beispiel #3
0
static int
board_parse_lin (window_board_t *win, char *line, FILE *f)
{
	char *saveptr;
	char *tok;
	int card_nr = 0;

	setlocale (LC_NUMERIC, "C");

	board *b = board_new (win->n_boards + 1);
	int board_filled = 0;
	board_window_append_board (win, b);

	/* global list of names for vugraph files */
	char *name_arr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	int name_n = 0;
	/* IMP/MP list */
	char *mp_str = NULL;
	char *mp_ptr = NULL;

	do {
	for (tok = sane_strtok_r(line, "|", &saveptr); tok; tok = STRTOK) {
		/* single hand */
		if (!strcmp(tok, "pn")) { /* SWNE */
			tok = STRTOK;
			char *nameptr;
			char *name = sane_strtok_r(tok, ",", &nameptr);
			int i = 0;
			do {
				if (i < 4)
					g_string_printf(b->hand_name[seat_mod (i++) - 1], "%s", name);
				if (name_n < 8)
					name_arr[name_n++] = strdup(name);
			} while ((name = sane_strtok_r(NULL, ",", &nameptr)));

		} else if (!strcmp(tok, "md")) { /* make deal */
			tok = STRTOK;
			if (*tok == '0') {
				printf ("md|0| (keep deal) mode not supported\n");
				continue;
			}
			if (board_filled) {
				/* start new board */
				card_nr = 0;
				board_filled = 0;

				b = board_new (win->n_boards + 1);
				board_window_append_board (win, b);
				/* initialize player names, required for vugraph files */
				int i;
				for (i = 0; i < 4; i++) {
					g_string_printf(b->hand_name[seat_mod (i) - 1],
						"%s", name_arr[i + (tok[0] == 'c' ? 4 : 0)]);
				}
			}
			char *c;
			seat se = south;
			suit su = spade;
			b->dealer = seat_mod(*tok - '0' - 1);
			for (c = tok + 1; *c; c++) {
				int i;
				if ((i = parse_suit(*c)) != -1) {
					su = i;
				} else if ((i = parse_rank_char(*c)) != -1) {
					if (add_card(b, se, (su * 13) + i) != 1)
						goto error;
				} else if (*c == ',') {
					se = seat_mod(se + 1);
				} else {
					printf("Parse error: %s", tok);
					goto error;
				}
			}
			// TODO: end positions
			deal_random(b); /* compute east hand */
			board_filled = 1; /* consider this board finished on next qx token */

		} else if (!strcmp(tok, "ah")) { /* board name */
			g_string_printf(b->name, "%s", STRTOK);

		} else if (!strcmp(tok, "qx")) { /* board number, o1, c1, o2, ... */
			tok = STRTOK;
			if (board_filled) { /* first token in new vugraph board */
				card_nr = 0;
				board_filled = 0;

				b = board_new (win->n_boards + 1);
				board_window_append_board (win, b);
				/* initialize player names, required for vugraph files */
				int i;
				for (i = 0; i < 4; i++) {
					g_string_printf(b->hand_name[seat_mod (i) - 1],
						"%s", name_arr[i + (tok[0] == 'c' ? 4 : 0)]);
				}
			}
			if (strlen (tok) >= 1)
				g_string_printf(b->name, "%s %s",
					tok[0] == 'c' ? _("Closed") :
						(tok[0] == 'o' ? _("Open") : _("Board")),
					tok + 1);

			/* for now assume qx|| is present in all lin files with mp|| */
			if (mp_str) {
				// FIXME: skip leading boards that were kibitzed but not played
				// (01-26-08-3.lin)
				char *score = mp_ptr ? sane_strtok_r (NULL, ",", &mp_ptr) :
						sane_strtok_r (mp_str, ",", &mp_ptr);
				b->mp[0] = score ? round (strtod (score, NULL) * 100.0) : 0;
				score = sane_strtok_r (NULL, ",", &mp_ptr);
				b->mp[1] = score ? round (strtod (score, NULL) * 100.0) : 0;
			}

		} else if (!strcmp(tok, "sv")) {
			tok = STRTOK;
			switch (*tok) {
				case '0':
				case 'o': b->vuln[0] = 0; b->vuln[1] = 0; break;
				case 'n': b->vuln[0] = 1; b->vuln[1] = 0; break;
				case 'e': b->vuln[0] = 0; b->vuln[1] = 1; break;
				case 'b': b->vuln[0] = 1; b->vuln[1] = 1; break;
				default: printf("Unknown vulnerability: sv|%s|\n", tok);
			}

		} else if (!strcmp(tok, "mb")) {
			/* mb|-ppp1Cp1Hp3Np4Dp4Hppp| */
			tok = STRTOK;
			char *bidp = tok;
			char *al = strchr (bidp, '!');
			if (al) {
				*al++ = '\0';
			}
			do {
				int bid = parse_bid(&bidp);
				if (bid == -1) {
					printf("Invalid bid %s/%s\n", tok, bidp);
					break;
				}
				board_append_bid(b, bid, 1);
				if (al) {
					board_set_alert (b, al);
					al = NULL;
				}
			} while (*bidp);

		} else if (!strcmp(tok, "an")) {
			tok = STRTOK;
			board_set_alert (b, !strcmp (tok, "!") ? "" : tok); /* filter uninteresting ! */

		} else if (!strcmp(tok, "pc")) {
			int c = parse_card(tok = STRTOK);
			if (c == -1) {
				printf("Invalid card %s\n", tok);
				continue;
			}
			if (card_nr < 52)
				b->played_cards[card_nr++] = c;

		} else if (!strcmp(tok, "mc")) {
			tok = STRTOK; // TODO: store number of (total) claimed tricks
			b->played_cards[card_nr] = claim_rest; // no card_nr increment here
			b->declarer_tricks = atoi (tok);

		/* vugraph file */
		} else if (!strcmp(tok, "vg")) { /* match title */
			tok = STRTOK;
			//printf ("Match title: %s\n", tok);
			if (win->title)
				free (win->title);
			if (win->subtitle)
				free (win->subtitle);
			if (win->team1)
				free (win->team1);
			if (win->team2)
				free (win->team2);

			char *t_ptr;
			char *title = sane_strtok_r (tok, ",", &t_ptr);
			if (title)
				win->title = strdup (title);
			char *subtitle = sane_strtok_r (NULL, ",", &t_ptr);
			if (subtitle)
				win->subtitle = strdup (subtitle);
			sane_strtok_r (NULL, ",", &t_ptr); /* scoring I IMPs P MPs B board-a-match */
			sane_strtok_r (NULL, ",", &t_ptr); /* first board nr */
			sane_strtok_r (NULL, ",", &t_ptr); /* last board nr */
			char *team1 = sane_strtok_r (NULL, ",", &t_ptr);
			if (team1)
				win->team1 = strdup (team1);
			sane_strtok_r (NULL, ",", &t_ptr); /* carry-over score team 1 */
			char *team2 = sane_strtok_r (NULL, ",", &t_ptr);
			if (team2)
				win->team2 = strdup (team2);
			/* carry-over score team 2 */

		} else if (!strcmp(tok, "pw")) { /* more player names */
			tok = STRTOK;
			//printf ("Players: %s\n", tok);
		} else if (!strcmp(tok, "bn")) { /* board numbers */
			tok = STRTOK;
			//printf ("Board numbers: %s\n", tok);
		} else if (!strcmp(tok, "rs")) { /* results */
			tok = STRTOK;
			//printf ("Results: %s\n", tok);
		} else if (!strcmp(tok, "mp")) { /* MP result */
			tok = STRTOK;
			//printf ("Scores: %s\n", tok);
			mp_str = strdup (tok);
		} else if (!strcmp(tok, "nt")) { /* comment (new text) */
			tok = STRTOK;
			//printf ("Comment: %s\n", tok);

		} else if (!strcmp(tok, "at")) { /* add text */
			STRTOK;
		} else if (!strcmp(tok, "cr") || !strcmp(tok, "cg") ||
			   !strcmp(tok, "cb")) { /* color */
			STRTOK;
		} else if (!strcmp(tok, "hc") || !strcmp(tok, "lc") ||
			   !strcmp(tok, "hs") || !strcmp(tok, "ls")) {
			STRTOK; /* hilight card, suit */
		} else if (!strcmp(tok, "pg")) {
			STRTOK; /* page break, e.g. after trick or comment */
		} else if (!strcmp(tok, "rh")) { /* reset heading */
			STRTOK;
		} else if (!strcmp(tok, "sk")) { /* set kibitzed */
			STRTOK;
		} else if (!strcmp(tok, "st")) { /* small text */
			STRTOK;
		} else if (!strcmp(tok, "up")) { /* undo play */
			tok = STRTOK;
		} else if (!*tok || *tok == '\n' || *tok == '\r') {
			/* empty token, hopefully end of line */
		} else {
			printf("Unknown token '%s|%s|'\n", tok, STRTOK);
		}
	}
	} while (fgets(line, 1023, f));

	int ret = 1;
	int i;
	goto ok;
error:
	ret = 0;
ok:
	for (i = 0; i < name_n; i++)
		free (name_arr[i]);
	if (mp_str)
		free (mp_str);

	setlocale (LC_NUMERIC, "");

	return ret;
}
Beispiel #4
0
static int
board_save_lin(window_board_t *win, char *filename)
{
	int cur;
	FILE *f;
	if ((f = fopen (filename, "w")) == NULL)
		return 0;

	setlocale (LC_NUMERIC, "C");

	if (win->title) {
		fprintf (f, "vg|%s,%s,%s,%d,%d,%s,,%s,|\n",
			win->title,
			win->subtitle ? win->subtitle : "",
			"P", // FIXME
			1, win->n_boards,
			win->team1 ? win->team1 : "",
			win->team2 ? win->team2 : "");

		fprintf (f, "rs|");
		for (cur = 0; cur < win->n_boards; cur++) {
			board *b = win->boards[cur];
			fprintf (f, "%s,", lin_contract (b));
			if (cur != win->n_boards - 1)
				fprintf (f, ",");
		}
		fprintf (f, "|\n");

		fprintf (f, "pw|");
		for (cur = 0; cur < win->n_boards; cur++) {
			board *b = win->boards[cur];
			fprintf (f, "%s,%s,%s,%s",
				b->hand_name[south-1]->str, b->hand_name[west-1]->str,
				b->hand_name[north-1]->str, b->hand_name[east-1]->str);
			if (cur != win->n_boards - 1)
				fprintf (f, ",");
		}
		fprintf (f, "|\n");

		fprintf (f, "mp|");
		for (cur = 0; cur < win->n_boards; cur++) {
			board *b = win->boards[cur];
			if (b->mp[0] == 0 && b->mp[1] == 0)
				fprintf (f, "--,--");
			else {
				if (b->mp[0])
					fprintf (f, "%.2f", b->mp[0] / 100.0);
				fprintf (f, ",");
				if (b->mp[1])
					fprintf (f, "%.2f", b->mp[1] / 100.0);
			}
			if (cur != win->n_boards - 1)
				fprintf (f, ",");
		}
		fprintf (f, "|\n");

		fprintf (f, "bn|");
		for (cur = 0; cur < win->n_boards; cur++) {
			//board *b = win->boards[cur];
			fprintf (f, "%d", cur + 1); // TODO: original number?
			if (cur != win->n_boards - 1)
				fprintf (f, ",");
		}
		fprintf (f, "|\n");

		fprintf (f, "pg||\n");
	}

	for (cur = 0; cur < win->n_boards; cur++) {
		board *b = win->boards[cur];
		int i;

		if (win->n_boards > 1)
			fprintf (f, "qx|o%d|", cur + 1); // TODO: open/closed, real board number

		fprintf (f, "pn|%s,%s,%s,%s|",
			b->hand_name[south-1]->str, b->hand_name[west-1]->str,
			b->hand_name[north-1]->str, b->hand_name[east-1]->str);
		fprintf (f, "st||");
		fprintf (f, "md|%d%s|", seat_mod(b->dealer + 1), lin_card_string(b)); // TODO: end positions
		fprintf (f, "rh||");
		fprintf (f, "ah|%s|", b->name->str);
		fprintf (f, "sv|%c|", b->vuln[0] ? (b->vuln[1] ? 'b' : 'n')
						: (b->vuln[1] ? 'e' : 'o'));
		for (i = 0; i < b->n_bids; i++) {
			fprintf (f, "mb|%s|", lin_bid(b->bidding[i]));
			if (b->alerts[i])
				fprintf (f, "an|%s|", *b->alerts[i] ? b->alerts[i] : "!");
		}
		for (i = 0; i < 52; i++) {
			if (i % 4 == 0)
				fprintf (f, "pg||");
			card c = b->played_cards[i];
			if (c < 0)
				break;
			if (c == claim_rest) {
				fprintf (f, "mc|%d|",
					b->declarer_tricks >= 0 ? b->declarer_tricks : 0);
				break;
			}
			fprintf (f, "pc|%c%c|", "CDHS"[SUIT(c)], rank_char(RANK(c)));
		}
		fprintf (f, "pg||\n");
	}

	int ret = 1, e = 0;
	if (ferror (f)) {
		ret = 0;
		e = errno;
	}
	fclose(f);
	errno = e;

	setlocale (LC_NUMERIC, "");

	return ret;
}
Beispiel #5
0
void show_board (board *b, redraw_t redraw)
{
	GtkWidget *w;
	GString *str = g_string_new(NULL);
	assert (b);

	if (redraw & REDRAW_BOARD_LIST) {
		board_window_rebuild_board_menu (win);
		window_options_board_list_populate ();
	}

	if (redraw & (REDRAW_TITLE | REDRAW_CONTRACT)) {
		g_string_printf(str, "Tenace - %s (%s)", b->name->str,
			contract_string_asc (b->level, b->trumps, b->declarer, b->doubled));
		if (win->title) {
			g_string_append_printf (str, " - %s", win->title);
			if (win->subtitle)
				g_string_append_printf (str, " - %s", win->subtitle);
			if (win->team1 && win->team2)
				g_string_append_printf (str, _(" - %s vs. %s"),
						win->team1, win->team2);
		} else if (win->filename) {
			char *fname = win->filename;
			if (strrchr(fname, '/'))
				fname = strrchr(fname, '/') + 1;
			g_string_append_printf (str, " - %s", fname);
		}
		gtk_window_set_title(GTK_WINDOW(win->window), str->str);
	}

	if (redraw & REDRAW_CONTRACT) {
		w = get_widget ("label_board");
		g_string_printf(str, "%s\n%s\n%s: %s\n%s: %s",
			b->name->str,
			contract_string(b->level, b->trumps, b->declarer, b->doubled),
			_("Dealer"), _(seat_str[b->dealer]),
			_("Vulnerable"), vuln_string(b));
		gtk_label_set_text((GtkLabel*) w, str->str);

		char *dealermenu[] = { 0, "dealer_west1", "dealer_north1",
			"dealer_east1", "dealer_south1"};
		w = get_widget (dealermenu[b->dealer]);
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);

		char *declarermenu[] = { 0, "declarer_west1", "declarer_north1",
			"declarer_east1", "declarer_south1"};
		w = get_widget (declarermenu[b->declarer]);
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);

		char *levelmenu[] = { "level1" /* PASS */, "level1", "level2", "level3",
			"level4", "level5", "level6", "level7" };
		w = get_widget (levelmenu[b->level]);
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);

		char *suitmenu[] = { "contract_clubs1", "contract_diamonds1",
			"contract_hearts1", "contract_spades1", "contract_no_trump1" };
		w = get_widget (suitmenu[b->trumps]);
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);

		char *doublemenu[] = { "level_doubled0", "level_doubled1", "level_redoubled1" };
		w = get_widget (doublemenu[b->doubled]);
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);

		char *vulnmenu[] = { "vuln_none", "vuln_ns", "vuln_ew", "vuln_all" };
		w = get_widget (vulnmenu[2 * b->vuln[1] + b->vuln[0]]);
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);

		window_options_board_populate ();
	}

	if (redraw & REDRAW_NAMES) {
		w = get_widget ("label_west");
		board_set_player_name (w, west, b->dealer == west, b->vuln[1],
				b->declarer == west,
				b->current_turn == west, b->hand_name[0]->str);
		w = get_widget ("label_north");
		board_set_player_name (w, north, b->dealer == north, b->vuln[0],
				b->declarer == north,
				b->current_turn == north, b->hand_name[1]->str);
		w = get_widget ("label_east");
		board_set_player_name (w, east, b->dealer == east, b->vuln[1],
				b->declarer == east,
				b->current_turn == east, b->hand_name[2]->str);
		w = get_widget ("label_south");
		board_set_player_name (w, south, b->dealer == south, b->vuln[0],
				b->declarer == south,
				b->current_turn == south, b->hand_name[3]->str);

		window_options_board_populate ();
	}

	if (redraw & REDRAW_TRICKS) {
		w = get_widget ("label_tricks");
		g_string_printf(str, _("NS: %d\nEW: %d"), b->tricks[0], b->tricks[1]);
		gtk_label_set_markup((GtkLabel*) w, str->str);
	}

	if (redraw & REDRAW_PAR) {
		w = get_widget ("par_label");
		if (b->par_score == -1) {
			gtk_label_set_text (GTK_LABEL (w), "");
		} else {
			char *par = par_label (b);
			gtk_label_set_markup(GTK_LABEL (w), par);
			free (par);
		}
	}

	if (redraw & REDRAW_HANDS) {
		int i, c;
		/* hands */
		int next_card = b->played_cards[b->n_played_cards];
		for (i = west; i <= south; i++) {
			for (c = 51; c >= 0; c--) {
				int has = i == b->cards[c];
				int had = i == b->dealt_cards[c];
				int color;
				if (seat_mask (i, win->show_hands))
					color = has ?
					(c == next_card ?
					 HAND_DISPLAY_HILIGHT_CARD : HAND_DISPLAY_CARD) :
					(had && win->show_played_cards ?
					 HAND_DISPLAY_OLD_CARD : HAND_DISPLAY_NO_CARD);
				else
					color = HAND_DISPLAY_NO_CARD;
				hand_display_set_card (win->handdisp[i - 1], c, color);
				if (has && b->current_dd && b->current_dd->card_score[c] >= 0 &&
						seat_mask (i, win->show_dd_scores))
					hand_display_set_card_score (win->handdisp[i - 1], c,
						card_overtricks(b, c));
				else
					hand_display_set_card_score (win->handdisp[i - 1], c,
						HAND_DISPLAY_NO_SCORE);
			}
			hand_display_set_card_score_neg (win->handdisp[i - 1],
					i % 2 != b->declarer % 2);
			hand_display_draw(GTK_WIDGET (win->handdisp[i - 1]));
		}

		/* table */
		hand_display_table_reset_cards (win->table);
		if (b->n_played_cards) {
			int trick_start = b->n_played_cards - seat_mod(b->n_played_cards);
			for (i = trick_start; i < b->n_played_cards; i++) {
				card c = b->played_cards[i];
				seat s = b->dealt_cards[c];
				hand_display_table_set_card (win->table, i - trick_start, s, c);
			}
		}
		hand_display_draw(GTK_WIDGET (win->table));

		line_entry_set_from_board(b);
	}

	g_string_free(str, TRUE);

	if (redraw & REDRAW_PLAY)
		window_play_update(b);

	if (redraw & REDRAW_BIDDING) {
		bidding_update (win, b, redraw & REDRAW_BIDDING_SCROLL);
	}
}