/* chess-game.c generated by valac 0.12.0, the Vala compiler
 * generated from chess-game.vala, do not modify */


#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gobject/gvaluecollector.h>


#define TYPE_COLOR (color_get_type ())

#define TYPE_CHESS_PLAYER (chess_player_get_type ())
#define CHESS_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHESS_PLAYER, ChessPlayer))
#define CHESS_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHESS_PLAYER, ChessPlayerClass))
#define IS_CHESS_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHESS_PLAYER))
#define IS_CHESS_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHESS_PLAYER))
#define CHESS_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHESS_PLAYER, ChessPlayerClass))

typedef struct _ChessPlayer ChessPlayer;
typedef struct _ChessPlayerClass ChessPlayerClass;
typedef struct _ChessPlayerPrivate ChessPlayerPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))

#define TYPE_PIECE_TYPE (piece_type_get_type ())

#define TYPE_CHESS_PIECE (chess_piece_get_type ())
#define CHESS_PIECE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHESS_PIECE, ChessPiece))
#define CHESS_PIECE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHESS_PIECE, ChessPieceClass))
#define IS_CHESS_PIECE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHESS_PIECE))
#define IS_CHESS_PIECE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHESS_PIECE))
#define CHESS_PIECE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHESS_PIECE, ChessPieceClass))

typedef struct _ChessPiece ChessPiece;
typedef struct _ChessPieceClass ChessPieceClass;
typedef struct _ChessPiecePrivate ChessPiecePrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _ParamSpecChessPiece ParamSpecChessPiece;

#define TYPE_CHECK_STATE (check_state_get_type ())

#define TYPE_CHESS_MOVE (chess_move_get_type ())
#define CHESS_MOVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHESS_MOVE, ChessMove))
#define CHESS_MOVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHESS_MOVE, ChessMoveClass))
#define IS_CHESS_MOVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHESS_MOVE))
#define IS_CHESS_MOVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHESS_MOVE))
#define CHESS_MOVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHESS_MOVE, ChessMoveClass))

typedef struct _ChessMove ChessMove;
typedef struct _ChessMoveClass ChessMoveClass;
typedef struct _ChessMovePrivate ChessMovePrivate;
#define _chess_piece_unref0(var) ((var == NULL) ? NULL : (var = (chess_piece_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
#define _chess_move_unref0(var) ((var == NULL) ? NULL : (var = (chess_move_unref (var), NULL)))
typedef struct _ParamSpecChessMove ParamSpecChessMove;

#define TYPE_CHESS_STATE (chess_state_get_type ())
#define CHESS_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHESS_STATE, ChessState))
#define CHESS_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHESS_STATE, ChessStateClass))
#define IS_CHESS_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHESS_STATE))
#define IS_CHESS_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHESS_STATE))
#define CHESS_STATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHESS_STATE, ChessStateClass))

typedef struct _ChessState ChessState;
typedef struct _ChessStateClass ChessStateClass;
typedef struct _ChessStatePrivate ChessStatePrivate;
#define _chess_state_unref0(var) ((var == NULL) ? NULL : (var = (chess_state_unref (var), NULL)))

#define TYPE_CHESS_RULE (chess_rule_get_type ())

#define TYPE_CHESS_RESULT (chess_result_get_type ())
typedef struct _ParamSpecChessState ParamSpecChessState;

#define TYPE_CHESS_GAME (chess_game_get_type ())
#define CHESS_GAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHESS_GAME, ChessGame))
#define CHESS_GAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHESS_GAME, ChessGameClass))
#define IS_CHESS_GAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHESS_GAME))
#define IS_CHESS_GAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHESS_GAME))
#define CHESS_GAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHESS_GAME, ChessGameClass))

typedef struct _ChessGame ChessGame;
typedef struct _ChessGameClass ChessGameClass;
typedef struct _ChessGamePrivate ChessGamePrivate;

#define TYPE_CHESS_CLOCK (chess_clock_get_type ())
#define CHESS_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHESS_CLOCK, ChessClock))
#define CHESS_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHESS_CLOCK, ChessClockClass))
#define IS_CHESS_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHESS_CLOCK))
#define IS_CHESS_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHESS_CLOCK))
#define CHESS_CLOCK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHESS_CLOCK, ChessClockClass))

typedef struct _ChessClock ChessClock;
typedef struct _ChessClockClass ChessClockClass;
#define __g_list_free__chess_state_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__chess_state_unref0_ (var), NULL)))
typedef struct _ParamSpecChessGame ParamSpecChessGame;

typedef enum  {
	COLOR_WHITE,
	COLOR_BLACK
} Color;

struct _ChessPlayer {
	GObject parent_instance;
	ChessPlayerPrivate * priv;
	Color color;
};

struct _ChessPlayerClass {
	GObjectClass parent_class;
};

typedef enum  {
	PIECE_TYPE_PAWN,
	PIECE_TYPE_ROOK,
	PIECE_TYPE_KNIGHT,
	PIECE_TYPE_BISHOP,
	PIECE_TYPE_QUEEN,
	PIECE_TYPE_KING
} PieceType;

struct _ChessPiece {
	GTypeInstance parent_instance;
	volatile int ref_count;
	ChessPiecePrivate * priv;
	ChessPlayer* player;
	PieceType type;
};

struct _ChessPieceClass {
	GTypeClass parent_class;
	void (*finalize) (ChessPiece *self);
};

struct _ParamSpecChessPiece {
	GParamSpec parent_instance;
};

typedef enum  {
	CHECK_STATE_NONE,
	CHECK_STATE_CHECK,
	CHECK_STATE_CHECKMATE
} CheckState;

struct _ChessMove {
	GTypeInstance parent_instance;
	volatile int ref_count;
	ChessMovePrivate * priv;
	gint number;
	ChessPiece* piece;
	ChessPiece* promotion_piece;
	ChessPiece* moved_rook;
	ChessPiece* victim;
	gint r0;
	gint f0;
	gint r1;
	gint f1;
	gboolean ambiguous_rank;
	gboolean ambiguous_file;
	CheckState check_state;
};

struct _ChessMoveClass {
	GTypeClass parent_class;
	void (*finalize) (ChessMove *self);
};

struct _ParamSpecChessMove {
	GParamSpec parent_instance;
};

struct _ChessState {
	GTypeInstance parent_instance;
	volatile int ref_count;
	ChessStatePrivate * priv;
	gint number;
	ChessPlayer* players[2];
	ChessPlayer* current_player;
	gboolean can_castle_kingside[2];
	gboolean can_castle_queenside[2];
	gint en_passant_index;
	CheckState check_state;
	gint halfmove_clock;
	ChessPiece* board[64];
	ChessMove* last_move;
};

struct _ChessStateClass {
	GTypeClass parent_class;
	void (*finalize) (ChessState *self);
};

struct _ChessStatePrivate {
	gint64 piece_masks[2];
};

typedef enum  {
	CHESS_RULE_CHECKMATE,
	CHESS_RULE_STALEMATE,
	CHESS_RULE_FIFTY_MOVES,
	CHESS_RULE_TIMEOUT,
	CHESS_RULE_THREE_FOLD_REPETITION,
	CHESS_RULE_INSUFFICIENT_MATERIAL,
	CHESS_RULE_RESIGN,
	CHESS_RULE_ABANDONMENT,
	CHESS_RULE_DEATH
} ChessRule;

typedef enum  {
	CHESS_RESULT_IN_PROGRESS,
	CHESS_RESULT_WHITE_WON,
	CHESS_RESULT_BLACK_WON,
	CHESS_RESULT_DRAW
} ChessResult;

struct _ParamSpecChessState {
	GParamSpec parent_instance;
};

struct _ChessGame {
	GTypeInstance parent_instance;
	volatile int ref_count;
	ChessGamePrivate * priv;
	gboolean is_started;
	ChessResult result;
	ChessRule rule;
	GList* move_stack;
};

struct _ChessGameClass {
	GTypeClass parent_class;
	void (*finalize) (ChessGame *self);
};

struct _ChessGamePrivate {
	gint hold_count;
	ChessClock* _clock;
};

struct _ParamSpecChessGame {
	GParamSpec parent_instance;
};


static gpointer chess_player_parent_class = NULL;
static gpointer chess_piece_parent_class = NULL;
static gpointer chess_move_parent_class = NULL;
static gpointer chess_state_parent_class = NULL;
static gpointer chess_game_parent_class = NULL;

GType color_get_type (void) G_GNUC_CONST;
GType chess_player_get_type (void) G_GNUC_CONST;
enum  {
	CHESS_PLAYER_DUMMY_PROPERTY
};
ChessPlayer* chess_player_new (Color color);
ChessPlayer* chess_player_construct (GType object_type, Color color);
gboolean chess_player_move (ChessPlayer* self, const gchar* move, gboolean apply);
gboolean chess_player_move_with_coords (ChessPlayer* self, gint r0, gint f0, gint r1, gint f1, gboolean apply);
void chess_player_undo (ChessPlayer* self);
gboolean chess_player_resign (ChessPlayer* self);
gboolean chess_player_claim_draw (ChessPlayer* self);
static void g_cclosure_user_marshal_BOOLEAN__STRING_BOOLEAN (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void g_cclosure_user_marshal_BOOLEAN__VOID (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void chess_player_finalize (GObject* obj);
GType piece_type_get_type (void) G_GNUC_CONST;
gpointer chess_piece_ref (gpointer instance);
void chess_piece_unref (gpointer instance);
GParamSpec* param_spec_chess_piece (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_chess_piece (GValue* value, gpointer v_object);
void value_take_chess_piece (GValue* value, gpointer v_object);
gpointer value_get_chess_piece (const GValue* value);
GType chess_piece_get_type (void) G_GNUC_CONST;
enum  {
	CHESS_PIECE_DUMMY_PROPERTY
};
ChessPiece* chess_piece_new (ChessPlayer* player, PieceType type);
ChessPiece* chess_piece_construct (GType object_type, ChessPlayer* player, PieceType type);
Color chess_piece_get_color (ChessPiece* self);
gunichar chess_piece_get_symbol (ChessPiece* self);
static void chess_piece_finalize (ChessPiece* obj);
GType check_state_get_type (void) G_GNUC_CONST;
gpointer chess_move_ref (gpointer instance);
void chess_move_unref (gpointer instance);
GParamSpec* param_spec_chess_move (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_chess_move (GValue* value, gpointer v_object);
void value_take_chess_move (GValue* value, gpointer v_object);
gpointer value_get_chess_move (const GValue* value);
GType chess_move_get_type (void) G_GNUC_CONST;
enum  {
	CHESS_MOVE_DUMMY_PROPERTY
};
gchar* chess_move_get_lan (ChessMove* self);
gchar* chess_move_get_san (ChessMove* self);
static gchar* chess_move_make_san (ChessMove* self, gchar** piece_names, int piece_names_length1);
gchar* chess_move_get_fan (ChessMove* self);
gchar* chess_move_get_engine (ChessMove* self);
ChessMove* chess_move_copy (ChessMove* self);
ChessMove* chess_move_new (void);
ChessMove* chess_move_construct (GType object_type);
static void chess_move_finalize (ChessMove* obj);
gpointer chess_state_ref (gpointer instance);
void chess_state_unref (gpointer instance);
GParamSpec* param_spec_chess_state (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_chess_state (GValue* value, gpointer v_object);
void value_take_chess_state (GValue* value, gpointer v_object);
gpointer value_get_chess_state (const GValue* value);
GType chess_state_get_type (void) G_GNUC_CONST;
#define CHESS_STATE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_CHESS_STATE, ChessStatePrivate))
enum  {
	CHESS_STATE_DUMMY_PROPERTY
};
static ChessState* chess_state_new_empty (void);
static ChessState* chess_state_construct_empty (GType object_type);
ChessState* chess_state_new (const gchar* fen);
ChessState* chess_state_construct (GType object_type, const gchar* fen);
static gboolean chess_state_decode_piece_type (ChessState* self, gunichar c, PieceType* type);
gint chess_state_get_index (ChessState* self, gint rank, gint file);
static CheckState chess_state_get_check_state (ChessState* self, ChessPlayer* player);
ChessState* chess_state_copy (ChessState* self);
gboolean chess_state_equals (ChessState* self, ChessState* state);
gchar* chess_state_get_fen (ChessState* self);
gint chess_state_get_file (ChessState* self, gint index);
gint chess_state_get_rank (ChessState* self, gint index);
gboolean chess_state_move (ChessState* self, const gchar* move, gboolean apply);
static gboolean chess_state_decode_move (ChessState* self, ChessPlayer* player, const gchar* move, gint* r0, gint* f0, gint* r1, gint* f1, PieceType* promotion_type);
gboolean chess_state_move_with_coords (ChessState* self, ChessPlayer* player, gint r0, gint f0, gint r1, gint f1, PieceType promotion_type, gboolean apply, gboolean test_check);
ChessPlayer* chess_state_get_opponent (ChessState* self);
static gboolean chess_state_is_in_check (ChessState* self, ChessPlayer* player);
GType chess_rule_get_type (void) G_GNUC_CONST;
GType chess_result_get_type (void) G_GNUC_CONST;
ChessResult chess_state_get_result (ChessState* self, ChessRule* rule);
static gboolean chess_state_can_move (ChessState* self, ChessPlayer* player);
gboolean chess_state_have_sufficient_material (ChessState* self);
static gboolean chess_state_is_in_checkmate (ChessState* self, ChessPlayer* player);
static void chess_state_finalize (ChessState* obj);
gpointer chess_game_ref (gpointer instance);
void chess_game_unref (gpointer instance);
GParamSpec* param_spec_chess_game (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_chess_game (GValue* value, gpointer v_object);
void value_take_chess_game (GValue* value, gpointer v_object);
gpointer value_get_chess_game (const GValue* value);
GType chess_game_get_type (void) G_GNUC_CONST;
GType chess_clock_get_type (void) G_GNUC_CONST;
#define CHESS_GAME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_CHESS_GAME, ChessGamePrivate))
enum  {
	CHESS_GAME_DUMMY_PROPERTY
};
static void _chess_state_unref0_ (gpointer var);
static void _g_list_free__chess_state_unref0_ (GList* self);
#define CHESS_GAME_STANDARD_SETUP "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
ChessGame* chess_game_new (const gchar* fen, gchar** moves, int moves_length1);
ChessGame* chess_game_construct (GType object_type, const gchar* fen, gchar** moves, int moves_length1);
static gboolean chess_game_do_move (ChessGame* self, ChessPlayer* player, const gchar* move, gboolean apply);
ChessPlayer* chess_game_get_current_player (ChessGame* self);
ChessPlayer* chess_game_get_white (ChessGame* self);
static gboolean chess_game_move_cb (ChessGame* self, ChessPlayer* player, const gchar* move, gboolean apply);
static gboolean _chess_game_move_cb_chess_player_do_move (ChessPlayer* _sender, const gchar* move, gboolean apply, gpointer self);
static void chess_game_undo_cb (ChessGame* self, ChessPlayer* player);
static void _chess_game_undo_cb_chess_player_do_undo (ChessPlayer* _sender, gpointer self);
static gboolean chess_game_resign_cb (ChessGame* self, ChessPlayer* player);
static gboolean _chess_game_resign_cb_chess_player_do_resign (ChessPlayer* _sender, gpointer self);
static gboolean chess_game_claim_draw_cb (ChessGame* self, ChessPlayer* player);
static gboolean _chess_game_claim_draw_cb_chess_player_do_claim_draw (ChessPlayer* _sender, gpointer self);
ChessPlayer* chess_game_get_black (ChessGame* self);
ChessState* chess_game_get_current_state (ChessGame* self);
static void chess_game_complete_move (ChessGame* self);
void chess_game_add_hold (ChessGame* self);
void chess_game_remove_hold (ChessGame* self);
static void chess_game_stop (ChessGame* self, ChessResult _result_, ChessRule rule);
void chess_clock_set_active_color (ChessClock* self, Color value);
ChessPlayer* chess_game_get_opponent (ChessGame* self);
static gboolean chess_game_is_three_fold_repeat (ChessGame* self);
void chess_game_start (ChessGame* self);
static void chess_game_clock_expired_cb (ChessGame* self, ChessClock* clock);
static void _chess_game_clock_expired_cb_chess_clock_expired (ChessClock* _sender, gpointer self);
void chess_clock_start (ChessClock* self);
void chess_game_abandon (ChessGame* self);
ChessPiece* chess_game_get_piece (ChessGame* self, gint rank, gint file, gint move_number);
ChessClock* chess_game_get_clock (ChessGame* self);
void chess_game_set_clock (ChessGame* self, ChessClock* value);
guint chess_game_get_n_moves (ChessGame* self);
static void g_cclosure_user_marshal_VOID__CHESS_MOVE (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void chess_game_finalize (ChessGame* obj);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);
static gint _vala_array_length (gpointer array);

extern const gint64 BIT_BOARD_set_location_masks[64];
extern const gint64 BIT_BOARD_move_masks[768];
extern const gint64 BIT_BOARD_over_masks[4096];
extern const gint64 BIT_BOARD_clear_location_masks[64];

GType color_get_type (void) {
	static volatile gsize color_type_id__volatile = 0;
	if (g_once_init_enter (&color_type_id__volatile)) {
		static const GEnumValue values[] = {{COLOR_WHITE, "COLOR_WHITE", "white"}, {COLOR_BLACK, "COLOR_BLACK", "black"}, {0, NULL, NULL}};
		GType color_type_id;
		color_type_id = g_enum_register_static ("Color", values);
		g_once_init_leave (&color_type_id__volatile, color_type_id);
	}
	return color_type_id__volatile;
}


ChessPlayer* chess_player_construct (GType object_type, Color color) {
	ChessPlayer * self = NULL;
	self = (ChessPlayer*) g_object_new (object_type, NULL);
	self->color = color;
	return self;
}


ChessPlayer* chess_player_new (Color color) {
	return chess_player_construct (TYPE_CHESS_PLAYER, color);
}


gboolean chess_player_move (ChessPlayer* self, const gchar* move, gboolean apply) {
	gboolean result = FALSE;
	gboolean _tmp0_;
	gboolean _tmp1_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (move != NULL, FALSE);
	g_signal_emit_by_name (self, "do-move", move, apply, &_tmp0_);
	_tmp1_ = _tmp0_;
	result = _tmp1_;
	return result;
}


gboolean chess_player_move_with_coords (ChessPlayer* self, gint r0, gint f0, gint r1, gint f1, gboolean apply) {
	gboolean result = FALSE;
	gchar* _tmp0_ = NULL;
	gchar* move;
	gboolean _tmp1_;
	gboolean _tmp2_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = g_strdup_printf ("%c%d%c%d", 'a' + f0, r0 + 1, 'a' + f1, r1 + 1);
	move = _tmp0_;
	g_signal_emit_by_name (self, "do-move", move, apply, &_tmp1_);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	_g_free0 (move);
	return result;
}


void chess_player_undo (ChessPlayer* self) {
	g_return_if_fail (self != NULL);
	g_signal_emit_by_name (self, "do-undo");
}


gboolean chess_player_resign (ChessPlayer* self) {
	gboolean result = FALSE;
	gboolean _tmp0_;
	gboolean _tmp1_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_signal_emit_by_name (self, "do-resign", &_tmp0_);
	_tmp1_ = _tmp0_;
	result = _tmp1_;
	return result;
}


gboolean chess_player_claim_draw (ChessPlayer* self) {
	gboolean result = FALSE;
	gboolean _tmp0_;
	gboolean _tmp1_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_signal_emit_by_name (self, "do-claim-draw", &_tmp0_);
	_tmp1_ = _tmp0_;
	result = _tmp1_;
	return result;
}


static void g_cclosure_user_marshal_BOOLEAN__STRING_BOOLEAN (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_BOOLEAN) (gpointer data1, const char* arg_1, gboolean arg_2, gpointer data2);
	register GMarshalFunc_BOOLEAN__STRING_BOOLEAN callback;
	register GCClosure * cc;
	register gpointer data1, data2;
	gboolean v_return;
	cc = (GCClosure *) closure;
	g_return_if_fail (return_value != NULL);
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_BOOLEAN__STRING_BOOLEAN) (marshal_data ? marshal_data : cc->callback);
	v_return = callback (data1, g_value_get_string (param_values + 1), g_value_get_boolean (param_values + 2), data2);
	g_value_set_boolean (return_value, v_return);
}


static void g_cclosure_user_marshal_BOOLEAN__VOID (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, gpointer data2);
	register GMarshalFunc_BOOLEAN__VOID callback;
	register GCClosure * cc;
	register gpointer data1, data2;
	gboolean v_return;
	cc = (GCClosure *) closure;
	g_return_if_fail (return_value != NULL);
	g_return_if_fail (n_param_values == 1);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback);
	v_return = callback (data1, data2);
	g_value_set_boolean (return_value, v_return);
}


static void chess_player_class_init (ChessPlayerClass * klass) {
	chess_player_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->finalize = chess_player_finalize;
	g_signal_new ("start_turn", TYPE_CHESS_PLAYER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("do_move", TYPE_CHESS_PLAYER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_BOOLEAN__STRING_BOOLEAN, G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_BOOLEAN);
	g_signal_new ("do_undo", TYPE_CHESS_PLAYER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("do_resign", TYPE_CHESS_PLAYER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_BOOLEAN__VOID, G_TYPE_BOOLEAN, 0);
	g_signal_new ("do_claim_draw", TYPE_CHESS_PLAYER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_BOOLEAN__VOID, G_TYPE_BOOLEAN, 0);
}


static void chess_player_instance_init (ChessPlayer * self) {
}


static void chess_player_finalize (GObject* obj) {
	ChessPlayer * self;
	self = CHESS_PLAYER (obj);
	G_OBJECT_CLASS (chess_player_parent_class)->finalize (obj);
}


GType chess_player_get_type (void) {
	static volatile gsize chess_player_type_id__volatile = 0;
	if (g_once_init_enter (&chess_player_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (ChessPlayerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_player_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessPlayer), 0, (GInstanceInitFunc) chess_player_instance_init, NULL };
		GType chess_player_type_id;
		chess_player_type_id = g_type_register_static (G_TYPE_OBJECT, "ChessPlayer", &g_define_type_info, 0);
		g_once_init_leave (&chess_player_type_id__volatile, chess_player_type_id);
	}
	return chess_player_type_id__volatile;
}


GType piece_type_get_type (void) {
	static volatile gsize piece_type_type_id__volatile = 0;
	if (g_once_init_enter (&piece_type_type_id__volatile)) {
		static const GEnumValue values[] = {{PIECE_TYPE_PAWN, "PIECE_TYPE_PAWN", "pawn"}, {PIECE_TYPE_ROOK, "PIECE_TYPE_ROOK", "rook"}, {PIECE_TYPE_KNIGHT, "PIECE_TYPE_KNIGHT", "knight"}, {PIECE_TYPE_BISHOP, "PIECE_TYPE_BISHOP", "bishop"}, {PIECE_TYPE_QUEEN, "PIECE_TYPE_QUEEN", "queen"}, {PIECE_TYPE_KING, "PIECE_TYPE_KING", "king"}, {0, NULL, NULL}};
		GType piece_type_type_id;
		piece_type_type_id = g_enum_register_static ("PieceType", values);
		g_once_init_leave (&piece_type_type_id__volatile, piece_type_type_id);
	}
	return piece_type_type_id__volatile;
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


ChessPiece* chess_piece_construct (GType object_type, ChessPlayer* player, PieceType type) {
	ChessPiece* self = NULL;
	ChessPlayer* _tmp0_;
	g_return_val_if_fail (player != NULL, NULL);
	self = (ChessPiece*) g_type_create_instance (object_type);
	_tmp0_ = _g_object_ref0 (player);
	_g_object_unref0 (self->player);
	self->player = _tmp0_;
	self->type = type;
	return self;
}


ChessPiece* chess_piece_new (ChessPlayer* player, PieceType type) {
	return chess_piece_construct (TYPE_CHESS_PIECE, player, type);
}


Color chess_piece_get_color (ChessPiece* self) {
	Color result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->player->color;
	return result;
}


gunichar chess_piece_get_symbol (ChessPiece* self) {
	gunichar result;
	gunichar c;
	g_return_val_if_fail (self != NULL, 0U);
	c = (gunichar) ' ';
	switch (self->type) {
		case PIECE_TYPE_PAWN:
		{
			c = (gunichar) 'p';
			break;
		}
		case PIECE_TYPE_ROOK:
		{
			c = (gunichar) 'r';
			break;
		}
		case PIECE_TYPE_KNIGHT:
		{
			c = (gunichar) 'k';
			break;
		}
		case PIECE_TYPE_BISHOP:
		{
			c = (gunichar) 'b';
			break;
		}
		case PIECE_TYPE_QUEEN:
		{
			c = (gunichar) 'q';
			break;
		}
		case PIECE_TYPE_KING:
		{
			c = (gunichar) 'k';
			break;
		}
		default:
		break;
	}
	if (self->player->color == COLOR_WHITE) {
		gunichar _tmp0_;
		_tmp0_ = g_unichar_toupper (c);
		c = _tmp0_;
	}
	result = c;
	return result;
}


static void value_chess_piece_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_chess_piece_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		chess_piece_unref (value->data[0].v_pointer);
	}
}


static void value_chess_piece_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = chess_piece_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_chess_piece_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_chess_piece_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		ChessPiece* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = chess_piece_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_chess_piece_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	ChessPiece** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = chess_piece_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_chess_piece (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecChessPiece* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_CHESS_PIECE), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_chess_piece (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_PIECE), NULL);
	return value->data[0].v_pointer;
}


void value_set_chess_piece (GValue* value, gpointer v_object) {
	ChessPiece* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_PIECE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHESS_PIECE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		chess_piece_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		chess_piece_unref (old);
	}
}


void value_take_chess_piece (GValue* value, gpointer v_object) {
	ChessPiece* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_PIECE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHESS_PIECE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		chess_piece_unref (old);
	}
}


static void chess_piece_class_init (ChessPieceClass * klass) {
	chess_piece_parent_class = g_type_class_peek_parent (klass);
	CHESS_PIECE_CLASS (klass)->finalize = chess_piece_finalize;
	g_signal_new ("moved", TYPE_CHESS_PIECE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("promoted", TYPE_CHESS_PIECE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("died", TYPE_CHESS_PIECE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}


static void chess_piece_instance_init (ChessPiece * self) {
	self->ref_count = 1;
}


static void chess_piece_finalize (ChessPiece* obj) {
	ChessPiece * self;
	self = CHESS_PIECE (obj);
	_g_object_unref0 (self->player);
}


GType chess_piece_get_type (void) {
	static volatile gsize chess_piece_type_id__volatile = 0;
	if (g_once_init_enter (&chess_piece_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_chess_piece_init, value_chess_piece_free_value, value_chess_piece_copy_value, value_chess_piece_peek_pointer, "p", value_chess_piece_collect_value, "p", value_chess_piece_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (ChessPieceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_piece_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessPiece), 0, (GInstanceInitFunc) chess_piece_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType chess_piece_type_id;
		chess_piece_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ChessPiece", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&chess_piece_type_id__volatile, chess_piece_type_id);
	}
	return chess_piece_type_id__volatile;
}


gpointer chess_piece_ref (gpointer instance) {
	ChessPiece* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void chess_piece_unref (gpointer instance) {
	ChessPiece* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		CHESS_PIECE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


GType check_state_get_type (void) {
	static volatile gsize check_state_type_id__volatile = 0;
	if (g_once_init_enter (&check_state_type_id__volatile)) {
		static const GEnumValue values[] = {{CHECK_STATE_NONE, "CHECK_STATE_NONE", "none"}, {CHECK_STATE_CHECK, "CHECK_STATE_CHECK", "check"}, {CHECK_STATE_CHECKMATE, "CHECK_STATE_CHECKMATE", "checkmate"}, {0, NULL, NULL}};
		GType check_state_type_id;
		check_state_type_id = g_enum_register_static ("CheckState", values);
		g_once_init_leave (&check_state_type_id__volatile, check_state_type_id);
	}
	return check_state_type_id__volatile;
}


gchar* chess_move_get_lan (ChessMove* self) {
	gchar* result = NULL;
	GString* _tmp2_ = NULL;
	GString* builder;
	static const gchar promotion_symbols[] = {' ', 'R', 'N', 'B', 'Q', 'K'};
	gchar* _tmp3_;
	g_return_val_if_fail (self != NULL, NULL);
	if (self->moved_rook != NULL) {
		if (self->f1 > self->f0) {
			gchar* _tmp0_;
			_tmp0_ = g_strdup ("O-O");
			result = _tmp0_;
			return result;
		} else {
			gchar* _tmp1_;
			_tmp1_ = g_strdup ("O-O-O");
			result = _tmp1_;
			return result;
		}
	}
	_tmp2_ = g_string_new ("");
	builder = _tmp2_;
	if (self->victim != NULL) {
		g_string_append_printf (builder, "%c%dx%c%d", 'a' + self->f0, self->r0 + 1, 'a' + self->f1, self->r1 + 1);
	} else {
		g_string_append_printf (builder, "%c%d-%c%d", 'a' + self->f0, self->r0 + 1, 'a' + self->f1, self->r1 + 1);
	}
	if (self->promotion_piece != NULL) {
		g_string_append_printf (builder, "=%c", (gint) promotion_symbols[self->promotion_piece->type]);
	}
	switch (self->check_state) {
		case CHECK_STATE_CHECK:
		{
			g_string_append_c (builder, '+');
			break;
		}
		case CHECK_STATE_CHECKMATE:
		{
			g_string_append_c (builder, '#');
			break;
		}
		default:
		break;
	}
	_tmp3_ = g_strdup (builder->str);
	result = _tmp3_;
	_g_string_free0 (builder);
	return result;
}


gchar* chess_move_get_san (ChessMove* self) {
	gchar* result = NULL;
	static const gchar* piece_names[] = {"", "R", "N", "B", "Q", "K"};
	gchar* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_move_make_san (self, (gchar**) piece_names, G_N_ELEMENTS (piece_names));
	result = _tmp0_;
	return result;
}


gchar* chess_move_get_fan (ChessMove* self) {
	gchar* result = NULL;
	static const gchar* white_piece_names[] = {"", "♞", "♝", "♜", "♛", "♚"};
	static const gchar* black_piece_names[] = {"", "♘", "♗", "♖", "♕", "♔"};
	Color _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_piece_get_color (self->piece);
	if (_tmp0_ == COLOR_WHITE) {
		gchar* _tmp1_ = NULL;
		_tmp1_ = chess_move_make_san (self, (gchar**) white_piece_names, G_N_ELEMENTS (white_piece_names));
		result = _tmp1_;
		return result;
	} else {
		gchar* _tmp2_ = NULL;
		_tmp2_ = chess_move_make_san (self, (gchar**) black_piece_names, G_N_ELEMENTS (black_piece_names));
		result = _tmp2_;
		return result;
	}
}


static gchar* chess_move_make_san (ChessMove* self, gchar** piece_names, int piece_names_length1) {
	gchar* result = NULL;
	GString* _tmp2_ = NULL;
	GString* builder;
	gchar* _tmp3_;
	g_return_val_if_fail (self != NULL, NULL);
	if (self->moved_rook != NULL) {
		if (self->f1 > self->f0) {
			gchar* _tmp0_;
			_tmp0_ = g_strdup ("O-O");
			result = _tmp0_;
			return result;
		} else {
			gchar* _tmp1_;
			_tmp1_ = g_strdup ("O-O-O");
			result = _tmp1_;
			return result;
		}
	}
	_tmp2_ = g_string_new ("");
	builder = _tmp2_;
	g_string_append (builder, piece_names[self->piece->type]);
	if (self->ambiguous_file) {
		g_string_append_printf (builder, "%c", 'a' + self->f0);
	}
	if (self->ambiguous_rank) {
		g_string_append_printf (builder, "%d", self->r0 + 1);
	}
	if (self->victim != NULL) {
		g_string_append (builder, "x");
	}
	g_string_append_printf (builder, "%c%d", 'a' + self->f1, self->r1 + 1);
	if (self->promotion_piece != NULL) {
		g_string_append_printf (builder, "=%s", piece_names[self->promotion_piece->type]);
	}
	switch (self->check_state) {
		case CHECK_STATE_CHECK:
		{
			g_string_append_c (builder, '+');
			break;
		}
		case CHECK_STATE_CHECKMATE:
		{
			g_string_append_c (builder, '#');
			break;
		}
		default:
		break;
	}
	_tmp3_ = g_strdup (builder->str);
	result = _tmp3_;
	_g_string_free0 (builder);
	return result;
}


gchar* chess_move_get_engine (ChessMove* self) {
	gchar* result = NULL;
	GString* _tmp0_ = NULL;
	GString* builder;
	static const gchar promotion_symbols[] = {' ', 'r', 'n', 'b', 'q', ' '};
	gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_string_new ("");
	builder = _tmp0_;
	if (self->promotion_piece != NULL) {
		g_string_append_printf (builder, "%c%d%c%d%c", 'a' + self->f0, self->r0 + 1, 'a' + self->f1, self->r1 + 1, (gint) promotion_symbols[self->promotion_piece->type]);
	} else {
		g_string_append_printf (builder, "%c%d%c%d", 'a' + self->f0, self->r0 + 1, 'a' + self->f1, self->r1 + 1);
	}
	_tmp1_ = g_strdup (builder->str);
	result = _tmp1_;
	_g_string_free0 (builder);
	return result;
}


static gpointer _chess_piece_ref0 (gpointer self) {
	return self ? chess_piece_ref (self) : NULL;
}


ChessMove* chess_move_copy (ChessMove* self) {
	ChessMove* result = NULL;
	ChessMove* _tmp0_ = NULL;
	ChessMove* move;
	ChessPiece* _tmp1_;
	ChessPiece* _tmp2_;
	ChessPiece* _tmp3_;
	ChessPiece* _tmp4_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_move_new ();
	move = _tmp0_;
	move->number = self->number;
	_tmp1_ = _chess_piece_ref0 (self->piece);
	_chess_piece_unref0 (move->piece);
	move->piece = _tmp1_;
	_tmp2_ = _chess_piece_ref0 (self->promotion_piece);
	_chess_piece_unref0 (move->promotion_piece);
	move->promotion_piece = _tmp2_;
	_tmp3_ = _chess_piece_ref0 (self->moved_rook);
	_chess_piece_unref0 (move->moved_rook);
	move->moved_rook = _tmp3_;
	_tmp4_ = _chess_piece_ref0 (self->victim);
	_chess_piece_unref0 (move->victim);
	move->victim = _tmp4_;
	move->r0 = self->r0;
	move->f0 = self->f0;
	move->r1 = self->r1;
	move->f1 = self->f1;
	move->ambiguous_rank = self->ambiguous_rank;
	move->ambiguous_file = self->ambiguous_file;
	move->check_state = self->check_state;
	result = move;
	return result;
}


ChessMove* chess_move_construct (GType object_type) {
	ChessMove* self = NULL;
	self = (ChessMove*) g_type_create_instance (object_type);
	return self;
}


ChessMove* chess_move_new (void) {
	return chess_move_construct (TYPE_CHESS_MOVE);
}


static void value_chess_move_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_chess_move_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		chess_move_unref (value->data[0].v_pointer);
	}
}


static void value_chess_move_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = chess_move_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_chess_move_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_chess_move_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		ChessMove* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = chess_move_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_chess_move_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	ChessMove** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = chess_move_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_chess_move (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecChessMove* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_CHESS_MOVE), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_chess_move (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_MOVE), NULL);
	return value->data[0].v_pointer;
}


void value_set_chess_move (GValue* value, gpointer v_object) {
	ChessMove* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_MOVE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHESS_MOVE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		chess_move_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		chess_move_unref (old);
	}
}


void value_take_chess_move (GValue* value, gpointer v_object) {
	ChessMove* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_MOVE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHESS_MOVE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		chess_move_unref (old);
	}
}


static void chess_move_class_init (ChessMoveClass * klass) {
	chess_move_parent_class = g_type_class_peek_parent (klass);
	CHESS_MOVE_CLASS (klass)->finalize = chess_move_finalize;
}


static void chess_move_instance_init (ChessMove * self) {
	self->ref_count = 1;
}


static void chess_move_finalize (ChessMove* obj) {
	ChessMove * self;
	self = CHESS_MOVE (obj);
	_chess_piece_unref0 (self->piece);
	_chess_piece_unref0 (self->promotion_piece);
	_chess_piece_unref0 (self->moved_rook);
	_chess_piece_unref0 (self->victim);
}


GType chess_move_get_type (void) {
	static volatile gsize chess_move_type_id__volatile = 0;
	if (g_once_init_enter (&chess_move_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_chess_move_init, value_chess_move_free_value, value_chess_move_copy_value, value_chess_move_peek_pointer, "p", value_chess_move_collect_value, "p", value_chess_move_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (ChessMoveClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_move_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessMove), 0, (GInstanceInitFunc) chess_move_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType chess_move_type_id;
		chess_move_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ChessMove", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&chess_move_type_id__volatile, chess_move_type_id);
	}
	return chess_move_type_id__volatile;
}


gpointer chess_move_ref (gpointer instance) {
	ChessMove* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void chess_move_unref (gpointer instance) {
	ChessMove* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		CHESS_MOVE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


static ChessState* chess_state_construct_empty (GType object_type) {
	ChessState* self = NULL;
	self = (ChessState*) g_type_create_instance (object_type);
	return self;
}


static ChessState* chess_state_new_empty (void) {
	return chess_state_construct_empty (TYPE_CHESS_STATE);
}


static gchar string_get (const gchar* self, glong index) {
	gchar result = '\0';
	g_return_val_if_fail (self != NULL, '\0');
	result = ((gchar*) self)[index];
	return result;
}


ChessState* chess_state_construct (GType object_type, const gchar* fen) {
	ChessState* self = NULL;
	ChessPlayer* _tmp0_ = NULL;
	ChessPlayer* _tmp1_;
	ChessPlayer* _tmp2_ = NULL;
	ChessPlayer* _tmp3_;
	gchar** _tmp6_;
	gchar** _tmp7_ = NULL;
	gchar** fields;
	gint fields_length1;
	gint _fields_size_;
	gchar** _tmp8_;
	gchar** _tmp9_ = NULL;
	gchar** ranks;
	gint ranks_length1;
	gint _ranks_size_;
	gint _tmp34_;
	gint _tmp35_;
	CheckState _tmp36_;
	g_return_val_if_fail (fen != NULL, NULL);
	self = (ChessState*) g_type_create_instance (object_type);
	_tmp0_ = chess_player_new (COLOR_WHITE);
	_tmp1_ = _tmp0_;
	_g_object_unref0 (self->players[COLOR_WHITE]);
	self->players[COLOR_WHITE] = _tmp1_;
	_tmp2_ = chess_player_new (COLOR_BLACK);
	_tmp3_ = _tmp2_;
	_g_object_unref0 (self->players[COLOR_BLACK]);
	self->players[COLOR_BLACK] = _tmp3_;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp4_;
			_tmp4_ = TRUE;
			while (TRUE) {
				ChessPiece* _tmp5_;
				if (!_tmp4_) {
					i++;
				}
				_tmp4_ = FALSE;
				if (!(i < 64)) {
					break;
				}
				_tmp5_ = NULL;
				_chess_piece_unref0 (self->board[i]);
				self->board[i] = _tmp5_;
			}
		}
	}
	_tmp7_ = _tmp6_ = g_strsplit (fen, " ", 0);
	fields = _tmp7_;
	fields_length1 = _vala_array_length (_tmp6_);
	_fields_size_ = _vala_array_length (_tmp6_);
	_tmp9_ = _tmp8_ = g_strsplit (fields[0], "/", 0);
	ranks = _tmp9_;
	ranks_length1 = _vala_array_length (_tmp8_);
	_ranks_size_ = _vala_array_length (_tmp8_);
	{
		gint rank;
		rank = 0;
		{
			gboolean _tmp10_;
			_tmp10_ = TRUE;
			while (TRUE) {
				gchar* _tmp11_;
				gchar* rank_string;
				if (!_tmp10_) {
					rank++;
				}
				_tmp10_ = FALSE;
				if (!(rank < 8)) {
					break;
				}
				_tmp11_ = g_strdup (ranks[7 - rank]);
				rank_string = _tmp11_;
				{
					gint file;
					gint offset;
					file = 0;
					offset = 0;
					{
						gboolean _tmp12_;
						_tmp12_ = TRUE;
						while (TRUE) {
							gboolean _tmp13_ = FALSE;
							gchar _tmp15_;
							gchar c;
							gboolean _tmp16_ = FALSE;
							PieceType type = 0;
							Color _tmp17_ = 0;
							gboolean _tmp18_;
							Color color;
							gchar _tmp19_;
							PieceType _tmp20_;
							gboolean _tmp21_;
							gint _tmp22_;
							gint index;
							ChessPiece* _tmp23_ = NULL;
							ChessPiece* piece;
							ChessPiece* _tmp24_;
							ChessPiece* _tmp25_;
							gint64 mask;
							if (!_tmp12_) {
								offset++;
							}
							_tmp12_ = FALSE;
							if (file < 8) {
								gint _tmp14_;
								_tmp14_ = strlen (rank_string);
								_tmp13_ = offset < _tmp14_;
							} else {
								_tmp13_ = FALSE;
							}
							if (!_tmp13_) {
								break;
							}
							_tmp15_ = string_get (rank_string, (glong) offset);
							c = _tmp15_;
							if (c >= '1') {
								_tmp16_ = c <= '8';
							} else {
								_tmp16_ = FALSE;
							}
							if (_tmp16_) {
								file = file + ((gint) (c - '0'));
								continue;
							}
							_tmp18_ = g_ascii_isupper (c);
							if (_tmp18_) {
								_tmp17_ = COLOR_WHITE;
							} else {
								_tmp17_ = COLOR_BLACK;
							}
							color = _tmp17_;
							_tmp19_ = g_ascii_toupper (c);
							_tmp21_ = chess_state_decode_piece_type (self, (gunichar) _tmp19_, &_tmp20_);
							type = _tmp20_;
							if (!_tmp21_) {
							}
							_tmp22_ = chess_state_get_index (self, rank, file);
							index = _tmp22_;
							_tmp23_ = chess_piece_new (self->players[color], type);
							piece = _tmp23_;
							_tmp24_ = _chess_piece_ref0 (piece);
							_tmp25_ = _tmp24_;
							_chess_piece_unref0 (self->board[index]);
							self->board[index] = _tmp25_;
							mask = BIT_BOARD_set_location_masks[index];
							self->priv->piece_masks[color] |= mask;
							file++;
							_chess_piece_unref0 (piece);
						}
					}
				}
				_g_free0 (rank_string);
			}
		}
	}
	if (g_strcmp0 (fields[1], "w") == 0) {
		ChessPlayer* _tmp26_;
		_tmp26_ = _g_object_ref0 (self->players[COLOR_WHITE]);
		_g_object_unref0 (self->current_player);
		self->current_player = _tmp26_;
	} else {
		if (g_strcmp0 (fields[1], "b") == 0) {
			ChessPlayer* _tmp27_;
			_tmp27_ = _g_object_ref0 (self->players[COLOR_BLACK]);
			_g_object_unref0 (self->current_player);
			self->current_player = _tmp27_;
		}
	}
	if (g_strcmp0 (fields[2], "-") != 0) {
		{
			gint i;
			i = 0;
			{
				gboolean _tmp28_;
				_tmp28_ = TRUE;
				while (TRUE) {
					gint _tmp29_;
					gchar _tmp30_;
					gchar c;
					if (!_tmp28_) {
						i++;
					}
					_tmp28_ = FALSE;
					_tmp29_ = strlen (fields[2]);
					if (!(i < _tmp29_)) {
						break;
					}
					_tmp30_ = string_get (fields[2], (glong) i);
					c = _tmp30_;
					if (c == 'K') {
						self->can_castle_kingside[COLOR_WHITE] = TRUE;
					} else {
						if (c == 'Q') {
							self->can_castle_queenside[COLOR_WHITE] = TRUE;
						} else {
							if (c == 'k') {
								self->can_castle_kingside[COLOR_BLACK] = TRUE;
							} else {
								if (c == 'q') {
									self->can_castle_queenside[COLOR_BLACK] = TRUE;
								}
							}
						}
					}
				}
			}
		}
	}
	if (g_strcmp0 (fields[3], "-") != 0) {
		gchar _tmp31_;
		gchar _tmp32_;
		gint _tmp33_;
		_tmp31_ = string_get (fields[3], (glong) 1);
		_tmp32_ = string_get (fields[3], (glong) 0);
		_tmp33_ = chess_state_get_index (self, (gint) (_tmp31_ - '1'), (gint) (_tmp32_ - 'a'));
		self->en_passant_index = _tmp33_;
	}
	_tmp34_ = atoi (fields[4]);
	self->halfmove_clock = _tmp34_;
	_tmp35_ = atoi (fields[5]);
	self->number = (_tmp35_ - 1) * 2;
	if (self->current_player->color == COLOR_BLACK) {
		self->number++;
	}
	_tmp36_ = chess_state_get_check_state (self, self->current_player);
	self->check_state = _tmp36_;
	ranks = (_vala_array_free (ranks, ranks_length1, (GDestroyNotify) g_free), NULL);
	fields = (_vala_array_free (fields, fields_length1, (GDestroyNotify) g_free), NULL);
	return self;
}


ChessState* chess_state_new (const gchar* fen) {
	return chess_state_construct (TYPE_CHESS_STATE, fen);
}


ChessState* chess_state_copy (ChessState* self) {
	ChessState* result = NULL;
	ChessState* _tmp0_ = NULL;
	ChessState* state;
	ChessPlayer* _tmp1_;
	ChessPlayer* _tmp2_;
	ChessPlayer* _tmp3_;
	ChessPlayer* _tmp4_;
	ChessPlayer* _tmp5_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_state_new_empty ();
	state = _tmp0_;
	state->number = self->number;
	_tmp1_ = _g_object_ref0 (self->players[COLOR_WHITE]);
	_tmp2_ = _tmp1_;
	_g_object_unref0 (state->players[COLOR_WHITE]);
	state->players[COLOR_WHITE] = _tmp2_;
	_tmp3_ = _g_object_ref0 (self->players[COLOR_BLACK]);
	_tmp4_ = _tmp3_;
	_g_object_unref0 (state->players[COLOR_BLACK]);
	state->players[COLOR_BLACK] = _tmp4_;
	_tmp5_ = _g_object_ref0 (self->current_player);
	_g_object_unref0 (state->current_player);
	state->current_player = _tmp5_;
	state->can_castle_kingside[COLOR_WHITE] = self->can_castle_kingside[COLOR_WHITE];
	state->can_castle_queenside[COLOR_WHITE] = self->can_castle_queenside[COLOR_WHITE];
	state->can_castle_kingside[COLOR_BLACK] = self->can_castle_kingside[COLOR_BLACK];
	state->can_castle_queenside[COLOR_BLACK] = self->can_castle_queenside[COLOR_BLACK];
	state->en_passant_index = self->en_passant_index;
	state->check_state = self->check_state;
	if (self->last_move != NULL) {
		ChessMove* _tmp6_ = NULL;
		_tmp6_ = chess_move_copy (self->last_move);
		_chess_move_unref0 (state->last_move);
		state->last_move = _tmp6_;
	}
	{
		gint i;
		i = 0;
		{
			gboolean _tmp7_;
			_tmp7_ = TRUE;
			while (TRUE) {
				ChessPiece* _tmp8_;
				ChessPiece* _tmp9_;
				if (!_tmp7_) {
					i++;
				}
				_tmp7_ = FALSE;
				if (!(i < 64)) {
					break;
				}
				_tmp8_ = _chess_piece_ref0 (self->board[i]);
				_tmp9_ = _tmp8_;
				_chess_piece_unref0 (state->board[i]);
				state->board[i] = _tmp9_;
			}
		}
	}
	state->priv->piece_masks[COLOR_WHITE] = self->priv->piece_masks[COLOR_WHITE];
	state->priv->piece_masks[COLOR_BLACK] = self->priv->piece_masks[COLOR_BLACK];
	result = state;
	return result;
}


gboolean chess_state_equals (ChessState* self, ChessState* state) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	gboolean _tmp6_ = FALSE;
	gboolean _tmp7_ = FALSE;
	gboolean _tmp8_ = FALSE;
	gboolean _tmp9_ = FALSE;
	gboolean _tmp10_ = FALSE;
	gboolean _tmp11_ = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (state != NULL, FALSE);
	if (self->priv->piece_masks[COLOR_WHITE] != state->priv->piece_masks[COLOR_WHITE]) {
		_tmp11_ = TRUE;
	} else {
		_tmp11_ = self->priv->piece_masks[COLOR_BLACK] != state->priv->piece_masks[COLOR_BLACK];
	}
	if (_tmp11_) {
		_tmp10_ = TRUE;
	} else {
		_tmp10_ = self->can_castle_kingside[COLOR_WHITE] != state->can_castle_kingside[COLOR_WHITE];
	}
	if (_tmp10_) {
		_tmp9_ = TRUE;
	} else {
		_tmp9_ = self->can_castle_queenside[COLOR_WHITE] != state->can_castle_queenside[COLOR_WHITE];
	}
	if (_tmp9_) {
		_tmp8_ = TRUE;
	} else {
		_tmp8_ = self->can_castle_kingside[COLOR_BLACK] != state->can_castle_kingside[COLOR_BLACK];
	}
	if (_tmp8_) {
		_tmp7_ = TRUE;
	} else {
		_tmp7_ = self->can_castle_queenside[COLOR_BLACK] != state->can_castle_queenside[COLOR_BLACK];
	}
	if (_tmp7_) {
		_tmp6_ = TRUE;
	} else {
		_tmp6_ = self->en_passant_index != state->en_passant_index;
	}
	if (_tmp6_) {
		_tmp5_ = TRUE;
	} else {
		_tmp5_ = (self->last_move != NULL) != (state->last_move != NULL);
	}
	if (_tmp5_) {
		_tmp4_ = TRUE;
	} else {
		_tmp4_ = self->last_move->piece->type != state->last_move->piece->type;
	}
	if (_tmp4_) {
		_tmp3_ = TRUE;
	} else {
		_tmp3_ = self->last_move->r0 != state->last_move->r0;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = self->last_move->f0 != state->last_move->f0;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = self->last_move->r1 != state->last_move->r1;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->last_move->f1 != state->last_move->f1;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	{
		gint i;
		i = 0;
		{
			gboolean _tmp12_;
			_tmp12_ = TRUE;
			while (TRUE) {
				gboolean _tmp13_ = FALSE;
				if (!_tmp12_) {
					i++;
				}
				_tmp12_ = FALSE;
				if (!(i < 64)) {
					break;
				}
				if (self->board[i] != NULL) {
					_tmp13_ = self->board[i]->type != state->board[i]->type;
				} else {
					_tmp13_ = FALSE;
				}
				if (_tmp13_) {
					result = FALSE;
					return result;
				}
			}
		}
	}
	result = TRUE;
	return result;
}


gchar* chess_state_get_fen (ChessState* self) {
	gchar* result = NULL;
	GString* _tmp0_ = NULL;
	GString* value;
	gchar* _tmp8_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_string_new ("");
	value = _tmp0_;
	{
		gint rank;
		rank = 7;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				gint skip_count;
				if (!_tmp1_) {
					rank--;
				}
				_tmp1_ = FALSE;
				if (!(rank >= 0)) {
					break;
				}
				skip_count = 0;
				{
					gint file;
					file = 0;
					{
						gboolean _tmp2_;
						_tmp2_ = TRUE;
						while (TRUE) {
							gint _tmp3_;
							ChessPiece* _tmp4_;
							ChessPiece* p;
							if (!_tmp2_) {
								file++;
							}
							_tmp2_ = FALSE;
							if (!(file < 8)) {
								break;
							}
							_tmp3_ = chess_state_get_index (self, rank, file);
							_tmp4_ = _chess_piece_ref0 (self->board[_tmp3_]);
							p = _tmp4_;
							if (p == NULL) {
								skip_count++;
							} else {
								gunichar _tmp5_;
								if (skip_count > 0) {
									g_string_append_printf (value, "%d", skip_count);
									skip_count = 0;
								}
								_tmp5_ = chess_piece_get_symbol (p);
								g_string_append_printf (value, "%c", (gint) _tmp5_);
							}
							_chess_piece_unref0 (p);
						}
					}
				}
				if (skip_count > 0) {
					g_string_append_printf (value, "%d", skip_count);
				}
				if (rank != 0) {
					g_string_append_c (value, '/');
				}
			}
		}
	}
	g_string_append_c (value, ' ');
	if (self->current_player->color == COLOR_WHITE) {
		g_string_append_c (value, 'w');
	} else {
		g_string_append_c (value, 'b');
	}
	g_string_append_c (value, ' ');
	if (self->can_castle_kingside[COLOR_WHITE]) {
		g_string_append_c (value, 'K');
	}
	if (self->can_castle_queenside[COLOR_WHITE]) {
		g_string_append_c (value, 'Q');
	}
	if (self->can_castle_kingside[COLOR_BLACK]) {
		g_string_append_c (value, 'k');
	}
	if (self->can_castle_queenside[COLOR_BLACK]) {
		g_string_append_c (value, 'q');
	}
	if (!(((self->can_castle_kingside[COLOR_WHITE] | self->can_castle_queenside[COLOR_WHITE]) | self->can_castle_kingside[COLOR_BLACK]) | self->can_castle_queenside[COLOR_BLACK])) {
		g_string_append_c (value, '-');
	}
	g_string_append_c (value, ' ');
	if (self->en_passant_index >= 0) {
		gint _tmp6_;
		gint _tmp7_;
		_tmp6_ = chess_state_get_file (self, self->en_passant_index);
		_tmp7_ = chess_state_get_rank (self, self->en_passant_index);
		g_string_append_printf (value, "%c%d", 'a' + _tmp6_, _tmp7_ + 1);
	} else {
		g_string_append_c (value, '-');
	}
	g_string_append_c (value, ' ');
	g_string_append_printf (value, "%d", self->halfmove_clock);
	g_string_append_c (value, ' ');
	if (self->current_player->color == COLOR_WHITE) {
		g_string_append_printf (value, "%d", self->number / 2);
	} else {
		g_string_append_printf (value, "%d", (self->number / 2) + 1);
	}
	_tmp8_ = g_strdup (value->str);
	result = _tmp8_;
	_g_string_free0 (value);
	return result;
}


gint chess_state_get_index (ChessState* self, gint rank, gint file) {
	gint result = 0;
	g_return_val_if_fail (self != NULL, 0);
	result = (rank * 8) + file;
	return result;
}


gint chess_state_get_rank (ChessState* self, gint index) {
	gint result = 0;
	g_return_val_if_fail (self != NULL, 0);
	result = index / 8;
	return result;
}


gint chess_state_get_file (ChessState* self, gint index) {
	gint result = 0;
	g_return_val_if_fail (self != NULL, 0);
	result = index % 8;
	return result;
}


gboolean chess_state_move (ChessState* self, const gchar* move, gboolean apply) {
	gboolean result = FALSE;
	gint r0 = 0;
	gint f0 = 0;
	gint r1 = 0;
	gint f1 = 0;
	PieceType promotion_type = 0;
	gint _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	PieceType _tmp4_;
	gboolean _tmp5_;
	gboolean _tmp6_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (move != NULL, FALSE);
	_tmp5_ = chess_state_decode_move (self, self->current_player, move, &_tmp0_, &_tmp1_, &_tmp2_, &_tmp3_, &_tmp4_);
	r0 = _tmp0_;
	f0 = _tmp1_;
	r1 = _tmp2_;
	f1 = _tmp3_;
	promotion_type = _tmp4_;
	if (!_tmp5_) {
		result = FALSE;
		return result;
	}
	_tmp6_ = chess_state_move_with_coords (self, self->current_player, r0, f0, r1, f1, promotion_type, apply, TRUE);
	if (!_tmp6_) {
		result = FALSE;
		return result;
	}
	result = TRUE;
	return result;
}


gboolean chess_state_move_with_coords (ChessState* self, ChessPlayer* player, gint r0, gint f0, gint r1, gint f1, PieceType promotion_type, gboolean apply, gboolean test_check) {
	gboolean result = FALSE;
	gint _tmp0_;
	gint start;
	gint _tmp1_;
	gint end;
	Color color;
	Color _tmp2_ = 0;
	Color opponent_color;
	ChessPiece* _tmp3_;
	ChessPiece* piece;
	gboolean _tmp4_ = FALSE;
	gint64 end_mask;
	gint64 move_mask;
	gint64 over_mask;
	ChessPiece* _tmp5_;
	ChessPiece* victim;
	gint victim_index;
	gboolean _tmp6_ = FALSE;
	gboolean _tmp7_ = FALSE;
	gint rook_start;
	gint rook_end;
	gboolean is_promotion;
	gboolean ambiguous_rank;
	gboolean ambiguous_file;
	gboolean _tmp25_ = FALSE;
	gint64 old_white_mask;
	gint64 old_black_mask;
	gboolean old_white_can_castle_kingside;
	gboolean old_white_can_castle_queenside;
	gboolean old_black_can_castle_kingside;
	gboolean old_black_can_castle_queenside;
	gint old_en_passant_index;
	gint old_halfmove_clock;
	ChessPiece* _tmp33_;
	gboolean _tmp44_ = FALSE;
	gboolean _tmp46_ = FALSE;
	gboolean _result_;
	gboolean _tmp47_ = FALSE;
	gboolean _tmp49_ = FALSE;
	ChessPlayer* _tmp59_ = NULL;
	ChessPlayer* _tmp60_;
	CheckState _tmp61_;
	ChessMove* _tmp62_ = NULL;
	ChessPiece* _tmp63_;
	ChessPiece* _tmp65_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	_tmp0_ = chess_state_get_index (self, r0, f0);
	start = _tmp0_;
	_tmp1_ = chess_state_get_index (self, r1, f1);
	end = _tmp1_;
	color = player->color;
	if (color == COLOR_WHITE) {
		_tmp2_ = COLOR_BLACK;
	} else {
		_tmp2_ = COLOR_WHITE;
	}
	opponent_color = _tmp2_;
	_tmp3_ = _chess_piece_ref0 (self->board[start]);
	piece = _tmp3_;
	if (piece == NULL) {
		_tmp4_ = TRUE;
	} else {
		_tmp4_ = piece->player != player;
	}
	if (_tmp4_) {
		result = FALSE;
		_chess_piece_unref0 (piece);
		return result;
	}
	end_mask = BIT_BOARD_set_location_masks[end];
	move_mask = BIT_BOARD_move_masks[(((color * 64) * 6) + (piece->type * 64)) + start];
	if ((end_mask & move_mask) == 0) {
		result = FALSE;
		_chess_piece_unref0 (piece);
		return result;
	}
	over_mask = BIT_BOARD_over_masks[(start * 64) + end];
	if ((over_mask & (self->priv->piece_masks[COLOR_WHITE] | self->priv->piece_masks[COLOR_BLACK])) != 0) {
		result = FALSE;
		_chess_piece_unref0 (piece);
		return result;
	}
	_tmp5_ = _chess_piece_ref0 (self->board[end]);
	victim = _tmp5_;
	victim_index = end;
	if (victim != NULL) {
		_tmp6_ = victim->player == player;
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		result = FALSE;
		_chess_piece_unref0 (victim);
		_chess_piece_unref0 (piece);
		return result;
	}
	if (victim == NULL) {
		_tmp7_ = end == self->en_passant_index;
	} else {
		_tmp7_ = FALSE;
	}
	if (_tmp7_) {
		gint _tmp8_ = 0;
		gint _tmp9_;
		ChessPiece* _tmp10_;
		if (r1 == 2) {
			_tmp8_ = 3;
		} else {
			_tmp8_ = 4;
		}
		_tmp9_ = chess_state_get_index (self, _tmp8_, f1);
		victim_index = _tmp9_;
		_tmp10_ = _chess_piece_ref0 (self->board[victim_index]);
		_chess_piece_unref0 (victim);
		victim = _tmp10_;
	}
	rook_start = -1;
	rook_end = -1;
	is_promotion = FALSE;
	ambiguous_rank = FALSE;
	ambiguous_file = FALSE;
	switch (piece->type) {
		case PIECE_TYPE_PAWN:
		{
			gboolean _tmp11_ = FALSE;
			if (f0 != f1) {
				if (victim == NULL) {
					result = FALSE;
					_chess_piece_unref0 (victim);
					_chess_piece_unref0 (piece);
					return result;
				}
			} else {
				if (victim != NULL) {
					result = FALSE;
					_chess_piece_unref0 (victim);
					_chess_piece_unref0 (piece);
					return result;
				}
			}
			if (r1 == 0) {
				_tmp11_ = TRUE;
			} else {
				_tmp11_ = r1 == 7;
			}
			is_promotion = _tmp11_;
			if (victim != NULL) {
				ambiguous_file = TRUE;
			}
			break;
		}
		case PIECE_TYPE_KING:
		{
			gint _tmp12_;
			_tmp12_ = abs (f0 - f1);
			if (_tmp12_ > 1) {
				gint _tmp13_ = 0;
				gint _tmp14_;
				gint _tmp15_ = 0;
				gint _tmp16_;
				ChessPiece* _tmp17_;
				ChessPiece* rook;
				gint64 rook_over_mask;
				if (f1 > f0) {
					_tmp13_ = 7;
				} else {
					_tmp13_ = 0;
				}
				_tmp14_ = chess_state_get_index (self, r0, _tmp13_);
				rook_start = _tmp14_;
				if (f1 > f0) {
					_tmp15_ = f1 - 1;
				} else {
					_tmp15_ = f1 + 1;
				}
				_tmp16_ = chess_state_get_index (self, r0, _tmp15_);
				rook_end = _tmp16_;
				if (f1 > f0) {
					if (!self->can_castle_kingside[color]) {
						result = FALSE;
						_chess_piece_unref0 (victim);
						_chess_piece_unref0 (piece);
						return result;
					}
				} else {
					if (!self->can_castle_queenside[color]) {
						result = FALSE;
						_chess_piece_unref0 (victim);
						_chess_piece_unref0 (piece);
						return result;
					}
				}
				_tmp17_ = _chess_piece_ref0 (self->board[rook_start]);
				rook = _tmp17_;
				if (rook == NULL) {
					result = FALSE;
					_chess_piece_unref0 (rook);
					_chess_piece_unref0 (victim);
					_chess_piece_unref0 (piece);
					return result;
				}
				rook_over_mask = BIT_BOARD_over_masks[(rook_start * 64) + rook_end];
				if ((rook_over_mask & (self->priv->piece_masks[COLOR_WHITE] | self->priv->piece_masks[COLOR_BLACK])) != 0) {
					result = FALSE;
					_chess_piece_unref0 (rook);
					_chess_piece_unref0 (victim);
					_chess_piece_unref0 (piece);
					return result;
				}
				if (self->check_state == CHECK_STATE_CHECK) {
					result = FALSE;
					_chess_piece_unref0 (rook);
					_chess_piece_unref0 (victim);
					_chess_piece_unref0 (piece);
					return result;
				}
				{
					gint i;
					i = 0;
					{
						gboolean _tmp18_;
						_tmp18_ = TRUE;
						while (TRUE) {
							ChessPlayer* _tmp19_ = NULL;
							gint _tmp20_;
							gint _tmp21_;
							gint _tmp22_;
							gint _tmp23_;
							gboolean _tmp24_;
							if (!_tmp18_) {
								i++;
							}
							_tmp18_ = FALSE;
							if (!(i < 64)) {
								break;
							}
							_tmp19_ = chess_state_get_opponent (self);
							_tmp20_ = chess_state_get_rank (self, i);
							_tmp21_ = chess_state_get_file (self, i);
							_tmp22_ = chess_state_get_rank (self, rook_end);
							_tmp23_ = chess_state_get_file (self, rook_end);
							_tmp24_ = chess_state_move_with_coords (self, _tmp19_, _tmp20_, _tmp21_, _tmp22_, _tmp23_, PIECE_TYPE_QUEEN, FALSE, FALSE);
							if (_tmp24_) {
								result = FALSE;
								_chess_piece_unref0 (rook);
								_chess_piece_unref0 (victim);
								_chess_piece_unref0 (piece);
								return result;
							}
						}
					}
				}
				_chess_piece_unref0 (rook);
			}
			break;
		}
		default:
		{
			break;
		}
	}
	if (!apply) {
		_tmp25_ = !test_check;
	} else {
		_tmp25_ = FALSE;
	}
	if (_tmp25_) {
		result = TRUE;
		_chess_piece_unref0 (victim);
		_chess_piece_unref0 (piece);
		return result;
	}
	if (apply) {
		{
			gint i;
			i = 0;
			{
				gboolean _tmp26_;
				_tmp26_ = TRUE;
				while (TRUE) {
					ChessPiece* _tmp27_;
					ChessPiece* p;
					gboolean _tmp28_ = FALSE;
					gboolean _tmp29_ = FALSE;
					gint _tmp30_;
					gint r;
					gint _tmp31_;
					gint f;
					gboolean _tmp32_;
					if (!_tmp26_) {
						i++;
					}
					_tmp26_ = FALSE;
					if (!(i < 64)) {
						break;
					}
					if (i == start) {
						continue;
					}
					_tmp27_ = _chess_piece_ref0 (self->board[i]);
					p = _tmp27_;
					if (p == NULL) {
						_tmp29_ = TRUE;
					} else {
						_tmp29_ = p->player != player;
					}
					if (_tmp29_) {
						_tmp28_ = TRUE;
					} else {
						_tmp28_ = p->type != piece->type;
					}
					if (_tmp28_) {
						_chess_piece_unref0 (p);
						continue;
					}
					_tmp30_ = chess_state_get_rank (self, i);
					r = _tmp30_;
					_tmp31_ = chess_state_get_file (self, i);
					f = _tmp31_;
					_tmp32_ = chess_state_move_with_coords (self, player, r, f, r1, f1, PIECE_TYPE_QUEEN, FALSE, TRUE);
					if (_tmp32_) {
						if (r != r0) {
							ambiguous_rank = TRUE;
						}
						if (f != f0) {
							ambiguous_file = TRUE;
						}
					}
					_chess_piece_unref0 (p);
				}
			}
		}
	}
	old_white_mask = self->priv->piece_masks[COLOR_WHITE];
	old_black_mask = self->priv->piece_masks[COLOR_BLACK];
	old_white_can_castle_kingside = self->can_castle_kingside[COLOR_WHITE];
	old_white_can_castle_queenside = self->can_castle_queenside[COLOR_WHITE];
	old_black_can_castle_kingside = self->can_castle_kingside[COLOR_BLACK];
	old_black_can_castle_queenside = self->can_castle_queenside[COLOR_BLACK];
	old_en_passant_index = self->en_passant_index;
	old_halfmove_clock = self->halfmove_clock;
	_tmp33_ = NULL;
	_chess_piece_unref0 (self->board[start]);
	self->board[start] = _tmp33_;
	if (victim != NULL) {
		ChessPiece* _tmp34_;
		_tmp34_ = NULL;
		_chess_piece_unref0 (self->board[victim_index]);
		self->board[victim_index] = _tmp34_;
	}
	if (is_promotion) {
		ChessPiece* _tmp35_ = NULL;
		ChessPiece* _tmp36_;
		_tmp35_ = chess_piece_new (player, promotion_type);
		_tmp36_ = _tmp35_;
		_chess_piece_unref0 (self->board[end]);
		self->board[end] = _tmp36_;
	} else {
		ChessPiece* _tmp37_;
		ChessPiece* _tmp38_;
		_tmp37_ = _chess_piece_ref0 (piece);
		_tmp38_ = _tmp37_;
		_chess_piece_unref0 (self->board[end]);
		self->board[end] = _tmp38_;
	}
	self->priv->piece_masks[COLOR_WHITE] &= BIT_BOARD_clear_location_masks[start];
	self->priv->piece_masks[COLOR_BLACK] &= BIT_BOARD_clear_location_masks[start];
	self->priv->piece_masks[color] |= end_mask;
	self->priv->piece_masks[opponent_color] &= BIT_BOARD_clear_location_masks[end];
	if (rook_start >= 0) {
		ChessPiece* _tmp39_;
		ChessPiece* rook;
		ChessPiece* _tmp40_;
		ChessPiece* _tmp41_;
		ChessPiece* _tmp42_;
		_tmp39_ = _chess_piece_ref0 (self->board[rook_start]);
		rook = _tmp39_;
		_tmp40_ = NULL;
		_chess_piece_unref0 (self->board[rook_start]);
		self->board[rook_start] = _tmp40_;
		_tmp41_ = _chess_piece_ref0 (rook);
		_tmp42_ = _tmp41_;
		_chess_piece_unref0 (self->board[rook_end]);
		self->board[rook_end] = _tmp42_;
		self->priv->piece_masks[color] &= BIT_BOARD_clear_location_masks[rook_start];
		self->priv->piece_masks[color] |= BIT_BOARD_set_location_masks[rook_end];
		_chess_piece_unref0 (rook);
	}
	if (piece->type == PIECE_TYPE_KING) {
		self->can_castle_kingside[color] = FALSE;
		self->can_castle_queenside[color] = FALSE;
	} else {
		if (piece->type == PIECE_TYPE_ROOK) {
			gint _tmp43_ = 0;
			gint base_rank;
			if (color == COLOR_WHITE) {
				_tmp43_ = 0;
			} else {
				_tmp43_ = 7;
			}
			base_rank = _tmp43_;
			if (r0 == base_rank) {
				if (f0 == 0) {
					self->can_castle_queenside[color] = FALSE;
				} else {
					if (f0 == 7) {
						self->can_castle_kingside[color] = FALSE;
					}
				}
			}
		}
	}
	if (piece->type == PIECE_TYPE_PAWN) {
		_tmp44_ = over_mask != 0;
	} else {
		_tmp44_ = FALSE;
	}
	if (_tmp44_) {
		gint _tmp45_;
		_tmp45_ = chess_state_get_index (self, (r0 + r1) / 2, f0);
		self->en_passant_index = _tmp45_;
	} else {
		self->en_passant_index = -1;
	}
	if (piece->type == PIECE_TYPE_PAWN) {
		_tmp46_ = TRUE;
	} else {
		_tmp46_ = victim != NULL;
	}
	if (_tmp46_) {
		self->halfmove_clock = 0;
	} else {
		self->halfmove_clock++;
	}
	_result_ = TRUE;
	if (test_check) {
		gboolean _tmp48_;
		_tmp48_ = chess_state_is_in_check (self, player);
		_tmp47_ = _tmp48_;
	} else {
		_tmp47_ = FALSE;
	}
	if (_tmp47_) {
		_result_ = FALSE;
	}
	if (!apply) {
		_tmp49_ = TRUE;
	} else {
		_tmp49_ = !_result_;
	}
	if (_tmp49_) {
		ChessPiece* _tmp50_;
		ChessPiece* _tmp51_;
		ChessPiece* _tmp52_;
		_tmp50_ = _chess_piece_ref0 (piece);
		_tmp51_ = _tmp50_;
		_chess_piece_unref0 (self->board[start]);
		self->board[start] = _tmp51_;
		_tmp52_ = NULL;
		_chess_piece_unref0 (self->board[end]);
		self->board[end] = _tmp52_;
		if (victim != NULL) {
			ChessPiece* _tmp53_;
			ChessPiece* _tmp54_;
			_tmp53_ = _chess_piece_ref0 (victim);
			_tmp54_ = _tmp53_;
			_chess_piece_unref0 (self->board[victim_index]);
			self->board[victim_index] = _tmp54_;
		}
		if (rook_start >= 0) {
			ChessPiece* _tmp55_;
			ChessPiece* rook;
			ChessPiece* _tmp56_;
			ChessPiece* _tmp57_;
			ChessPiece* _tmp58_;
			_tmp55_ = _chess_piece_ref0 (self->board[rook_end]);
			rook = _tmp55_;
			_tmp56_ = _chess_piece_ref0 (rook);
			_tmp57_ = _tmp56_;
			_chess_piece_unref0 (self->board[rook_start]);
			self->board[rook_start] = _tmp57_;
			_tmp58_ = NULL;
			_chess_piece_unref0 (self->board[rook_end]);
			self->board[rook_end] = _tmp58_;
			_chess_piece_unref0 (rook);
		}
		self->priv->piece_masks[COLOR_WHITE] = old_white_mask;
		self->priv->piece_masks[COLOR_BLACK] = old_black_mask;
		self->can_castle_kingside[COLOR_WHITE] = old_white_can_castle_kingside;
		self->can_castle_queenside[COLOR_WHITE] = old_white_can_castle_queenside;
		self->can_castle_kingside[COLOR_BLACK] = old_black_can_castle_kingside;
		self->can_castle_queenside[COLOR_BLACK] = old_black_can_castle_queenside;
		self->en_passant_index = old_en_passant_index;
		self->halfmove_clock = old_halfmove_clock;
		result = _result_;
		_chess_piece_unref0 (victim);
		_chess_piece_unref0 (piece);
		return result;
	}
	if (color == COLOR_WHITE) {
		_tmp59_ = self->players[COLOR_BLACK];
	} else {
		_tmp59_ = self->players[COLOR_WHITE];
	}
	_tmp60_ = _g_object_ref0 (_tmp59_);
	_g_object_unref0 (self->current_player);
	self->current_player = _tmp60_;
	_tmp61_ = chess_state_get_check_state (self, self->current_player);
	self->check_state = _tmp61_;
	_tmp62_ = chess_move_new ();
	_chess_move_unref0 (self->last_move);
	self->last_move = _tmp62_;
	self->last_move->number = self->number;
	_tmp63_ = _chess_piece_ref0 (piece);
	_chess_piece_unref0 (self->last_move->piece);
	self->last_move->piece = _tmp63_;
	if (is_promotion) {
		ChessPiece* _tmp64_;
		_tmp64_ = _chess_piece_ref0 (self->board[end]);
		_chess_piece_unref0 (self->last_move->promotion_piece);
		self->last_move->promotion_piece = _tmp64_;
	}
	_tmp65_ = _chess_piece_ref0 (victim);
	_chess_piece_unref0 (self->last_move->victim);
	self->last_move->victim = _tmp65_;
	if (rook_end >= 0) {
		ChessPiece* _tmp66_;
		_tmp66_ = _chess_piece_ref0 (self->board[rook_end]);
		_chess_piece_unref0 (self->last_move->moved_rook);
		self->last_move->moved_rook = _tmp66_;
	}
	self->last_move->r0 = r0;
	self->last_move->f0 = f0;
	self->last_move->r1 = r1;
	self->last_move->f1 = f1;
	self->last_move->ambiguous_rank = ambiguous_rank;
	self->last_move->ambiguous_file = ambiguous_file;
	self->last_move->check_state = self->check_state;
	result = TRUE;
	_chess_piece_unref0 (victim);
	_chess_piece_unref0 (piece);
	return result;
}


ChessResult chess_state_get_result (ChessState* self, ChessRule* rule) {
	ChessRule _rule = 0;
	ChessResult result = 0;
	gboolean _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	g_return_val_if_fail (self != NULL, 0);
	if (self->check_state == CHECK_STATE_CHECKMATE) {
		if (self->current_player->color == COLOR_WHITE) {
			_rule = CHESS_RULE_CHECKMATE;
			result = CHESS_RESULT_BLACK_WON;
			if (rule) {
				*rule = _rule;
			}
			return result;
		} else {
			_rule = CHESS_RULE_CHECKMATE;
			result = CHESS_RESULT_WHITE_WON;
			if (rule) {
				*rule = _rule;
			}
			return result;
		}
	}
	_tmp0_ = chess_state_can_move (self, self->current_player);
	if (!_tmp0_) {
		_rule = CHESS_RULE_STALEMATE;
		result = CHESS_RESULT_DRAW;
		if (rule) {
			*rule = _rule;
		}
		return result;
	}
	if (self->last_move != NULL) {
		_tmp2_ = self->last_move->victim != NULL;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		gboolean _tmp3_;
		_tmp3_ = chess_state_have_sufficient_material (self);
		_tmp1_ = !_tmp3_;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_rule = CHESS_RULE_INSUFFICIENT_MATERIAL;
		result = CHESS_RESULT_DRAW;
		if (rule) {
			*rule = _rule;
		}
		return result;
	}
	result = CHESS_RESULT_IN_PROGRESS;
	if (rule) {
		*rule = _rule;
	}
	return result;
}


static CheckState chess_state_get_check_state (ChessState* self, ChessPlayer* player) {
	CheckState result = 0;
	gboolean _tmp0_;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (player != NULL, 0);
	_tmp0_ = chess_state_is_in_check (self, player);
	if (_tmp0_) {
		gboolean _tmp1_;
		_tmp1_ = chess_state_is_in_checkmate (self, player);
		if (_tmp1_) {
			result = CHECK_STATE_CHECKMATE;
			return result;
		} else {
			result = CHECK_STATE_CHECK;
			return result;
		}
	}
	result = CHECK_STATE_NONE;
	return result;
}


static gboolean chess_state_is_in_check (ChessState* self, ChessPlayer* player) {
	gboolean result = FALSE;
	ChessPlayer* _tmp0_ = NULL;
	ChessPlayer* _tmp1_;
	ChessPlayer* opponent;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	if (player->color == COLOR_WHITE) {
		_tmp0_ = self->players[COLOR_BLACK];
	} else {
		_tmp0_ = self->players[COLOR_WHITE];
	}
	_tmp1_ = _g_object_ref0 (_tmp0_);
	opponent = _tmp1_;
	{
		gint king_index;
		king_index = 0;
		{
			gboolean _tmp2_;
			_tmp2_ = TRUE;
			while (TRUE) {
				ChessPiece* _tmp3_;
				ChessPiece* p;
				gboolean _tmp4_ = FALSE;
				gboolean _tmp5_ = FALSE;
				if (!_tmp2_) {
					king_index++;
				}
				_tmp2_ = FALSE;
				if (!(king_index < 64)) {
					break;
				}
				_tmp3_ = _chess_piece_ref0 (self->board[king_index]);
				p = _tmp3_;
				if (p != NULL) {
					_tmp5_ = p->player == player;
				} else {
					_tmp5_ = FALSE;
				}
				if (_tmp5_) {
					_tmp4_ = p->type == PIECE_TYPE_KING;
				} else {
					_tmp4_ = FALSE;
				}
				if (_tmp4_) {
					{
						gint start;
						start = 0;
						{
							gboolean _tmp6_;
							_tmp6_ = TRUE;
							while (TRUE) {
								gint _tmp7_;
								gint _tmp8_;
								gint _tmp9_;
								gint _tmp10_;
								gboolean _tmp11_;
								if (!_tmp6_) {
									start++;
								}
								_tmp6_ = FALSE;
								if (!(start < 64)) {
									break;
								}
								_tmp7_ = chess_state_get_rank (self, start);
								_tmp8_ = chess_state_get_file (self, start);
								_tmp9_ = chess_state_get_rank (self, king_index);
								_tmp10_ = chess_state_get_file (self, king_index);
								_tmp11_ = chess_state_move_with_coords (self, opponent, _tmp7_, _tmp8_, _tmp9_, _tmp10_, PIECE_TYPE_QUEEN, FALSE, FALSE);
								if (_tmp11_) {
									result = TRUE;
									_chess_piece_unref0 (p);
									_g_object_unref0 (opponent);
									return result;
								}
							}
						}
					}
				}
				_chess_piece_unref0 (p);
			}
		}
	}
	result = FALSE;
	_g_object_unref0 (opponent);
	return result;
}


static gboolean chess_state_is_in_checkmate (ChessState* self, ChessPlayer* player) {
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	{
		gint piece_index;
		piece_index = 0;
		{
			gboolean _tmp0_;
			_tmp0_ = TRUE;
			while (TRUE) {
				ChessPiece* _tmp1_;
				ChessPiece* p;
				gboolean _tmp2_ = FALSE;
				if (!_tmp0_) {
					piece_index++;
				}
				_tmp0_ = FALSE;
				if (!(piece_index < 64)) {
					break;
				}
				_tmp1_ = _chess_piece_ref0 (self->board[piece_index]);
				p = _tmp1_;
				if (p != NULL) {
					_tmp2_ = p->player == player;
				} else {
					_tmp2_ = FALSE;
				}
				if (_tmp2_) {
					{
						gint end;
						end = 0;
						{
							gboolean _tmp3_;
							_tmp3_ = TRUE;
							while (TRUE) {
								gint _tmp4_;
								gint _tmp5_;
								gint _tmp6_;
								gint _tmp7_;
								gboolean _tmp8_;
								if (!_tmp3_) {
									end++;
								}
								_tmp3_ = FALSE;
								if (!(end < 64)) {
									break;
								}
								_tmp4_ = chess_state_get_rank (self, piece_index);
								_tmp5_ = chess_state_get_file (self, piece_index);
								_tmp6_ = chess_state_get_rank (self, end);
								_tmp7_ = chess_state_get_file (self, end);
								_tmp8_ = chess_state_move_with_coords (self, player, _tmp4_, _tmp5_, _tmp6_, _tmp7_, PIECE_TYPE_QUEEN, FALSE, TRUE);
								if (_tmp8_) {
									result = FALSE;
									_chess_piece_unref0 (p);
									return result;
								}
							}
						}
					}
				}
				_chess_piece_unref0 (p);
			}
		}
	}
	result = TRUE;
	return result;
}


static gboolean chess_state_can_move (ChessState* self, ChessPlayer* player) {
	gboolean result = FALSE;
	gboolean have_pieces;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	have_pieces = FALSE;
	{
		gint start;
		start = 0;
		{
			gboolean _tmp0_;
			_tmp0_ = TRUE;
			while (TRUE) {
				ChessPiece* _tmp1_;
				ChessPiece* p;
				gboolean _tmp2_ = FALSE;
				if (!_tmp0_) {
					start++;
				}
				_tmp0_ = FALSE;
				if (!(start < 64)) {
					break;
				}
				_tmp1_ = _chess_piece_ref0 (self->board[start]);
				p = _tmp1_;
				if (p != NULL) {
					_tmp2_ = p->player == player;
				} else {
					_tmp2_ = FALSE;
				}
				if (_tmp2_) {
					have_pieces = TRUE;
					{
						gint end;
						end = 0;
						{
							gboolean _tmp3_;
							_tmp3_ = TRUE;
							while (TRUE) {
								gint _tmp4_;
								gint _tmp5_;
								gint _tmp6_;
								gint _tmp7_;
								gboolean _tmp8_;
								if (!_tmp3_) {
									end++;
								}
								_tmp3_ = FALSE;
								if (!(end < 64)) {
									break;
								}
								_tmp4_ = chess_state_get_rank (self, start);
								_tmp5_ = chess_state_get_file (self, start);
								_tmp6_ = chess_state_get_rank (self, end);
								_tmp7_ = chess_state_get_file (self, end);
								_tmp8_ = chess_state_move_with_coords (self, player, _tmp4_, _tmp5_, _tmp6_, _tmp7_, PIECE_TYPE_QUEEN, FALSE, TRUE);
								if (_tmp8_) {
									result = TRUE;
									_chess_piece_unref0 (p);
									return result;
								}
							}
						}
					}
				}
				_chess_piece_unref0 (p);
			}
		}
	}
	if (have_pieces) {
		result = FALSE;
		return result;
	} else {
		result = TRUE;
		return result;
	}
}


gboolean chess_state_have_sufficient_material (ChessState* self) {
	gboolean result = FALSE;
	gint white_knight_count;
	gint white_bishop_count;
	gboolean white_bishop_on_white_square;
	gboolean white_bishop_on_black_square;
	gint black_knight_count;
	gint black_bishop_count;
	gboolean black_bishop_on_white_square;
	gboolean black_bishop_on_black_square;
	g_return_val_if_fail (self != NULL, FALSE);
	white_knight_count = 0;
	white_bishop_count = 0;
	white_bishop_on_white_square = FALSE;
	white_bishop_on_black_square = FALSE;
	black_knight_count = 0;
	black_bishop_count = 0;
	black_bishop_on_white_square = FALSE;
	black_bishop_on_black_square = FALSE;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp0_;
			_tmp0_ = TRUE;
			while (TRUE) {
				ChessPiece* _tmp1_;
				ChessPiece* p;
				gboolean _tmp2_ = FALSE;
				gboolean _tmp3_ = FALSE;
				gboolean _tmp6_ = FALSE;
				gboolean _tmp7_ = FALSE;
				gboolean _tmp8_ = FALSE;
				gboolean _tmp9_ = FALSE;
				gboolean _tmp10_ = FALSE;
				if (!_tmp0_) {
					i++;
				}
				_tmp0_ = FALSE;
				if (!(i < 64)) {
					break;
				}
				_tmp1_ = _chess_piece_ref0 (self->board[i]);
				p = _tmp1_;
				if (p == NULL) {
					_chess_piece_unref0 (p);
					continue;
				}
				if (p->type == PIECE_TYPE_PAWN) {
					_tmp3_ = TRUE;
				} else {
					_tmp3_ = p->type == PIECE_TYPE_ROOK;
				}
				if (_tmp3_) {
					_tmp2_ = TRUE;
				} else {
					_tmp2_ = p->type == PIECE_TYPE_QUEEN;
				}
				if (_tmp2_) {
					result = TRUE;
					_chess_piece_unref0 (p);
					return result;
				}
				if (p->type == PIECE_TYPE_KNIGHT) {
					Color _tmp4_;
					_tmp4_ = chess_piece_get_color (p);
					if (_tmp4_ == COLOR_WHITE) {
						white_knight_count++;
					} else {
						black_knight_count++;
					}
				}
				if (p->type == PIECE_TYPE_BISHOP) {
					Color color;
					Color _tmp5_;
					color = COLOR_BLACK;
					if (((i + (i / 8)) % 2) != 0) {
						color = COLOR_WHITE;
					}
					_tmp5_ = chess_piece_get_color (p);
					if (_tmp5_ == COLOR_WHITE) {
						if (color == COLOR_WHITE) {
							white_bishop_on_white_square = TRUE;
						} else {
							white_bishop_on_black_square = TRUE;
						}
						white_bishop_count++;
					} else {
						if (color == COLOR_WHITE) {
							black_bishop_on_white_square = TRUE;
						} else {
							black_bishop_on_black_square = TRUE;
						}
						black_bishop_count++;
					}
				}
				if (white_knight_count > 2) {
					_tmp6_ = TRUE;
				} else {
					_tmp6_ = black_knight_count > 2;
				}
				if (_tmp6_) {
					result = TRUE;
					_chess_piece_unref0 (p);
					return result;
				}
				if (white_bishop_count > 0) {
					_tmp7_ = white_knight_count > 0;
				} else {
					_tmp7_ = FALSE;
				}
				if (_tmp7_) {
					result = TRUE;
					_chess_piece_unref0 (p);
					return result;
				}
				if (black_bishop_count > 0) {
					_tmp8_ = black_knight_count > 0;
				} else {
					_tmp8_ = FALSE;
				}
				if (_tmp8_) {
					result = TRUE;
					_chess_piece_unref0 (p);
					return result;
				}
				if (white_bishop_on_white_square) {
					_tmp9_ = white_bishop_on_black_square;
				} else {
					_tmp9_ = FALSE;
				}
				if (_tmp9_) {
					result = TRUE;
					_chess_piece_unref0 (p);
					return result;
				}
				if (black_bishop_on_white_square) {
					_tmp10_ = black_bishop_on_black_square;
				} else {
					_tmp10_ = FALSE;
				}
				if (_tmp10_) {
					result = TRUE;
					_chess_piece_unref0 (p);
					return result;
				}
				_chess_piece_unref0 (p);
			}
		}
	}
	result = FALSE;
	return result;
}


static gboolean chess_state_decode_piece_type (ChessState* self, gunichar c, PieceType* type) {
	PieceType _type = 0;
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	switch (c) {
		case 'P':
		{
			_type = PIECE_TYPE_PAWN;
			result = TRUE;
			if (type) {
				*type = _type;
			}
			return result;
		}
		case 'R':
		{
			_type = PIECE_TYPE_ROOK;
			result = TRUE;
			if (type) {
				*type = _type;
			}
			return result;
		}
		case 'N':
		{
			_type = PIECE_TYPE_KNIGHT;
			result = TRUE;
			if (type) {
				*type = _type;
			}
			return result;
		}
		case 'B':
		{
			_type = PIECE_TYPE_BISHOP;
			result = TRUE;
			if (type) {
				*type = _type;
			}
			return result;
		}
		case 'Q':
		{
			_type = PIECE_TYPE_QUEEN;
			result = TRUE;
			if (type) {
				*type = _type;
			}
			return result;
		}
		case 'K':
		{
			_type = PIECE_TYPE_KING;
			result = TRUE;
			if (type) {
				*type = _type;
			}
			return result;
		}
		default:
		{
			result = FALSE;
			if (type) {
				*type = _type;
			}
			return result;
		}
	}
	if (type) {
		*type = _type;
	}
}


static gboolean chess_state_decode_move (ChessState* self, ChessPlayer* player, const gchar* move, gint* r0, gint* f0, gint* r1, gint* f1, PieceType* promotion_type) {
	gint _r0 = 0;
	gint _f0 = 0;
	gint _r1 = 0;
	gint _f1 = 0;
	PieceType _promotion_type = 0;
	gboolean result = FALSE;
	gint i;
	gboolean _tmp0_;
	gchar _tmp41_;
	gchar _tmp43_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	g_return_val_if_fail (move != NULL, FALSE);
	i = 0;
	_promotion_type = PIECE_TYPE_QUEEN;
	_tmp0_ = g_str_has_prefix (move, "O-O-O");
	if (_tmp0_) {
		gint _tmp1_;
		if (player->color == COLOR_WHITE) {
			_r1 = 0;
			_r0 = _r1;
		} else {
			_r1 = 7;
			_r0 = _r1;
		}
		_f0 = 4;
		_f1 = 2;
		_tmp1_ = strlen ("O-O-O");
		i = i + ((gint) _tmp1_);
	} else {
		gboolean _tmp2_;
		_tmp2_ = g_str_has_prefix (move, "O-O");
		if (_tmp2_) {
			gint _tmp3_;
			if (player->color == COLOR_WHITE) {
				_r1 = 0;
				_r0 = _r1;
			} else {
				_r1 = 7;
				_r0 = _r1;
			}
			_f0 = 4;
			_f1 = 6;
			_tmp3_ = strlen ("O-O");
			i = i + ((gint) _tmp3_);
		} else {
			PieceType type;
			gchar _tmp4_;
			PieceType _tmp5_;
			gboolean _tmp6_;
			gboolean _tmp7_ = FALSE;
			gchar _tmp8_;
			gboolean _tmp11_ = FALSE;
			gchar _tmp12_;
			gchar _tmp15_;
			gboolean _tmp16_ = FALSE;
			gchar _tmp17_;
			gboolean _tmp20_ = FALSE;
			gchar _tmp21_;
			gchar _tmp24_;
			gboolean _tmp30_ = FALSE;
			gboolean _tmp31_ = FALSE;
			type = PIECE_TYPE_PAWN;
			_tmp4_ = string_get (move, (glong) i);
			_tmp6_ = chess_state_decode_piece_type (self, (gunichar) _tmp4_, &_tmp5_);
			type = _tmp5_;
			if (_tmp6_) {
				i++;
			}
			_f1 = -1;
			_r1 = _f1;
			_f0 = _r1;
			_r0 = _f0;
			_tmp8_ = string_get (move, (glong) i);
			if (_tmp8_ >= 'a') {
				gchar _tmp9_;
				_tmp9_ = string_get (move, (glong) i);
				_tmp7_ = _tmp9_ <= 'h';
			} else {
				_tmp7_ = FALSE;
			}
			if (_tmp7_) {
				gchar _tmp10_;
				_tmp10_ = string_get (move, (glong) i);
				_f1 = (gint) (_tmp10_ - 'a');
				i++;
			}
			_tmp12_ = string_get (move, (glong) i);
			if (_tmp12_ >= '1') {
				gchar _tmp13_;
				_tmp13_ = string_get (move, (glong) i);
				_tmp11_ = _tmp13_ <= '8';
			} else {
				_tmp11_ = FALSE;
			}
			if (_tmp11_) {
				gchar _tmp14_;
				_tmp14_ = string_get (move, (glong) i);
				_r1 = (gint) (_tmp14_ - '1');
				i++;
			}
			_tmp15_ = string_get (move, (glong) i);
			if (_tmp15_ == 'x') {
				i++;
			}
			_tmp17_ = string_get (move, (glong) i);
			if (_tmp17_ >= 'a') {
				gchar _tmp18_;
				_tmp18_ = string_get (move, (glong) i);
				_tmp16_ = _tmp18_ <= 'h';
			} else {
				_tmp16_ = FALSE;
			}
			if (_tmp16_) {
				gchar _tmp19_;
				_f0 = _f1;
				_tmp19_ = string_get (move, (glong) i);
				_f1 = (gint) (_tmp19_ - 'a');
				i++;
			}
			_tmp21_ = string_get (move, (glong) i);
			if (_tmp21_ >= '1') {
				gchar _tmp22_;
				_tmp22_ = string_get (move, (glong) i);
				_tmp20_ = _tmp22_ <= '8';
			} else {
				_tmp20_ = FALSE;
			}
			if (_tmp20_) {
				gchar _tmp23_;
				_r0 = _r1;
				_tmp23_ = string_get (move, (glong) i);
				_r1 = (gint) (_tmp23_ - '1');
				i++;
			}
			_tmp24_ = string_get (move, (glong) i);
			if (_tmp24_ == '=') {
				gchar _tmp25_;
				PieceType _tmp26_;
				gboolean _tmp27_;
				i++;
				_tmp25_ = string_get (move, (glong) i);
				_tmp27_ = chess_state_decode_piece_type (self, (gunichar) _tmp25_, &_tmp26_);
				_promotion_type = _tmp26_;
				if (_tmp27_) {
					i++;
				}
			} else {
				gchar _tmp28_;
				_tmp28_ = string_get (move, (glong) i);
				if (_tmp28_ != '\0') {
					gchar _tmp29_;
					_tmp29_ = string_get (move, (glong) i);
					switch (_tmp29_) {
						case 'q':
						{
							_promotion_type = PIECE_TYPE_QUEEN;
							i++;
							break;
						}
						case 'n':
						{
							_promotion_type = PIECE_TYPE_KNIGHT;
							i++;
							break;
						}
						case 'r':
						{
							_promotion_type = PIECE_TYPE_ROOK;
							i++;
							break;
						}
						case 'b':
						{
							_promotion_type = PIECE_TYPE_BISHOP;
							i++;
							break;
						}
						default:
						break;
					}
				}
			}
			if (_r1 < 0) {
				_tmp30_ = TRUE;
			} else {
				_tmp30_ = _f1 < 0;
			}
			if (_tmp30_) {
				g_debug ("chess-game.vala:1074: Move %s missing destination", move);
				result = FALSE;
				if (r0) {
					*r0 = _r0;
				}
				if (f0) {
					*f0 = _f0;
				}
				if (r1) {
					*r1 = _r1;
				}
				if (f1) {
					*f1 = _f1;
				}
				if (promotion_type) {
					*promotion_type = _promotion_type;
				}
				return result;
			}
			if (_r0 < 0) {
				_tmp31_ = TRUE;
			} else {
				_tmp31_ = _f0 < 0;
			}
			if (_tmp31_) {
				gint match_rank;
				gint match_file;
				match_rank = -1;
				match_file = -1;
				{
					gint file;
					file = 0;
					{
						gboolean _tmp32_;
						_tmp32_ = TRUE;
						while (TRUE) {
							gboolean _tmp33_ = FALSE;
							if (!_tmp32_) {
								file++;
							}
							_tmp32_ = FALSE;
							if (!(file < 8)) {
								break;
							}
							if (_f0 >= 0) {
								_tmp33_ = file != _f0;
							} else {
								_tmp33_ = FALSE;
							}
							if (_tmp33_) {
								continue;
							}
							{
								gint rank;
								rank = 0;
								{
									gboolean _tmp34_;
									_tmp34_ = TRUE;
									while (TRUE) {
										gboolean _tmp35_ = FALSE;
										gint _tmp36_;
										ChessPiece* _tmp37_;
										ChessPiece* piece;
										gboolean _tmp38_ = FALSE;
										gboolean _tmp39_ = FALSE;
										gboolean _tmp40_;
										if (!_tmp34_) {
											rank++;
										}
										_tmp34_ = FALSE;
										if (!(rank < 8)) {
											break;
										}
										if (_r0 >= 0) {
											_tmp35_ = rank != _r0;
										} else {
											_tmp35_ = FALSE;
										}
										if (_tmp35_) {
											continue;
										}
										_tmp36_ = chess_state_get_index (self, rank, file);
										_tmp37_ = _chess_piece_ref0 (self->board[_tmp36_]);
										piece = _tmp37_;
										if (piece == NULL) {
											_tmp39_ = TRUE;
										} else {
											_tmp39_ = piece->type != type;
										}
										if (_tmp39_) {
											_tmp38_ = TRUE;
										} else {
											_tmp38_ = piece->player != player;
										}
										if (_tmp38_) {
											_chess_piece_unref0 (piece);
											continue;
										}
										_tmp40_ = chess_state_move_with_coords (self, player, rank, file, _r1, _f1, PIECE_TYPE_QUEEN, FALSE, TRUE);
										if (!_tmp40_) {
											_chess_piece_unref0 (piece);
											continue;
										}
										if (match_rank >= 0) {
											g_debug ("chess-game.vala:1105: Move %s is ambiguous", move);
											result = FALSE;
											_chess_piece_unref0 (piece);
											if (r0) {
												*r0 = _r0;
											}
											if (f0) {
												*f0 = _f0;
											}
											if (r1) {
												*r1 = _r1;
											}
											if (f1) {
												*f1 = _f1;
											}
											if (promotion_type) {
												*promotion_type = _promotion_type;
											}
											return result;
										}
										match_rank = rank;
										match_file = file;
										_chess_piece_unref0 (piece);
									}
								}
							}
						}
					}
				}
				if (match_rank < 0) {
					g_debug ("chess-game.vala:1116: Move %s has no matches", move);
					result = FALSE;
					if (r0) {
						*r0 = _r0;
					}
					if (f0) {
						*f0 = _f0;
					}
					if (r1) {
						*r1 = _r1;
					}
					if (f1) {
						*f1 = _f1;
					}
					if (promotion_type) {
						*promotion_type = _promotion_type;
					}
					return result;
				}
				_r0 = match_rank;
				_f0 = match_file;
			}
		}
	}
	_tmp41_ = string_get (move, (glong) i);
	if (_tmp41_ == '+') {
		i++;
	} else {
		gchar _tmp42_;
		_tmp42_ = string_get (move, (glong) i);
		if (_tmp42_ == '#') {
			i++;
		}
	}
	_tmp43_ = string_get (move, (glong) i);
	if (_tmp43_ != '\0') {
		g_debug ("chess-game.vala:1132: Move %s has unexpected characters", move);
		result = FALSE;
		if (r0) {
			*r0 = _r0;
		}
		if (f0) {
			*f0 = _f0;
		}
		if (r1) {
			*r1 = _r1;
		}
		if (f1) {
			*f1 = _f1;
		}
		if (promotion_type) {
			*promotion_type = _promotion_type;
		}
		return result;
	}
	result = TRUE;
	if (r0) {
		*r0 = _r0;
	}
	if (f0) {
		*f0 = _f0;
	}
	if (r1) {
		*r1 = _r1;
	}
	if (f1) {
		*f1 = _f1;
	}
	if (promotion_type) {
		*promotion_type = _promotion_type;
	}
	return result;
}


ChessPlayer* chess_state_get_opponent (ChessState* self) {
	ChessPlayer* result;
	ChessPlayer* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	if (self->current_player->color == COLOR_WHITE) {
		_tmp0_ = self->players[COLOR_BLACK];
	} else {
		_tmp0_ = self->players[COLOR_WHITE];
	}
	result = _tmp0_;
	return result;
}


static void value_chess_state_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_chess_state_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		chess_state_unref (value->data[0].v_pointer);
	}
}


static void value_chess_state_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = chess_state_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_chess_state_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_chess_state_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		ChessState* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = chess_state_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_chess_state_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	ChessState** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = chess_state_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_chess_state (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecChessState* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_CHESS_STATE), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_chess_state (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_STATE), NULL);
	return value->data[0].v_pointer;
}


void value_set_chess_state (GValue* value, gpointer v_object) {
	ChessState* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_STATE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHESS_STATE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		chess_state_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		chess_state_unref (old);
	}
}


void value_take_chess_state (GValue* value, gpointer v_object) {
	ChessState* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_STATE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHESS_STATE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		chess_state_unref (old);
	}
}


static void chess_state_class_init (ChessStateClass * klass) {
	chess_state_parent_class = g_type_class_peek_parent (klass);
	CHESS_STATE_CLASS (klass)->finalize = chess_state_finalize;
	g_type_class_add_private (klass, sizeof (ChessStatePrivate));
}


static void chess_state_instance_init (ChessState * self) {
	self->priv = CHESS_STATE_GET_PRIVATE (self);
	self->number = 0;
	self->en_passant_index = -1;
	self->last_move = NULL;
	self->ref_count = 1;
}


static void chess_state_finalize (ChessState* obj) {
	ChessState * self;
	self = CHESS_STATE (obj);
	_vala_array_destroy (self->players, 2, (GDestroyNotify) g_object_unref);
	_g_object_unref0 (self->current_player);
	_vala_array_destroy (self->board, 64, (GDestroyNotify) chess_piece_unref);
	_chess_move_unref0 (self->last_move);
}


GType chess_state_get_type (void) {
	static volatile gsize chess_state_type_id__volatile = 0;
	if (g_once_init_enter (&chess_state_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_chess_state_init, value_chess_state_free_value, value_chess_state_copy_value, value_chess_state_peek_pointer, "p", value_chess_state_collect_value, "p", value_chess_state_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (ChessStateClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_state_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessState), 0, (GInstanceInitFunc) chess_state_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType chess_state_type_id;
		chess_state_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ChessState", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&chess_state_type_id__volatile, chess_state_type_id);
	}
	return chess_state_type_id__volatile;
}


gpointer chess_state_ref (gpointer instance) {
	ChessState* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void chess_state_unref (gpointer instance) {
	ChessState* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		CHESS_STATE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


GType chess_result_get_type (void) {
	static volatile gsize chess_result_type_id__volatile = 0;
	if (g_once_init_enter (&chess_result_type_id__volatile)) {
		static const GEnumValue values[] = {{CHESS_RESULT_IN_PROGRESS, "CHESS_RESULT_IN_PROGRESS", "in-progress"}, {CHESS_RESULT_WHITE_WON, "CHESS_RESULT_WHITE_WON", "white-won"}, {CHESS_RESULT_BLACK_WON, "CHESS_RESULT_BLACK_WON", "black-won"}, {CHESS_RESULT_DRAW, "CHESS_RESULT_DRAW", "draw"}, {0, NULL, NULL}};
		GType chess_result_type_id;
		chess_result_type_id = g_enum_register_static ("ChessResult", values);
		g_once_init_leave (&chess_result_type_id__volatile, chess_result_type_id);
	}
	return chess_result_type_id__volatile;
}


GType chess_rule_get_type (void) {
	static volatile gsize chess_rule_type_id__volatile = 0;
	if (g_once_init_enter (&chess_rule_type_id__volatile)) {
		static const GEnumValue values[] = {{CHESS_RULE_CHECKMATE, "CHESS_RULE_CHECKMATE", "checkmate"}, {CHESS_RULE_STALEMATE, "CHESS_RULE_STALEMATE", "stalemate"}, {CHESS_RULE_FIFTY_MOVES, "CHESS_RULE_FIFTY_MOVES", "fifty-moves"}, {CHESS_RULE_TIMEOUT, "CHESS_RULE_TIMEOUT", "timeout"}, {CHESS_RULE_THREE_FOLD_REPETITION, "CHESS_RULE_THREE_FOLD_REPETITION", "three-fold-repetition"}, {CHESS_RULE_INSUFFICIENT_MATERIAL, "CHESS_RULE_INSUFFICIENT_MATERIAL", "insufficient-material"}, {CHESS_RULE_RESIGN, "CHESS_RULE_RESIGN", "resign"}, {CHESS_RULE_ABANDONMENT, "CHESS_RULE_ABANDONMENT", "abandonment"}, {CHESS_RULE_DEATH, "CHESS_RULE_DEATH", "death"}, {0, NULL, NULL}};
		GType chess_rule_type_id;
		chess_rule_type_id = g_enum_register_static ("ChessRule", values);
		g_once_init_leave (&chess_rule_type_id__volatile, chess_rule_type_id);
	}
	return chess_rule_type_id__volatile;
}


static void _chess_state_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (chess_state_unref (var), NULL));
}


static void _g_list_free__chess_state_unref0_ (GList* self) {
	g_list_foreach (self, (GFunc) _chess_state_unref0_, NULL);
	g_list_free (self);
}


static gboolean _chess_game_move_cb_chess_player_do_move (ChessPlayer* _sender, const gchar* move, gboolean apply, gpointer self) {
	gboolean result;
	result = chess_game_move_cb (self, _sender, move, apply);
	return result;
}


static void _chess_game_undo_cb_chess_player_do_undo (ChessPlayer* _sender, gpointer self) {
	chess_game_undo_cb (self, _sender);
}


static gboolean _chess_game_resign_cb_chess_player_do_resign (ChessPlayer* _sender, gpointer self) {
	gboolean result;
	result = chess_game_resign_cb (self, _sender);
	return result;
}


static gboolean _chess_game_claim_draw_cb_chess_player_do_claim_draw (ChessPlayer* _sender, gpointer self) {
	gboolean result;
	result = chess_game_claim_draw_cb (self, _sender);
	return result;
}


ChessGame* chess_game_construct (GType object_type, const gchar* fen, gchar** moves, int moves_length1) {
	ChessGame* self = NULL;
	ChessState* _tmp0_ = NULL;
	ChessPlayer* _tmp4_ = NULL;
	ChessPlayer* _tmp5_ = NULL;
	ChessPlayer* _tmp6_ = NULL;
	ChessPlayer* _tmp7_ = NULL;
	ChessPlayer* _tmp8_ = NULL;
	ChessPlayer* _tmp9_ = NULL;
	ChessPlayer* _tmp10_ = NULL;
	ChessPlayer* _tmp11_ = NULL;
	g_return_val_if_fail (fen != NULL, NULL);
	self = (ChessGame*) g_type_create_instance (object_type);
	self->is_started = FALSE;
	_tmp0_ = chess_state_new (fen);
	self->move_stack = g_list_prepend (self->move_stack, _tmp0_);
	self->result = CHESS_RESULT_IN_PROGRESS;
	if (moves != NULL) {
		{
			gint i;
			i = 0;
			{
				gboolean _tmp1_;
				_tmp1_ = TRUE;
				while (TRUE) {
					ChessPlayer* _tmp2_ = NULL;
					gboolean _tmp3_;
					if (!_tmp1_) {
						i++;
					}
					_tmp1_ = FALSE;
					if (!(i < moves_length1)) {
						break;
					}
					_tmp2_ = chess_game_get_current_player (self);
					_tmp3_ = chess_game_do_move (self, _tmp2_, moves[i], TRUE);
					if (!_tmp3_) {
						g_warning ("chess-game.vala:1222: Invalid move %s", moves[i]);
					}
				}
			}
		}
	}
	_tmp4_ = chess_game_get_white (self);
	g_signal_connect (_tmp4_, "do-move", (GCallback) _chess_game_move_cb_chess_player_do_move, self);
	_tmp5_ = chess_game_get_white (self);
	g_signal_connect (_tmp5_, "do-undo", (GCallback) _chess_game_undo_cb_chess_player_do_undo, self);
	_tmp6_ = chess_game_get_white (self);
	g_signal_connect (_tmp6_, "do-resign", (GCallback) _chess_game_resign_cb_chess_player_do_resign, self);
	_tmp7_ = chess_game_get_white (self);
	g_signal_connect (_tmp7_, "do-claim-draw", (GCallback) _chess_game_claim_draw_cb_chess_player_do_claim_draw, self);
	_tmp8_ = chess_game_get_black (self);
	g_signal_connect (_tmp8_, "do-move", (GCallback) _chess_game_move_cb_chess_player_do_move, self);
	_tmp9_ = chess_game_get_black (self);
	g_signal_connect (_tmp9_, "do-undo", (GCallback) _chess_game_undo_cb_chess_player_do_undo, self);
	_tmp10_ = chess_game_get_black (self);
	g_signal_connect (_tmp10_, "do-resign", (GCallback) _chess_game_resign_cb_chess_player_do_resign, self);
	_tmp11_ = chess_game_get_black (self);
	g_signal_connect (_tmp11_, "do-claim-draw", (GCallback) _chess_game_claim_draw_cb_chess_player_do_claim_draw, self);
	return self;
}


ChessGame* chess_game_new (const gchar* fen, gchar** moves, int moves_length1) {
	return chess_game_construct (TYPE_CHESS_GAME, fen, moves, moves_length1);
}


static gboolean chess_game_move_cb (ChessGame* self, ChessPlayer* player, const gchar* move, gboolean apply) {
	gboolean result = FALSE;
	gboolean _tmp0_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	g_return_val_if_fail (move != NULL, FALSE);
	if (!self->is_started) {
		result = FALSE;
		return result;
	}
	_tmp0_ = chess_game_do_move (self, player, move, apply);
	result = _tmp0_;
	return result;
}


static gpointer _chess_state_ref0 (gpointer self) {
	return self ? chess_state_ref (self) : NULL;
}


static gboolean chess_game_do_move (ChessGame* self, ChessPlayer* player, const gchar* move, gboolean apply) {
	gboolean result = FALSE;
	ChessPlayer* _tmp0_ = NULL;
	ChessState* _tmp1_ = NULL;
	ChessState* _tmp2_ = NULL;
	ChessState* state;
	gboolean _tmp3_;
	ChessState* _tmp4_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	_tmp0_ = chess_game_get_current_player (self);
	if (player != _tmp0_) {
		result = FALSE;
		return result;
	}
	_tmp1_ = chess_game_get_current_state (self);
	_tmp2_ = chess_state_copy (_tmp1_);
	state = _tmp2_;
	state->number++;
	_tmp3_ = chess_state_move (state, move, apply);
	if (!_tmp3_) {
		result = FALSE;
		_chess_state_unref0 (state);
		return result;
	}
	if (!apply) {
		result = TRUE;
		_chess_state_unref0 (state);
		return result;
	}
	_tmp4_ = _chess_state_ref0 (state);
	self->move_stack = g_list_prepend (self->move_stack, _tmp4_);
	if (state->last_move->victim != NULL) {
		g_signal_emit_by_name (state->last_move->victim, "died");
	}
	g_signal_emit_by_name (state->last_move->piece, "moved");
	if (state->last_move->moved_rook != NULL) {
		g_signal_emit_by_name (state->last_move->moved_rook, "moved");
	}
	g_signal_emit_by_name (self, "moved", state->last_move);
	chess_game_complete_move (self);
	result = TRUE;
	_chess_state_unref0 (state);
	return result;
}


void chess_game_add_hold (ChessGame* self) {
	g_return_if_fail (self != NULL);
	self->priv->hold_count++;
}


void chess_game_remove_hold (ChessGame* self) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (self->priv->hold_count > 0);
	self->priv->hold_count--;
	if (self->priv->hold_count == 0) {
		chess_game_complete_move (self);
	}
}


static void chess_game_complete_move (ChessGame* self) {
	ChessRule rule = 0;
	ChessState* _tmp0_ = NULL;
	ChessRule _tmp1_;
	ChessResult _tmp2_;
	ChessResult _result_;
	g_return_if_fail (self != NULL);
	if (self->priv->hold_count > 0) {
		return;
	}
	_tmp0_ = chess_game_get_current_state (self);
	_tmp2_ = chess_state_get_result (_tmp0_, &_tmp1_);
	rule = _tmp1_;
	_result_ = _tmp2_;
	if (_result_ != CHESS_RESULT_IN_PROGRESS) {
		chess_game_stop (self, _result_, rule);
	} else {
		ChessPlayer* _tmp4_ = NULL;
		ChessPlayer* _tmp5_ = NULL;
		if (self->priv->_clock != NULL) {
			ChessPlayer* _tmp3_ = NULL;
			_tmp3_ = chess_game_get_current_player (self);
			chess_clock_set_active_color (self->priv->_clock, _tmp3_->color);
		}
		_tmp4_ = chess_game_get_current_player (self);
		g_signal_emit_by_name (_tmp4_, "start-turn");
		_tmp5_ = chess_game_get_current_player (self);
		g_signal_emit_by_name (self, "turn-started", _tmp5_);
	}
}


static void chess_game_undo_cb (ChessGame* self, ChessPlayer* player) {
	ChessPlayer* _tmp0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (player != NULL);
	_tmp0_ = chess_game_get_current_player (self);
	if (player == _tmp0_) {
		ChessPlayer* _tmp1_ = NULL;
		_tmp1_ = chess_game_get_opponent (self);
		chess_game_undo_cb (self, _tmp1_);
	}
	if (self->move_stack->next == NULL) {
		return;
	}
	self->move_stack = g_list_remove_link (self->move_stack, self->move_stack);
	g_signal_emit_by_name (self, "undo");
}


static gboolean chess_game_resign_cb (ChessGame* self, ChessPlayer* player) {
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	if (!self->is_started) {
		result = FALSE;
		return result;
	}
	if (player->color == COLOR_WHITE) {
		chess_game_stop (self, CHESS_RESULT_BLACK_WON, CHESS_RULE_RESIGN);
	} else {
		chess_game_stop (self, CHESS_RESULT_WHITE_WON, CHESS_RULE_RESIGN);
	}
	result = TRUE;
	return result;
}


static gboolean chess_game_claim_draw_cb (ChessGame* self, ChessPlayer* player) {
	gboolean result = FALSE;
	ChessState* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	if (!self->is_started) {
		result = FALSE;
		return result;
	}
	_tmp0_ = chess_game_get_current_state (self);
	if (_tmp0_->halfmove_clock >= 100) {
		chess_game_stop (self, CHESS_RESULT_DRAW, CHESS_RULE_FIFTY_MOVES);
	} else {
		gboolean _tmp1_;
		_tmp1_ = chess_game_is_three_fold_repeat (self);
		if (_tmp1_) {
			chess_game_stop (self, CHESS_RESULT_DRAW, CHESS_RULE_THREE_FOLD_REPETITION);
		} else {
			result = FALSE;
			return result;
		}
	}
	result = TRUE;
	return result;
}


static void _chess_game_clock_expired_cb_chess_clock_expired (ChessClock* _sender, gpointer self) {
	chess_game_clock_expired_cb (self, _sender);
}


void chess_game_start (ChessGame* self) {
	ChessPlayer* _tmp1_ = NULL;
	ChessPlayer* _tmp2_ = NULL;
	g_return_if_fail (self != NULL);
	if (self->result != CHESS_RESULT_IN_PROGRESS) {
		return;
	}
	if (self->is_started) {
		return;
	}
	self->is_started = TRUE;
	if (self->priv->_clock != NULL) {
		ChessPlayer* _tmp0_ = NULL;
		g_signal_connect (self->priv->_clock, "expired", (GCallback) _chess_game_clock_expired_cb_chess_clock_expired, self);
		_tmp0_ = chess_game_get_current_player (self);
		chess_clock_set_active_color (self->priv->_clock, _tmp0_->color);
		chess_clock_start (self->priv->_clock);
	}
	g_signal_emit_by_name (self, "started");
	_tmp1_ = chess_game_get_current_player (self);
	g_signal_emit_by_name (_tmp1_, "start-turn");
	_tmp2_ = chess_game_get_current_player (self);
	g_signal_emit_by_name (self, "turn-started", _tmp2_);
}


static void chess_game_clock_expired_cb (ChessGame* self, ChessClock* clock) {
	ChessPlayer* _tmp0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (clock != NULL);
	_tmp0_ = chess_game_get_current_player (self);
	if (_tmp0_->color == COLOR_WHITE) {
		chess_game_stop (self, CHESS_RESULT_BLACK_WON, CHESS_RULE_TIMEOUT);
	} else {
		chess_game_stop (self, CHESS_RESULT_WHITE_WON, CHESS_RULE_TIMEOUT);
	}
}


void chess_game_abandon (ChessGame* self) {
	g_return_if_fail (self != NULL);
	if (!self->is_started) {
		return;
	}
	chess_game_stop (self, CHESS_RESULT_DRAW, CHESS_RULE_ABANDONMENT);
}


ChessPiece* chess_game_get_piece (ChessGame* self, gint rank, gint file, gint move_number) {
	ChessPiece* result = NULL;
	guint _tmp1_;
	gconstpointer _tmp2_ = NULL;
	ChessState* _tmp3_;
	ChessState* state;
	gint _tmp4_;
	ChessPiece* _tmp5_;
	g_return_val_if_fail (self != NULL, NULL);
	if (move_number < 0) {
		guint _tmp0_;
		_tmp0_ = g_list_length (self->move_stack);
		move_number = move_number + ((gint) _tmp0_);
	}
	_tmp1_ = g_list_length (self->move_stack);
	_tmp2_ = g_list_nth_data (self->move_stack, (_tmp1_ - move_number) - 1);
	_tmp3_ = _chess_state_ref0 ((ChessState*) _tmp2_);
	state = _tmp3_;
	_tmp4_ = chess_state_get_index (state, rank, file);
	_tmp5_ = _chess_piece_ref0 (state->board[_tmp4_]);
	result = _tmp5_;
	_chess_state_unref0 (state);
	return result;
}


static void chess_game_stop (ChessGame* self, ChessResult _result_, ChessRule rule) {
	g_return_if_fail (self != NULL);
	self->result = _result_;
	self->rule = rule;
	self->is_started = FALSE;
	g_signal_emit_by_name (self, "ended");
}


static gboolean chess_game_is_three_fold_repeat (ChessGame* self) {
	gboolean result = FALSE;
	gint count;
	g_return_val_if_fail (self != NULL, FALSE);
	count = 1;
	{
		GList* state_collection;
		GList* state_it;
		state_collection = self->move_stack->next;
		for (state_it = state_collection; state_it != NULL; state_it = state_it->next) {
			ChessState* _tmp0_;
			ChessState* state;
			_tmp0_ = _chess_state_ref0 ((ChessState*) state_it->data);
			state = _tmp0_;
			{
				ChessState* _tmp1_ = NULL;
				gboolean _tmp2_;
				_tmp1_ = chess_game_get_current_state (self);
				_tmp2_ = chess_state_equals (_tmp1_, state);
				if (_tmp2_) {
					count++;
					if (count >= 3) {
						result = TRUE;
						_chess_state_unref0 (state);
						return result;
					}
				}
				_chess_state_unref0 (state);
			}
		}
	}
	result = FALSE;
	return result;
}


ChessState* chess_game_get_current_state (ChessGame* self) {
	ChessState* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = (ChessState*) self->move_stack->data;
	return result;
}


ChessPlayer* chess_game_get_white (ChessGame* self) {
	ChessPlayer* result;
	ChessState* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_game_get_current_state (self);
	result = _tmp0_->players[COLOR_WHITE];
	return result;
}


ChessPlayer* chess_game_get_black (ChessGame* self) {
	ChessPlayer* result;
	ChessState* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_game_get_current_state (self);
	result = _tmp0_->players[COLOR_BLACK];
	return result;
}


ChessPlayer* chess_game_get_current_player (ChessGame* self) {
	ChessPlayer* result;
	ChessState* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_game_get_current_state (self);
	result = _tmp0_->current_player;
	return result;
}


ChessPlayer* chess_game_get_opponent (ChessGame* self) {
	ChessPlayer* result;
	ChessState* _tmp0_ = NULL;
	ChessPlayer* _tmp1_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = chess_state_get_opponent (_tmp0_);
	result = _tmp1_;
	return result;
}


ChessClock* chess_game_get_clock (ChessGame* self) {
	ChessClock* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self->priv->_clock;
	return result;
}


void chess_game_set_clock (ChessGame* self, ChessClock* value) {
	ChessClock* _tmp0_;
	g_return_if_fail (self != NULL);
	if (self->is_started) {
		return;
	}
	_tmp0_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_clock);
	self->priv->_clock = _tmp0_;
}


guint chess_game_get_n_moves (ChessGame* self) {
	guint result;
	guint _tmp0_;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = g_list_length (self->move_stack);
	result = _tmp0_ - 1;
	return result;
}


static void g_cclosure_user_marshal_VOID__CHESS_MOVE (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__CHESS_MOVE) (gpointer data1, gpointer arg_1, gpointer data2);
	register GMarshalFunc_VOID__CHESS_MOVE callback;
	register GCClosure * cc;
	register gpointer data1, data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 2);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__CHESS_MOVE) (marshal_data ? marshal_data : cc->callback);
	callback (data1, value_get_chess_move (param_values + 1), data2);
}


static void value_chess_game_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_chess_game_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		chess_game_unref (value->data[0].v_pointer);
	}
}


static void value_chess_game_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = chess_game_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_chess_game_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_chess_game_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		ChessGame* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = chess_game_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_chess_game_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	ChessGame** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = chess_game_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_chess_game (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecChessGame* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_CHESS_GAME), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_chess_game (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_GAME), NULL);
	return value->data[0].v_pointer;
}


void value_set_chess_game (GValue* value, gpointer v_object) {
	ChessGame* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_GAME));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHESS_GAME));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		chess_game_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		chess_game_unref (old);
	}
}


void value_take_chess_game (GValue* value, gpointer v_object) {
	ChessGame* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHESS_GAME));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHESS_GAME));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		chess_game_unref (old);
	}
}


static void chess_game_class_init (ChessGameClass * klass) {
	chess_game_parent_class = g_type_class_peek_parent (klass);
	CHESS_GAME_CLASS (klass)->finalize = chess_game_finalize;
	g_type_class_add_private (klass, sizeof (ChessGamePrivate));
	g_signal_new ("started", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("turn_started", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, TYPE_CHESS_PLAYER);
	g_signal_new ("moved", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__CHESS_MOVE, G_TYPE_NONE, 1, TYPE_CHESS_MOVE);
	g_signal_new ("undo", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("ended", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}


static void chess_game_instance_init (ChessGame * self) {
	self->priv = CHESS_GAME_GET_PRIVATE (self);
	self->priv->hold_count = 0;
	self->ref_count = 1;
}


static void chess_game_finalize (ChessGame* obj) {
	ChessGame * self;
	self = CHESS_GAME (obj);
	__g_list_free__chess_state_unref0_0 (self->move_stack);
	_g_object_unref0 (self->priv->_clock);
}


GType chess_game_get_type (void) {
	static volatile gsize chess_game_type_id__volatile = 0;
	if (g_once_init_enter (&chess_game_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_chess_game_init, value_chess_game_free_value, value_chess_game_copy_value, value_chess_game_peek_pointer, "p", value_chess_game_collect_value, "p", value_chess_game_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (ChessGameClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_game_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessGame), 0, (GInstanceInitFunc) chess_game_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType chess_game_type_id;
		chess_game_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ChessGame", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&chess_game_type_id__volatile, chess_game_type_id);
	}
	return chess_game_type_id__volatile;
}


gpointer chess_game_ref (gpointer instance) {
	ChessGame* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void chess_game_unref (gpointer instance) {
	ChessGame* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		CHESS_GAME_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}


static gint _vala_array_length (gpointer array) {
	int length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}



