Commit f78534d3 authored by Vivien Kraus's avatar Vivien Kraus
Browse files

Resolve "Use the command-line parser from glib"

parent 65f4164a
......@@ -18,10 +18,6 @@
SUBDIRS = po lib
if NEED_LIBOPTS
SUBDIRS += $(LIBOPTS_DIR)
endif
include defaults.am
ACLOCAL_AMFLAGS = -I m4
......
......@@ -25,18 +25,8 @@ gnulib-tool --libtool \
--import assert git-version-gen getopt-gnu gitlog-to-changelog setenv xalloc readline \
setlocale || exit 1
./gitlog-to-changelog > ChangeLog
rm -rf libopts libopts-* || exit 1
gunzip -c `autoopts-config libsrc` | tar -xvf - || exit 1
mv -f libopts-*.*.* libopts || exit 1
cp -fp libopts/m4/*.m4 m4/. || exit 1
touch README || exit 1
autoreconf -vif || exit 1
rm doc/tarot.texi || exit 1
rm AUTHORS || exit 1
rm README || exit 1
grep -v "choke.me" libopts/compat/snprintf.c > libopts/compat/snprintf.c.fixed || exit 1
mv libopts/compat/snprintf.c.fixed libopts/compat/snprintf.c || exit 1
echo "libopts_la_CPPFLAGS += -w" >> libopts/Makefile.am || exit 1
echo "EXTRA_DIST += verify.h" >> libopts/Makefile.am || exit 1
echo '#define verify(whatever)' > libopts/verify.h || exit 1
......@@ -36,7 +36,6 @@ AM_CONDITIONAL([HAVE_VALGRIND], [test "x$HAVE_VALGRIND" = "xyes"])
AM_MISSING_PROG([XSLTPROC], [xsltproc])
AM_MISSING_PROG([XMLLINT], [xmllint])
AM_MISSING_PROG([CONVERT], [convert])
PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.0], [glib_mkenums])
AM_PROG_VALAC
AC_ARG_VAR([VALAFLAGS], [Additional flags to pass to the vala compiler])
AC_ARG_ENABLE([renderer], AS_HELP_STRING([--enable-renderer=yes],
......@@ -51,13 +50,13 @@ AM_CONDITIONAL([ENABLE_GENERATOR], [test "x$enable_generator" = "xyes"])
AM_MISSING_PROG([JEKYLL], [jekyll])
PKG_INSTALLDIR
AM_MISSING_PROG([FDP], [fdp])
AM_MISSING_PROG([HELP2MAN], [help2man])
# Checks for libraries.
gl_INIT
AX_LIB_NETTLE([yes])
PKG_CHECK_MODULES([XML], [libxml-2.0])
PKG_CHECK_MODULES([LIBTAROT], [libtarot-gobject])
LIBOPTS_CHECK
PKG_CHECK_MODULES([GOBJECT], [gobject-2.0],, [
AC_MSG_ERROR([GObject was not found.])
])
......
......@@ -31,3 +31,4 @@ include %reldir%/texinfo.am
include %reldir%/export-html.am
include %reldir%/export-docbook.am
include %reldir%/org-export-texinfo.am
include %reldir%/man.am
# Makefile.am
# man.am
#
# Copyright (C) 2017, 2018 Vivien Kraus <vivien@planete-kraus.eu>
# Copyright (C) 2019 Vivien Kraus <vivien@planete-kraus.eu>
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
......@@ -16,9 +16,17 @@
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
include %reldir%/cardpainter-vapi.am
include %reldir%/libtarot-cardpainter.am
dist_man6_MANS += %reldir%/tarot.man
MAINTAINERCLEANFILES += %reldir%/tarot.man
AM_VALAFLAGS += --pkg cairo
help2man_verbose = $(help2man_verbose_@AM_V@)
help2man_verbose_ = $(help2man_verbose_@AM_DEFAULT_V@)
help2man_verbose_0 = @echo " HELP2MAN" $@;
AM_CPPFLAGS += -I $(srcdir)/%reldir% -I %reldir%
if ENABLE_GENERATOR
$(srcdir)/%reldir%/tarot.man: src/tarot$(EXEEXT)
$(help2man_verbose) ./pre-inst-env help2man tarot > $(srcdir)/%reldir%/tarot.man
else # not HAVE_GENERATOR
$(srcdir)/%reldir%/tarot.man: src/main.vala
$(help2man_verbose) ./pre-inst-env help2man tarot > $(srcdir)/%reldir%/tarot.man
endif # not HAVE_GENERATOR
......@@ -608,8 +608,18 @@ previous second.
The command-line interface =tarot= has two modes: either it
processes an XML game doing one game action, or it opens a shell to
quickly play a game.
** Invoking tarot
#+texinfo: @include invoke-tarot-body.texi
** TODO Invoking tarot
If invoked without program arguments, then it will start an
interactive session in which you play the first player against 3 other
players, a game which is dealt at random.
If you pass =--help=, you will get the list of supported options.
Please note that the option names are internationalized, so this guide
assumes that you are running tarot with the =C= locale:
#+BEGIN_SRC shell :eval no
LANG=C tarot --help
#+END_SRC
** The shell
The shell will guide you. You will first have to bid, then do a slam
declaration, then a call (only if you chose =--call-allowed=), then a
......
......@@ -18,55 +18,7 @@
info_TEXINFOS += %reldir%/tarot.texi
tarotfiguresdir = $(infodir)/tarot-figures
dist_tarotfigures_DATA = \
%reldir%/tarot-figures/example.png \
%reldir%/tarot-figures/example-tree.png
dist_tarotfigures_DATA =
%canon_reldir%_tarot_TEXINFOS = \
%reldir%/fdl.texi \
%reldir%/invoke-tarot-body.texi
EXTRA_DIST += \
%reldir%/tarot-figures/example.eps \
%reldir%/tarot-figures/example-tree.eps \
%reldir%/invoke-tarot-body.texi \
$(srcdir)/%reldir%/example-status.txt
MAINTAINERCLEANFILES += \
$(srcdir)/%reldir%/tarot-figures/example.png \
$(srcdir)/%reldir%/tarot-figures/example.eps \
$(srcdir)/%reldir%/tarot-figures/example-tree.png \
$(srcdir)/%reldir%/tarot-figures/example-tree.eps \
$(srcdir)/%reldir%/invoke-tarot-body.texi \
$(srcdir)/%reldir%/example-status.txt
$(srcdir)/%reldir%/tarot.texi: \
%reldir%/tarot-figures/example.png \
%reldir%/tarot-figures/example-tree.png \
%reldir%/example-status.txt
$(srcdir)/%reldir%/tarot-figures/example.png: games/example.xml.png
@$(MKDIR_P) $(srcdir)/%reldir%/tarot-figures
$(AM_V_GEN) cp $(srcdir)/games/example.xml.png $(srcdir)/%reldir%/tarot-figures/example.png
$(srcdir)/%reldir%/tarot-figures/example-tree.eps: %reldir%/tarot-figures/example-tree.png
$(AM_V_GEN) $(CONVERT) $(srcdir)/%reldir%/tarot-figures/example-tree.png $(srcdir)/%reldir%/tarot-figures/example-tree.eps
$(srcdir)/%reldir%/tarot-figures/example.eps: %reldir%/tarot-figures/example.png
$(AM_V_GEN) $(CONVERT) $(srcdir)/%reldir%/tarot-figures/example.png $(srcdir)/%reldir%/tarot-figures/example.eps
generate_verbose = $(generate_verbose_@AM_V@)
generate_verbose_ = $(generate_verbose_@AM_DEFAULT_V@)
generate_verbose_0 = @echo " GENERATE " $@;
if ENABLE_GENERATOR
$(srcdir)/%reldir%/example-status.txt: src/tarot
$(generate_verbose) src/tarot --generate -n 5 -c \
| src/tarot --status -o $(srcdir)/%reldir%/example-status.txt
else # not ENABLE_GENERATOR
$(srcdir)/%reldir%/example-status.txt:
@echo "Error: the status $@ should be rebuilt. Please pass --enable-generator=yes to configure."
@false
endif # not ENABLE_GENERATOR
$(srcdir)/%reldir%/tarot.texi: $(%canon_reldir%_tarot_TEXINFOS)
%reldir%/fdl.texi
......@@ -17,24 +17,34 @@
# <http://www.gnu.org/licenses/>.
dist_games_DATA += %reldir%/example.xml
EXTRA_DIST += %reldir%/example.xml.png \
%reldir%/render_mcts_tree.xsl
EXTRA_DIST += \
%reldir%/render_mcts_tree.xsl \
%reldir%/generated.xml \
doc/tarot-figures/example-tree.png \
doc/tarot-figures/example.png
MAINTAINERCLEANFILES += $(srcdir)/%reldir%/example.xml.png
MAINTAINERCLEANFILES += \
%reldir%/generated.xml \
doc/tarot-figures/example-tree.png \
doc/tarot-figures/example.png
render_verbose = $(render_verbose_@AM_V@)
render_verbose_ = $(render_verbose_@AM_DEFAULT_V@)
render_verbose_0 = @echo " RENDER " $@;
tree_render_verbose = $(render_verbose_@AM_V@)
tree_render_verbose_ = $(render_verbose_@AM_DEFAULT_V@)
tree_render_verbose = $(tree_render_verbose_@AM_V@)
tree_render_verbose_ = $(tree_render_verbose_@AM_DEFAULT_V@)
tree_render_verbose_0 = @echo " TREE " $@;
generator_verbose = $(generator_verbose_@AM_V@)
generator_verbose_ = $(generator_verbose_@AM_DEFAULT_V@)
generator_verbose_0 = @echo " GENERATE" $@;
if ENABLE_RENDERER
$(srcdir)/%reldir%/example.xml.png: %reldir%/example.xml src/tarot
$(render_verbose) ./pre-inst-env tarot --render -i $(srcdir)/%reldir%/example.xml -o $(srcdir)/%reldir%/example.xml.png
$(srcdir)/doc/tarot-figures/example.png: %reldir%/example.xml src/tarot
$(render_verbose) ./pre-inst-env tarot --render -i $(srcdir)/%reldir%/example.xml -o $(srcdir)/doc/tarot-figures/example.png
else # not ENABLE_RENDERER
$(srcdir)/%reldir%/example.xml.png: %reldir%/example.xml
$(srcdir)/doc/tarot-figures/example.png: %reldir%/example.xml
@echo "Error: the figure $@ should be rebuilt. Please pass --enable-renderer=yes to configure."
@false
endif # not ENABLE_RENDERER
......@@ -42,12 +52,21 @@ endif # not ENABLE_RENDERER
if ENABLE_TREE_RENDERER
$(srcdir)/doc/tarot-figures/example-tree.png: %reldir%/example.xml src/tarot
@$(MKDIR_P) $(srcdir)/doc/tarot-figures
$(tree_render_verbose) src/tarot --impute < $(srcdir)/%reldir%/example.xml \
| src/tarot --mcts-tree \
$(tree_render_verbose) ./pre-inst-env tarot --impute < $(srcdir)/%reldir%/example.xml \
| ./pre-inst-env tarot --mcts-tree \
| $(XSLTPROC) $(srcdir)/%reldir%/render_mcts_tree.xsl - \
| $(FDP) -Tpng -o $(srcdir)/doc/tarot-figures/example-tree.png
else # not ENABLE_TREE_RENDERER
$(srcdir)/doc/tarot-figures/example-tree.png: %reldir%/example.xml
@echo "Error: the figure $@ should be rebuilt. Please pass --enable-renderer=yes to configure."
@echo "Error: the figure $@ should be rebuilt. Please pass --enable-tree-renderer=yes to configure."
@false
endif # not ENABLE_TREE_RENDERER
if ENABLE_GENERATOR
$(srcdir)/%reldir%/generated.xml: src/tarot
$(generator_verbose) ./pre-inst-env tarot -o $(srcdir)/%reldir%/generated.xml --generate
else # not ENABLE_TREE_RENDERER
$(srcdir)/%reldir%/generated.xml: $(src_tarot_SOURCES)
@echo "Error: the generated game $@ should be rebuilt. Please pass --enable-generator=yes to configure."
@false
endif # not ENABLE_TREE_RENDERER
......@@ -3,5 +3,4 @@ src/tarot_cli.vala
src/engine/application.vala
src/engine/pretty_status.vala
src/engine/solo.vala
src/tarot-opts.h
src/tarot-opts.c
\ No newline at end of file
src/main.vala
\ No newline at end of file
This diff is collapsed.
......@@ -20,5 +20,3 @@ include %reldir%/tarot-cli-program.am
include %reldir%/gettext-h.am
AM_CPPFLAGS += -I $(srcdir)/%reldir% -I %reldir%
include %reldir%/cairo/Makefile.am
# cardpainter-vapi.am
#
# Copyright (C) 2017, 2018 Vivien Kraus <vivien@planete-kraus.eu>
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
EXTRA_DIST += \
%reldir%/cardpainter.vapi \
%reldir%/card_painter.h \
%reldir%/card_painter.c \
%reldir%/card_painter_default.c \
%reldir%/card_painter.vala \
%reldir%/card_painter_default.vala \
%reldir%/cardpainter-vapi-stamp
MAINTAINERCLEANFILES += \
$(srcdir)/%reldir%/cardpainter.vapi \
$(srcdir)/%reldir%/card_painter.h \
$(srcdir)/%reldir%/cardpainter-vapi-stamp \
$(srcdir)/%reldir%/card_painter.c \
$(srcdir)/%reldir%/card_painter_default.c
AM_VALAFLAGS += --pkg=libtarot-gobject
$(srcdir)/%reldir%/cardpainter-vapi-stamp: %reldir%/card_painter.vala %reldir%/card_painter_default.vala
$(AM_V_VALAC) cd $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) \
--library %reldir%/cardpainter \
-H %reldir%/card_painter.h \
-C \
%reldir%/card_painter.vala \
%reldir%/card_painter_default.vala \
&& touch %reldir%/card_painter.h \
&& touch %reldir%/cardpainter.vapi \
&& touch %reldir%/card_painter.c \
&& touch %reldir%/card_painter_default.c \
&& touch %reldir%/cardpainter-vapi-stamp
$(srcdir)/%reldir%/cardpainter.vapi $(srcdir)/%reldir%/card_painter.h $(srcdir)/%reldir%/card_painter.c $(srcdir)/%reldir%/card_painter_default.c: %reldir%/cardpainter-vapi-stamp
@dry=; for f in x $$MAKEFLAGS; do \
case $$f in \
*=*|--*);; \
*n*) dry=:;; \
esac; \
done; \
if test -f $@; then :; else \
$$dry trap 'rm -rf $(srcdir)/%reldir%/cardpainter-vapi-lock $(srcdir)/%reldir%/cardpainter-vapi-stamp' 1 2 13 15; \
if $$dry mkdir $(srcdir)/%reldir%/cardpainter-vapi-lock 2>/dev/null; then \
$$dry rm -f $(srcdir)/%reldir%/cardpainter-vapi-stamp || exit 1; \
$(MAKE) $(AM_MAKEFLAGS) %reldir%/cardpainter-vapi-stamp; \
$$dry rmdir $(srcdir)/%reldir%/cardpainter-vapi-lock; \
else \
while test -d $(srcdir)/%reldir%/cardpainter-vapi-lock && test -z "$$dry"; do \
sleep 1; \
done; \
$$dry test -f $(srcdir)/%reldir%/cardpainter-vapi-stamp; exit $$?; \
fi; \
fi
# libtarot-cardpainter.am
#
# Copyright (C) 2017, 2018 Vivien Kraus <vivien@planete-kraus.eu>
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
noinst_LTLIBRARIES += \
%reldir%/libtarot-painter.la
%canon_reldir%_libtarot_painter_la_SOURCES = \
%reldir%/card_painter.c \
%reldir%/card_painter_default.c
%canon_reldir%_libtarot_painter_la_CFLAGS = \
$(AM_CFLAGS) \
-include "config.h" \
-w
%canon_reldir%_libtarot_painter_la_CFLAGS += \
$(LIBTAROT_GOBJECT_CFLAGS) \
$(CAIRO_CFLAGS)
%canon_reldir%_libtarot_painter_la_LIBADD = \
$(LIBTAROT_GOBJECT_LIBS) \
$(AM_LIBS) \
$(CAIRO_LIBS)
......@@ -18,7 +18,9 @@
extern string? readline (string prompt);
extern void add_history (string command);
extern string tarot_version;
[CCode (cname="PACKAGE_VERSION")]
extern const string tarot_version;
namespace Tarot {
public class Solo: GLib.Object {
......
// main.vala
//
// Copyright (C) 2019 Vivien Kraus <vivien@planete-kraus.eu>
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <http://www.gnu.org/licenses/>.
[CCode (cname="RUNTIME_PREFIX_ENV")]
extern const string RUNTIME_PREFIX_ENV;
[CCode (cname="SYSCONFDIR")]
extern const string SYSCONFDIR;
[CCode (cname="LOCALEDIR")]
extern const string LOCALEDIR;
[CCode (cname="PACKAGE")]
extern const string PACKAGE;
[CCode (cname="PACKAGE_STRING")]
extern const string PACKAGE_STRING;
const string program_name = "tarot";
namespace Tarot {
private static string read_input (GLib.FileStream input_source) {
int c = 0;
string ret = "";
while ((c = input_source.getc ()) >= 0) {
ret += string.nfill (1, (char) c);
}
return ret;
}
/// Return whether we have written some data. Otherwise the file
/// should be removed.
private bool write_output (GLib.FileStream output, string? data) {
if (data != null) {
output.puts (data);
return true;
} else {
return false;
}
}
private GLib.OptionEntry create_option_none (string long_name, char short_name, ref bool? is_set, string documentation) {
GLib.OptionEntry ret = GLib.OptionEntry ();
ret.arg = OptionArg.NONE;
ret.arg_data = &is_set;
ret.arg_description = null;
ret.description = documentation;
ret.flags = 0;
ret.long_name = long_name;
ret.short_name = short_name;
return ret;
}
private GLib.OptionEntry create_option_string (string long_name, char short_name, ref string? value, string documentation, string documentation_arg) {
GLib.OptionEntry ret = GLib.OptionEntry ();
ret.arg = OptionArg.STRING;
ret.arg_data = &value;
ret.arg_description = documentation_arg;
ret.description = documentation;
ret.flags = 0;
ret.long_name = long_name;
ret.short_name = short_name;
return ret;
}
private GLib.OptionEntry create_option_int (string long_name, char short_name, ref int? value, string documentation, string documentation_arg) {
GLib.OptionEntry ret = GLib.OptionEntry ();
ret.arg = OptionArg.INT;
ret.arg_data = &value;
ret.arg_description = documentation_arg;
ret.description = documentation;
ret.flags = 0;
ret.long_name = long_name;
ret.short_name = short_name;
return ret;
}
public static int main (string[] args) {
int n_players = 4;
bool call_allowed = false;
string seed = "default";
int retry = 0;
int n_iterations = 100;
string? output_resource = null;
string? input_resource = null;
int width = 640;
int height = 480;
bool print_version = false;
bool has_status = false;
bool has_new_game = false;
string? has_deal_to = null;
string? has_deal_all = null;
bool has_deal_random = false;
bool has_impute = false;
bool has_mcts = false;
bool has_mcts_tree = false;
bool has_generate = false;
string? has_bid = null;
string? has_decl = null;
string? has_call = null;
string? has_dog = null;
string? has_discard = null;
string? has_handful = null;
string? has_play = null;
bool has_render = false;
setup_environment (RUNTIME_PREFIX_ENV, SYSCONFDIR, LOCALEDIR);
GLib.Intl.setlocale (LocaleCategory.ALL, "");
GLib.Intl.bindtextdomain (PACKAGE, Environment.get_variable ("LOCALEDIR"));
GLib.Intl.textdomain (PACKAGE);
var options = new GLib.OptionEntry[0];
options += create_option_none (_ ("new-game"), 0, ref has_new_game, _ ("Create a new game"));
options += create_option_none (_ ("deal-random"), 0, ref has_deal_random, _ ("Deal the cards at random"));
options += create_option_none (_ ("impute"), 0, ref has_impute, _ ("Impute the missing cards"));
options += create_option_none (_ ("mcts"), 0, ref has_mcts, _ ("Play the next move with MCTS"));
options += create_option_none (_ ("mcts-tree"), 0, ref has_mcts_tree, _ ("Print the MCTS tree for the next move"));
options += create_option_none (_ ("generate"), 0, ref has_generate, _ ("Generate an entire game with MCTS moves"));
options += create_option_none (_ ("render"), 0, ref has_render, _ ("Render a game as PNG"));
options += create_option_none (_ ("status"), 0, ref has_status, _ ("Print the status of the game"));
options += create_option_none (_ ("call-allowed"), 'c', ref call_allowed, _ ("The new game can have a call"));
options += create_option_none (_ ("version"), 'v', ref print_version, _ ("Print version information and exit"));
options += create_option_string (_ ("deal-to"), 0, ref has_deal_to, _ ("Deal cards to a specific player"), _ ("PN=CARD,CARD,..."));
options += create_option_string (_ ("deal-all"), 0, ref has_deal_all, _ ("Deal the cards to all players at once"), _ ("OWNER1,OWNER2,..."));
options += create_option_string (_ ("bid"), 0, ref has_bid, _ ("Add a bid to the game: 'pass', 'take', 'push', 'straight-keep', or 'double-keep'"), _ ("BID"));
options += create_option_string (_ ("declare"), 0, ref has_decl, _ ("Add a slam declaration to the game"), _ ("'pass'/'slam'"));
options += create_option_string (_ ("call"), 0, ref has_call, _ ("Call a card"), _ ("CARD"));
options += create_option_string (_ ("dog"), 0, ref has_dog, _ ("Reveal the dog"), _ ("CARD,CARD..."));
options += create_option_string (_ ("discard"), 0, ref has_discard, _ ("The discard is done"), _ ("'' or CARD,CARD..."));
options += create_option_string (_ ("handful"), 0, ref has_handful, _ ("Show a handful"), _ ("'' or CARD,CARD..."));
options += create_option_string (_ ("play"), 0, ref has_play, _ ("Play a card"), _ ("CARD"));
options += create_option_string (_ ("seed"), 's', ref seed, _ ("The random seed for MCTS-related operations (defaults to 'default')"), _ ("NON-EMPTY"));
options += create_option_string (_ ("output"), 'o', ref output_resource, _ ("Output file to write (defaults to stdout)"), _ ("FILE"));
options += create_option_string (_ ("input"), 'i', ref input_resource, _ ("Input file to read (defaults to stdin)"), _ ("FILE"));
options += create_option_int (_ ("n-player"), 'n', ref n_players, _ ("Specify the number of players for a new game"), _ ("N"));
options += create_option_int (_ ("retry"), 'r', ref retry, _ ("Number of times to retry an operation that may fail out of bad luck"), _ ("N"));
options += create_option_int (_ ("n-iterations"), 'I', ref n_iterations, _ ("Number of iterations for the MCTS exploration (defaults to 100)"), _ ("N"));
options += create_option_int (_ ("width"), 'w', ref width, _ ("PNG width (defaults to 640)"), _ ("N"));
options += create_option_int (_ ("height"), 'h', ref height, _ ("PNG height (defaults to 480)"), _ ("N"));
GLib.OptionEntry final = { null };
options += final;
int ret = 0;
try {
var opt_context = new OptionContext (_ ("- Tarot command-line options"));
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
opt_context.parse (ref args);
} catch (OptionError e) {
stderr.printf ("Error: %s\n", e.message);
GLib.Process.abort ();
}
string? actual_output = null;
unowned GLib.FileStream input_stream = stdin;
GLib.FileStream file_input_stream;
if (input_resource != null) {
file_input_stream = GLib.FileStream.open (input_resource, "r");
input_stream = file_input_stream;
}
if (print_version) {
ret = run_version (PACKAGE_STRING);
} else if (has_status) {
ret = run_status (read_input (input_stream), out actual_output);
} else if (has_impute) {
ret = run_impute (read_input (input_stream), seed, retry, out actual_output);
} else if (has_mcts) {
ret = run_mcts (read_input (input_stream), seed, n_iterations, out actual_output);
} else if (has_mcts_tree) {
ret = run_mcts_tree (read_input (input_stream), seed, n_iterations, out actual_output);
} else if (has_new_game) {
ret = run_new_game (n_players, call_allowed, out actual_output);
} else if (has_deal_to != null) {
ret = run_deal_to (read_input (input_stream), has_deal_to, out actual_output);
} else if (has_deal_all != null) {
ret = run_deal_all (read_input (input_stream), has_deal_all, out actual_output);
} else if (has_deal_random) {
ret = run_deal_random (read_input (input_stream), seed, retry, out actual_output);
} else if (has_bid != null) {
Tarot.Bid bid_arg;
if (has_bid == _ ("pass")) {
bid_arg = Tarot.Bid.PASS;
} else if (has_bid == _ ("take")) {
bid_arg = Tarot.Bid.TAKE;
} else if (has_bid == _ ("push")) {
bid_arg = Tarot.Bid.PUSH;
} else if (has_bid == _ ("straight-keep")) {
bid_arg = Tarot.Bid.STRAIGHT_KEEP;
} else if (has_bid == _ ("double-keep")) {
bid_arg = Tarot.Bid.DOUBLE_KEEP;
} else {
stderr.printf ("Error: '%s' is not a bid\n", has_bid);
return 1;
}
ret = run_bid (read_input (input_stream), bid_arg, out actual_output);
} else if (has_decl != null) {
bool decl_arg;
if (has_decl == _ ("pass")) {
decl_arg = false;
} else if (has_decl == _ ("slam")) {
decl_arg = true;
} else {
stderr.printf ("Error: '%s' is not a slam declaration\n", has_decl);
return 1;
}
ret = run_decl (read_input (input_stream), decl_arg, out actual_output);
} else if (has_call != null) {
ret = run_call (read_input (input_stream), has_call, out actual_output);
} else if (has_dog != null) {
ret = run_dog (read_input (input_stream), has_dog, out actual_output);
} else if (has_discard != null) {
ret = run_discard (read_input (input_stream), has_discard, out actual_output);
} else if (has_handful != null) {
ret = run_handful (read_input (input_stream), has_handful, out actual_output);
} else if (has_play != null) {
ret = run_play (read_input (input_stream), has_play, out actual_output);
} else if (has_generate) {
ret = run_generate (n_players, call_allowed, seed, retry, n_iterations, out actual_output);
} else if (has_render) {
var png_bytes = new char[0];
ret = run_render (read_input (input_stream), width, height, out png_bytes);
unowned GLib.FileStream str = stdout;
GLib.FileStream file_str;
if (output_resource != null) {
file_str = GLib.FileStream.open (output_resource, "w");
str = file_str;
}
foreach (char c in png_bytes) {
str.putc (c);
}
} else {
ret = run_interactive (n_players, call_allowed, seed, n_iterations, retry, out actual_output);
// Discard the output
actual_output = null;
}
Tarot.quit ();
if (ret == 0 && actual_output != null) {