예제 #1
0
파일: bridge.c 프로젝트: ralight/ggz
static void bridge_next_bid(void)
{
	/* closely based on Suaro code, below */
	if (BRIDGE.pass_count == 4) {
		/* done bidding */
		if (BRIDGE.contract == 0) {
			ggz_debug(DBG_GAME,
				  "Four passes; redealing hand.");
			set_global_message("",
					   "Everyone passed; redealing.");
			set_game_state(STATE_NEXT_HAND);	/* redeal
								   hand */
		} else {
			ggz_debug(DBG_GAME,
				  "Three passes; bidding is over.");
			game.bid_total = game.bid_count;
			/* contract was determined in game_handle_bid */
		}
	} else {
		if (game.bid_count == 0)
			game.next_bid = game.dealer;
		else
			game.next_bid =
			    (game.next_bid + 1) % game.num_players;
	}
}
예제 #2
0
파일: game.c 프로젝트: ralight/ggz
void game_get_bid(int possible_bids,
		  bid_t * bid_choices, char **bid_texts, char **bid_descs)
{
	/* We ignore bid_texts and bid_descs */
	bid_t bid = get_bid(bid_choices, possible_bids);
	int i;

	ggz_debug(DBG_BID, "Making bid %d (%d/%d/%d).",
		  bid.bid, bid.sbid.val, bid.sbid.suit, bid.sbid.spec);

	for (i = 0; i < possible_bids; i++) {
		if (bid.bid == bid_choices[i].bid) {
			client_send_bid(i);
			return;
		}
	}

	/* This can happen when some variant is enabled that the AI doesn't
	   support.  The best choice is to find the closest matching bid. */
	ggz_debug(DBG_BID, "Uh oh; invalid bid!");
	for (i = 0; i < possible_bids; i++) {
		if (bid.sbid.spec == bid_choices[i].sbid.spec) {
			client_send_bid(i);
			return;
		}
	}
	client_send_bid(random() % possible_bids);
}
예제 #3
0
파일: server.c 프로젝트: ralight/ggz
int _ggzcore_server_connect(GGZServer * server)
{
	int status;
	char *errmsg;

	if (server) {
		if (thread_policy) {
			ggz_set_network_notify_func(connection_callback);
			reconnect_server = server;
		}

		_ggzcore_server_change_state(server, GGZ_TRANS_CONN_TRY);
		status = _ggzcore_net_connect(server->net);
	} else {
		ggz_set_network_notify_func(NULL);
		server = reconnect_server;
		reconnect_server = NULL;

		status = _ggzcore_net_get_fd(server->net);
	}

	if (status == GGZ_SOCKET_PENDING) {
		/* Asynchronous lookup */
		ggz_debug(GGZCORE_DBG_SERVER, "<gai> start lookup");
		return 0;
	}

	if (status < 0) {
		_ggzcore_server_change_state(server, GGZ_TRANS_CONN_FAIL);
#ifdef HAVE_HSTRERROR
		/* Unknown shouldn't happen - see ggz-cmd vs. ggz-txt */
		if (h_errno == 0)
			if (errno == 0)
				errmsg = _("Unknown reason");
			else
				errmsg = strerror(errno);
		else
			errmsg = (char *)hstrerror(h_errno);
#else
		/* Not all systems have hstrerror. */
		errmsg = _("Unable to connect");
#endif
		_ggzcore_server_event(server, GGZ_CONNECT_FAIL, errmsg);
	} else
		_ggzcore_server_event(server, GGZ_CONNECTED, NULL);

	if (thread_policy) {
		ggz_debug(GGZCORE_DBG_SERVER, "<gai> return %i", status);
	}

	return status;
}
예제 #4
0
static void server_print(gpointer server_ptr, gpointer data)
{
	const Server *server = server_ptr;

	ggz_debug("servers", "Profile name: %s\n", server->name);
        ggz_debug("servers", "  Host %s:%d\n", server->host, 
		  server->port);
        ggz_debug("servers", "  Login type: %d\n", server->type);
        ggz_debug("servers", "  Login: %s\n", server->login);
        if (server->type == GGZ_LOGIN)
                ggz_debug("servers",
			  "  Password: %s\n", server->password);
}
예제 #5
0
파일: state.c 프로젝트: ralight/ggz
void _ggzcore_state_transition(GGZTransID trans, GGZStateID *cur)
{
	int i = 0;
	struct _GGZTransition *transitions;
	GGZStateID next = -1;

	transitions = _ggz_states[*cur].transitions;

	/* Look through valid transitions to see if this one is OK */
	while (transitions[i].id != -1) {
		if (transitions[i].id == trans) {
			next = transitions[i].next;
			break;
		}
		++i;
	}

	if (next != *cur && next != -1) {
		ggz_debug(GGZCORE_DBG_STATE, "State transition %s -> %s",
			  _ggz_states[*cur].name,
			  _ggz_states[next].name);
		*cur = next;
	} else if (next == -1) {
		ggz_error_msg("No state transition for %d from %s!",
			      trans, _ggz_states[*cur].name);
	}
}
예제 #6
0
파일: message.c 프로젝트: ralight/ggz
static void put_global_message(char *mark, char *msg)
{
	global_message_list_t *gml;
	ggz_debug(DBG_MISC,
		    "Setting global message for '%s'.  Length is %zd.", mark,
		    strlen(msg));

	if (!mark || !msg)
		ggz_error_msg("put_global_message called on NULL string.");

	for (gml = game.message_head; gml != NULL; gml = gml->next) {
		if (!strcmp(mark, gml->mark)) {
			ggz_free(gml->message);
			gml->message = ggz_strdup(msg);
			return;
		}
	}

	gml = ggz_malloc(sizeof(global_message_list_t));
	gml->mark = ggz_strdup(mark);
	gml->message = ggz_strdup(msg);
	if (game.message_tail)
		game.message_tail->next = gml;
	game.message_tail = gml;
	if (!game.message_head)
		game.message_head = gml;
}
예제 #7
0
파일: ggzclient.c 프로젝트: ralight/ggz
static void ggz_server_error(const char *msg_type,
			     const char *msg_explanation)
{
	gchar *msg;

	ggz_debug("connection", "%s: %s.",
		  msg_type, msg_explanation);

	assert(ggz_gtk.server_tag != 0);
	g_source_remove(ggz_gtk.server_tag);
	ggz_gtk.server_tag = 0;

	clear_room_list();
	clear_player_list();
	clear_table_list();
	main_activate();

	if (ggzcore_server_get_state(ggz_gtk.server)
	    != GGZ_STATE_RECONNECTING) {
		msg = g_strdup_printf(_("%s: %s"),
				      msg_type, msg_explanation);
		msgbox(msg, _("Error"),
		       MSGBOX_OKONLY, MSGBOX_STOP, MSGBOX_NORMAL);
		g_free(msg);
	}
}
예제 #8
0
파일: table.c 프로젝트: ralight/ggz
/* Setup some of the table data structures.  This is called just once
   immediately upon startup. */
void table_initialize(void)
{
	static int call_count = 0;

	/* Just a sanity check; we don't want to call this function twice. */
	assert(call_count == 0);
	call_count++;

	ggz_debug(DBG_TABLE, "Initializing table.");

	/* This starts our drawing code */
	table = g_object_get_data(G_OBJECT(dlg_main), "fixed1");
	table_style = gtk_widget_get_style(table);
	gtk_widget_show(table);

	table_drawing_area = gtk_drawing_area_new();
	gtk_widget_set_size_request(table_drawing_area,
				    get_table_width(), get_table_height());
	gtk_fixed_put(GTK_FIXED(table), table_drawing_area, 0, 0);
	gtk_widget_show(table_drawing_area);
	g_signal_connect(table_drawing_area, "expose_event",
			 GTK_SIGNAL_FUNC(on_table_expose_event), NULL);

	assert(table_drawing_area->window);
	assert(get_table_width() > 0 && get_table_height() > 0);
	table_buf = gdk_pixmap_new(table->window,
				   get_table_width(), get_table_height(),
				   -1);
	assert(table_buf);

	/* Redraw and display the table. */
	table_redraw();

	table_show_player_list();
}
예제 #9
0
파일: table.c 프로젝트: ralight/ggz
/* Handle a redraw of necessary items, for instance when a Gtk style change is 
   signaled. */
void table_redraw(void)
{
	ggz_debug(DBG_TABLE, "Redrawing table. ");
	if (table_ready) {
		int p;

		/* Complete (zip) any animation in process */
		animation_stop(TRUE);

		/* I really don't know why these are necessary... */
		gtk_widget_grab_focus(dlg_main);
		table_style = gtk_widget_get_style(table);

		/* Redraw everything to the buffer */
		table_clear_table(FALSE);
		draw_card_areas(FALSE);
		table_display_all_hands(FALSE);
		table_show_cards(FALSE);
		for (p = 0; p < ggzcards.num_players; p++)
			table_show_player_box(p, FALSE);

		/* Then draw the whole buffer to the window */
		table_show_table(0, 0, get_table_width(),
				 get_table_height());

		/* There has GOT to be a better way to force the redraw! */
		gdk_window_hide(table_drawing_area->window);
		gdk_window_show(table_drawing_area->window);
	} else {	/* not if (table_ready) */
		if (table_buf)
			draw_splash_screen();
	}
}
예제 #10
0
파일: server.c 프로젝트: ralight/ggz
void _ggzcore_server_change_state(GGZServer * server, GGZTransID trans)
{
	if (trans == GGZ_TRANS_NET_ERROR || trans == GGZ_TRANS_PROTO_ERROR) {
#ifdef SUPPORT_RECONNECT
		if (reconnect_policy) {
			char *host;
			int port;
			GGZConnectionPolicy policy;

			ggz_debug(GGZCORE_DBG_SERVER, "Setting up reconnection attempt");

			reconnect_server = server;
			host = ggz_strdup(_ggzcore_net_get_host(server->net));
			port = _ggzcore_net_get_port(server->net);
			policy = _ggzcore_net_get_policy(server->net);
			_ggzcore_net_free(server->net);
			server->net = _ggzcore_net_new();
			_ggzcore_net_init(server->net, server, host, port, policy);
			ggz_free(host);

			_ggzcore_server_clear_reconnect(server);

			server->state = GGZ_STATE_RECONNECTING;
			_ggzcore_server_event(server, GGZ_STATE_CHANGE, NULL);

			signal(SIGALRM, reconnect_alarm);
			alarm(reconnect_timeout);
			return;
		}
#endif
	}

	_ggzcore_state_transition(trans, &server->state);
	_ggzcore_server_event(server, GGZ_STATE_CHANGE, NULL);
}
예제 #11
0
파일: game.c 프로젝트: ralight/ggz
void game_get_play(int play_hand, int num_valid_cards,
		   card_t * valid_cards)
{
	int play_num, hand_num;
	hand_t *hand = &ggzcards.players[play_hand].hand;
	bool valid_plays[hand->hand_size];
	card_t play;

	assert(play_hand == ggzcards.play_hand);

	for (hand_num = 0; hand_num < hand->hand_size; hand_num++)
		valid_plays[hand_num] = FALSE;
	for (play_num = 0; play_num < num_valid_cards; play_num++) {
		card_t play_card = valid_cards[play_num];
		for (hand_num = 0; hand_num < hand->hand_size; hand_num++) {
			card_t hand_card = hand->cards[hand_num];
			if (are_cards_equal(play_card, hand_card)) {
				valid_plays[hand_num] = TRUE;
				break;
			}
		}
		assert(hand_num < hand->hand_size);
	}

	play = get_play(ggzcards.play_hand, valid_plays);

	ggz_debug(DBG_PLAY, "We're playing the %s of %s.",
		  get_face_name(play.face), get_suit_name(play.suit));

	make_play(play);
}
예제 #12
0
파일: table.c 프로젝트: ralight/ggz
/* Check for what card has been clicked and process it */
gboolean table_handle_cardclick_event(GdkEventButton * event)
{
	/* this function is tricky.  There are lots of different variables: x, 
	   y, w, h describe the card area itself, including the "selected
	   card" area.  xo and yo describe the offset given by the "selected
	   card".  x1 and y1 are specific coordinates of a card. xdiff and
	   ydiff is the overlapping offset for cards in hand.  There are so
	   many variables because hands can be facing any direction, and it's
	   possible to be playing from *any* hand (at least in theory). */
	int target;
	int which = -1;
	int p = ggzcards.play_hand;	/* player whose hand it is */
	int card_width, card_height;
	int hand_size;

	/* If it's not our turn to play, we don't care. */
	if (ggzcards.state != STATE_PLAY)
		return FALSE;

	assert(p >= 0 && p < ggzcards.num_players);

	ggz_debug(DBG_TABLE,
		  "table_handle_click_event: " "click at %f %f.", event->x,
		  event->y);

	/* This gets all of the layout information from the layout engine.
	   Unfortunately, it's very dense code. */
	card_width = get_card_width(get_orientation(p));
	card_height = get_card_height(get_orientation(p));

	/* Calculate our card target */
	hand_size = preferences.collapse_hand
	    ? ggzcards.players[p].hand.hand_size
	    : ggzcards.players[p].u_hand_size;
	for (target = 0; target < hand_size; target++) {
		int x, y;

		if (!preferences.collapse_hand &&
		    !ggzcards.players[p].u_hand[target].is_valid)
			continue;

		get_card_pos(p, target, target == selected_card, &x, &y);

		if (event->x >= x && event->x <= x + card_width
		    /* TODO: generalize for any orientation */
		    && event->y >= y && event->y <= y + card_height)
			which = target;
	}

	if (which == -1)
		/* The click wasn't actually on a card. */
		return FALSE;

	/* Handle the click. */
	table_card_clicked(which);
	return TRUE;
}
예제 #13
0
파일: table.c 프로젝트: ralight/ggz
/* Exposed function to show one player's hand. */
void table_display_hand(int p, int write_to_screen)
{
	int i;
	card_t table_card = table_cards[p];
	int hand_size;

#if 0
	/* It looks like the server violates this, although it's probably a
	   bug in the server. */
	assert(table_ready && game_started);
#endif

	/* The server may send out a hand of size 0 when we first connect, but 
	   we just want to ignore it. */
	if (!table_ready)
		return;

	ggz_debug(DBG_TABLE, "Displaying hand for player %d.", p);

	/* redraw outer rectangle */
	clear_card_area(p);
	draw_card_box(p);

	/* Draw the cards */
	hand_size = preferences.collapse_hand
	    ? ggzcards.players[p].hand.hand_size
	    : ggzcards.players[p].u_hand_size;
	for (i = 0; i < hand_size; i++) {
		card_t card;
		int x, y;

		if (preferences.collapse_hand)
			card = ggzcards.players[p].hand.cards[i];
		else {
			if (!ggzcards.players[p].u_hand[i].is_valid)
				continue;
			card = ggzcards.players[p].u_hand[i].card;
		}

		if (card.face >= 0 && card.face == table_card.face &&
		    card.suit >= 0 && card.suit == table_card.suit &&
		    card.deck >= 0 && card.deck == table_card.deck)
			/* if the player has a card on the table _and_ it
			   matches this card, skip over it. */
			continue;
		get_card_pos(p, i,
			     p == ggzcards.play_hand && i == selected_card,
			     &x, &y);

		draw_card(card, get_orientation(p), x, y, table_buf);
	}

	/* And refresh the on-screen image for card areas */
	if (write_to_screen)
		show_card_area(p);
}
예제 #14
0
파일: server.c 프로젝트: ralight/ggz
int _ggzcore_server_logout(GGZServer * server)
{
	int status;

	ggz_debug(GGZCORE_DBG_SERVER, "Logging out");
	status = _ggzcore_net_send_logout(server->net);
	if (status == 0)
		_ggzcore_server_change_state(server, GGZ_TRANS_LOGOUT_TRY);

	return status;
}
예제 #15
0
파일: server.c 프로젝트: ralight/ggz
int _ggzcore_server_disconnect(GGZServer * server)
{
	ggz_debug(GGZCORE_DBG_SERVER, "Disconnecting and going offline");
	_ggzcore_net_disconnect(server->net);

	/* Force the server object into the offline state */
	server->state = GGZ_STATE_OFFLINE;
	_ggzcore_server_event(server, GGZ_STATE_CHANGE, NULL);

	return 0;
}
예제 #16
0
파일: game.c 프로젝트: ralight/ggz
static GGZHookReturn game_playing(GGZGameEvent id, const void *event_data,
				  const void *user_data)
{
	ggz_debug("game",
		  "Game module connected to server over game channel");
	if (launch_in_process())
		launch_table();
	else
		client_join_table();

	return GGZ_HOOK_OK;
}
예제 #17
0
파일: table.c 프로젝트: ralight/ggz
/* Displays a player's message on the table. */
void table_set_player_message(int player, const char *message)
{
	ggz_debug(DBG_TABLE, "Setting player message for %d.", player);

	if (player_messages[player])
		ggz_free(player_messages[player]);

	player_messages[player] = ggz_strdup(message);

	if (table_ready)
		table_show_player_box(player, TRUE);
}
예제 #18
0
파일: server.c 프로젝트: ralight/ggz
void _ggzcore_server_set_login_status(GGZServer * server,
				      GGZClientReqError status)
{
	ggz_debug(GGZCORE_DBG_SERVER, "Status of login: %d", status);

	if (status == E_OK) {
		_ggzcore_server_change_state(server, GGZ_TRANS_LOGIN_OK);
		_ggzcore_server_event(server, GGZ_LOGGED_IN, NULL);
	} else {
		GGZErrorEventData error = {.status = status,
					   .message = NULL};

		switch (status) {
		case E_ALREADY_LOGGED_IN:
			error.message = _("Already logged in");
			break;
		case E_USR_LOOKUP:
			error.message = _("The password was incorrect");
			break;
		case E_USR_TAKEN:
			error.message = _("Name is already taken");
			break;
		case E_USR_TYPE:
			error.message = _("This name is already registered "
					  "so cannot be used by a guest");
			break;
		case E_USR_FOUND:
			error.message = _("No such name was found");
			break;
		case E_TOO_LONG:
			error.message = _("Name too long");
			break;
		case E_BAD_USERNAME:
			error.message = _("Name contains forbidden "
					  "characters");
			break;
		case E_BAD_PASSWORD:
			error.message = _("You must enter a legitimate "
					  "password");
			break;
		case E_BAD_OPTIONS:
			error.message = _("Missing password or other bad "
					  "options.");
			break;
		default:
			error.message = _("Unknown login error");
			break;
		}
		_ggzcore_server_change_state(server, GGZ_TRANS_LOGIN_FAIL);
		_ggzcore_server_event(server, GGZ_LOGIN_FAIL, &error);
	}

}
예제 #19
0
파일: server.c 프로젝트: ralight/ggz
static void reconnect_alarm(int sig)
{
	ggz_debug(GGZCORE_DBG_SERVER, "Trying to reconnect...");

	if (_ggzcore_net_connect(reconnect_server->net) < 0) {
		reconnect_server->state = GGZ_STATE_RECONNECTING;
		alarm(reconnect_timeout);
	} else {
		_ggzcore_server_change_state(reconnect_server, GGZ_TRANS_CONN_OK);
		_ggzcore_server_event(reconnect_server, GGZ_CONNECTED, NULL);
	}
}
예제 #20
0
파일: server.c 프로젝트: ralight/ggz
int _ggzcore_server_create_channel(GGZServer *server)
{
	int status;
	const char *host;
	unsigned int port;
	char *errmsg;

	/* FIXME: make sure we don't already have a channel */

	server->channel = _ggzcore_net_new();
	host = _ggzcore_net_get_host(server->net);
	port = _ggzcore_net_get_port(server->net);
	_ggzcore_net_init(server->channel, server, host, port, 0);
	status = _ggzcore_net_connect(server->channel);

	if (status < 0 && status != GGZ_SOCKET_PENDING) {
		ggz_debug(GGZCORE_DBG_SERVER, "Channel creation failed");
#ifdef HAVE_HSTRERROR
		errmsg = (char*)hstrerror(h_errno);
#else
		/* Not all systems have hstrerror. */
		errmsg = _("Unable to connect");
#endif
		_ggzcore_server_event(server, GGZ_CHANNEL_FAIL, errmsg);
 	}
	else {
		if (status != GGZ_SOCKET_PENDING) {
			ggz_debug(GGZCORE_DBG_SERVER, "Channel created");
			_ggzcore_server_event(server, GGZ_CHANNEL_CONNECTED, NULL);
		} else {
			if (thread_policy) {
				ggz_set_network_notify_func(channel_callback);
				reconnect_server = server;
			}
			ggz_debug(GGZCORE_DBG_SERVER, "Channel creation deferred");
		}
 	}

	return status;
}
예제 #21
0
파일: table.c 프로젝트: ralight/ggz
/* Display's a player's name on the table. */
void table_set_name(int player, const char *name)
{
	ggz_debug(DBG_TABLE, "Setting player name: %d => %s.", player,
		  name);

	if (player_names[player])
		ggz_free(player_names[player]);

	player_names[player] = ggz_strdup(name);

	if (table_ready)
		table_show_player_box(player, TRUE);
}
예제 #22
0
파일: ggzclient.c 프로젝트: ralight/ggz
static GGZHookReturn ggz_connected(GGZServerEvent id,
				   const void *event_data,
				   const void *user_data)
{
	int fd;

	if (id == GGZ_CONNECTED) {
		GIOChannel *channel;

		/* Add the fd to the gtk main loop */
		ggz_debug("connection", "We're connected.");
		fd = ggzcore_server_get_fd(ggz_gtk.server);
		assert(ggz_gtk.server_tag == 0);
		assert(fd >= 0);
		channel = g_io_channel_unix_new(fd);
		ggz_gtk.server_tag =
		    g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
					G_IO_IN, ggz_check_fd,
					GINT_TO_POINTER(fd),
					ggz_input_removed);
		g_io_channel_unref(channel);
	} else if (id == GGZ_CHANNEL_CONNECTED) {
		GIOChannel *channel;

		/* Add the fd to the gtk main loop */
		ggz_debug("connection", "Direct game channel connected.");
		fd = ggzcore_server_get_channel(ggz_gtk.server);
		assert(ggz_gtk.channel_tag == 0);
		assert(fd >= 0);
		channel = g_io_channel_unix_new(fd);
		ggz_gtk.channel_tag = g_io_add_watch(channel, G_IO_IN,
					     ggz_check_fd,
					     GINT_TO_POINTER(fd));
		g_io_channel_unref(channel);
	}

	return GGZ_HOOK_OK;
}
예제 #23
0
파일: message.c 프로젝트: ralight/ggz
void set_player_message(player_t p)
{
	if (game.data == NULL) {
		/* silently fail; it's easier to check here than elsewhere */
		return;
	}

	ggz_debug(DBG_MISC, "Setting player %d/%s's message.", p,
		    get_player_name(p));
	if (p < 0 || p >= game.num_players)
		ggz_error_msg("set_player_message(%d) called.", p);
	game.data->set_player_message(p);
	broadcast_player_message(game.players[p].seat);
}
예제 #24
0
파일: ggzclient.c 프로젝트: ralight/ggz
static GGZHookReturn ggz_channel_ready(GGZGameEvent id,
				       const void *event_data,
				       const void *user_data)
{
	ggz_debug("connection", "Direct game channel ready for game");

	/* Remove channel from gdk input list */
	assert(ggz_gtk.channel_tag != 0);
	g_source_remove(ggz_gtk.channel_tag);
	ggz_gtk.channel_tag = 0;

	game_channel_ready();

	return GGZ_HOOK_OK;
}
예제 #25
0
파일: server.c 프로젝트: ralight/ggz
int _ggzcore_server_join_room(GGZServer * server, GGZRoom *room)
{
	int status;
	int room_id = _ggzcore_room_get_id(room);

	ggz_debug(GGZCORE_DBG_SERVER, "Moving to room %d", room_id);

	status = _ggzcore_net_send_join_room(server->net, room_id);
	server->new_room = room;

	if (status == 0)
		_ggzcore_server_change_state(server, GGZ_TRANS_ENTER_TRY);

	return status;
}
예제 #26
0
파일: bridge.c 프로젝트: ralight/ggz
static void bridge_handle_bid(player_t p, bid_t bid)
{
	assert(game.next_bid == p);
	/* closely based on the Suaro code */
	ggz_debug(DBG_GAME, "The bid chosen is %d %s %d.", bid.sbid.val,
		  short_bridge_suit_names[(int)bid.sbid.suit],
		  bid.sbid.spec);

	if (bid.sbid.spec == BRIDGE_PASS) {
		BRIDGE.pass_count++;
	} else if (bid.sbid.spec == BRIDGE_DOUBLE
		   || bid.sbid.spec == BRIDGE_REDOUBLE) {
		BRIDGE.pass_count = 1;
		BRIDGE.bonus *= 2;
	} else {
		BRIDGE.contract = bid.sbid.val;
		BRIDGE.contract_suit = bid.sbid.suit;
		BRIDGE.bonus = 1;
		BRIDGE.pass_count = 1;

		if (BRIDGE.opener[p % 2][BRIDGE.contract_suit] == -1)
			BRIDGE.opener[p % 2][BRIDGE.contract_suit] = p;
		BRIDGE.declarer =
		    BRIDGE.opener[p % 2][BRIDGE.contract_suit];
		BRIDGE.dummy = (BRIDGE.declarer + 2) % 4;

		ggz_debug(DBG_GAME, "Setting bridge contract to %d %s.",
			  BRIDGE.contract,
			  long_bridge_suit_names[BRIDGE.contract_suit]);
		if (bid.sbid.suit != BRIDGE_NOTRUMP) {
			set_trump_suit(bid.sbid.suit);
		} else {
			set_trump_suit(NO_SUIT);
		}
	}
}
예제 #27
0
파일: table.c 프로젝트: ralight/ggz
/* Handle a card that is clicked by either popping it forward or playing it if 
   it is already selected. */
static void table_card_clicked(int card_num)
{
	ggz_debug(DBG_TABLE, "table_card_clicked: Card %d clicked.",
		  card_num);

	if (card_num == selected_card || preferences.single_click_play) {
		/* If you click on the already selected card, it gets played.
		   There's also an option so that you need only click once. */
		selected_card = -1;
		game_play_card(card_num);
	} else {
		/* Pop the card forward and select it */
		selected_card = card_num;
		table_display_hand(ggzcards.play_hand, TRUE);
	}
}
예제 #28
0
파일: ggzclient.c 프로젝트: ralight/ggz
static GGZHookReturn ggz_logout(GGZServerEvent id, const void *event_data,
				const void *user_data)
{
	ggz_debug("connection", "Logged out.");

	if (ggzcore_server_get_state(ggz_gtk.server)
	    != GGZ_STATE_RECONNECTING) {
		server_disconnect();
	}

	/* set title */
	if (!ggz_gtk.embedded_protocol_version) {
		gtk_window_set_title(GTK_WINDOW(ggz_gtk.main_window),
				     _("GGZ Gaming Zone"));
	}

	return GGZ_HOOK_OK;
}
예제 #29
0
파일: game.c 프로젝트: ralight/ggz
static GGZHookReturn game_negotiated(GGZGameEvent id,
				     const void *event_data,
				     const void *user_data)
{
	ggz_debug("game", "Game module ready (creating channel)");

#ifndef HAVE_WINSOCK_H
	ggzcore_server_create_channel(ggz_gtk.server);
#endif

	if(ggz_async_fd() != -1) {
		GIOChannel *channel;

		channel = g_io_channel_unix_new(ggz_async_fd());
		ggz_gtk.resolv_tag = g_io_add_watch(channel, G_IO_IN,
			game_check_asyncfd,
			GINT_TO_POINTER(ggz_async_fd()));
		g_io_channel_unref(channel);
	}

	return GGZ_HOOK_OK;
}
예제 #30
0
파일: table.c 프로젝트: ralight/ggz
/* Draws a "splash screen" that is shown before the game is initialized. */
static void draw_splash_screen(void)
{
#if 0
	card_t card = { ACE_HIGH, SPADES, 0 };
#endif

	ggz_debug(DBG_TABLE, "Drawing splash screen.");

	assert(!game_started && !table_ready);
	assert(table_buf);

	table_clear_table(FALSE);

#if 0
	/* This is temporarily disabled until I can figure out how to get it
	   to work with the player list. */
	draw_card(card, 0,
		  (get_table_width() - CARDWIDTH) / 2,
		  (get_table_height() - CARDHEIGHT) / 2, table_buf);
#endif

	table_show_table(0, 0, get_table_width(), get_table_height());
}