[cliquer] Initial import (#825494).

pcpa pcpa at fedoraproject.org
Fri Aug 17 23:20:24 UTC 2012


commit 49502b5d561456b64edb745a45992f1dc31c6d08
Author: pcpa <paulo.cesar.pereira.de.andrade at gmail.com>
Date:   Fri Aug 17 20:20:08 2012 -0400

    Initial import (#825494).

 .gitignore             |    4 +
 basic.c                |   24 +++++++
 cl.h                   |   33 +++++++++
 cliquer-sagemath.patch |  178 ++++++++++++++++++++++++++++++++++++++++++++++++
 cliquer.1              |   67 ++++++++++++++++++
 cliquer.spec           |  137 +++++++++++++++++++++++++++++++++++++
 hamming.c              |   46 ++++++++++++
 poly.c                 |  169 +++++++++++++++++++++++++++++++++++++++++++++
 sources                |    4 +
 tetromino.h            |  104 ++++++++++++++++++++++++++++
 10 files changed, 766 insertions(+), 0 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index e69de29..ff145ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/cliquer-1.21.tar.gz
+/cliquer.pdf
+/cliquer_bm.pdf
+/cliquer_fm.pdf
diff --git a/basic.c b/basic.c
new file mode 100644
index 0000000..54c455f
--- /dev/null
+++ b/basic.c
@@ -0,0 +1,24 @@
+
+#include <stdio.h>
+#include "cliquer.h"
+
+int main(int argc, char *argv[]) {
+    graph_t *g;
+    set_t s;
+
+    if (argc!=2) {
+        fprintf(stderr,"%s <dimacs_file>\n",argv[0]);
+        return 1;
+    }
+    g=graph_read_dimacs_file(argv[1]);
+    if (g==NULL)
+        return 1;
+
+    ASSERT(graph_test(g,stderr));
+
+    s=clique_find_single(g,0,0,FALSE,NULL);
+    set_print(s);
+
+    return 0;
+}
+
diff --git a/cl.h b/cl.h
new file mode 100644
index 0000000..cd08505
--- /dev/null
+++ b/cl.h
@@ -0,0 +1,33 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef ENABLE_LONG_OPTIONS
+#include <getopt.h>
+#endif
+
+#include "cliquer.h"
+
+
+#define TRYFORHELP  "Try `%s -h' for more information.\n",argv[0]
+
+void printhelp(char *prog);
+void read_options(int argc, char **argv);
+void print_search(graph_t *g);
+boolean record_clique_func(set_t s,graph_t *g,clique_options *opts);
+boolean print_clique_func(set_t s,graph_t *g,clique_options *opts);
+void print_clique(set_t s,graph_t *g);
+
+// As the global variables remain between two SAGE call, they 
+// have to be reset each time
+void sage_reset_global_variables();
+// The opt structure has to be initialised in each SAGE function
+clique_options * sage_init_clique_opt();
+// Computes a maximum clique of the graph g and return its size
+// The table list contains the ID of the vertices
+int sage_clique_max(graph_t *g,int **list);
+int sage_all_clique_max(graph_t *g,int **list);
+int sage_clique_number(graph_t *g);
+
+
diff --git a/cliquer-sagemath.patch b/cliquer-sagemath.patch
new file mode 100644
index 0000000..aea47f9
--- /dev/null
+++ b/cliquer-sagemath.patch
@@ -0,0 +1,178 @@
+diff -up cliquer-1.21/cl.c.orig cliquer-1.21/cl.c
+--- cliquer-1.21/cl.c.orig	2012-05-09 01:22:23.361598133 -0300
++++ cliquer-1.21/cl.c	2012-05-09 01:26:12.768606918 -0300
+@@ -3,17 +3,21 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ 
++#ifdef MAIN
+ #ifdef ENABLE_LONG_OPTIONS
+ #include <getopt.h>
+ #endif
++#endif
+ 
+ #include "cliquer.h"
+ 
+ 
+ #define TRYFORHELP  "Try `%s -h' for more information.\n",argv[0]
+ 
++#ifdef MAIN
+ void printhelp(char *prog);
+ void read_options(int argc, char **argv);
++#endif
+ void print_search(graph_t *g);
+ boolean record_clique_func(set_t s,graph_t *g,clique_options *opts);
+ boolean print_clique_func(set_t s,graph_t *g,clique_options *opts);
+@@ -39,7 +43,131 @@ static set_t *clique_list;
+ static int clique_count=0;
+ static int clique_list_size=0;
+ 
++// As the global variables remain between two SAGE call, they
++// have to be reset each time
++void sage_reset_global_variables(){
++	find_all=FALSE;
++	min_weight=0;
++	min_weight_set=FALSE;
++	max_weight=0;
++	max_weight_set=FALSE;
++	maximal=FALSE;
++	unweighted=FALSE;
++	number1=TRUE;
++	quiet=0;
++	only_weight=FALSE;
++	clique_count=0;
++	clique_list_size=0;
++}
++
++
++// The opt structure has to be initialised in each SAGE function
++clique_options * sage_init_clique_opt(){
++	sage_reset_global_variables();
++	clique_options *opts;
++	quiet++;
++	opts=malloc(sizeof(clique_options));
++	if (quiet)
++		opts->time_function=NULL;
++	else
++		opts->time_function=clique_print_time;
++	opts->output=stderr;
++	opts->reorder_function=reorder;
++	opts->reorder_map=NULL;
++	// Without commenting these lines the sage_all_clique_max
++	// function does not work correctly
++
++	/*
++	if (quiet)
++		opts->user_function=print_clique_func;
++	else
++	*/
++		opts->user_function=record_clique_func;
++	opts->user_data=NULL;
++	opts->clique_list=NULL;
++	opts->clique_list_length=0;
++	return opts;
++}
++
++
++// Computes a maximum clique of the graph g and return its size
++// The table list contains the ID of the vertices
++int sage_clique_max(graph_t *g,int **list){
++	sage_reset_global_variables();
++	quiet++;
++	find_all=FALSE;
++	maximal=TRUE;
++	number1=FALSE;
++	set_t s;
++	int i,l;
++	s=clique_unweighted_find_single(g,min_weight,
++	max_weight,maximal,
++	sage_init_clique_opt());
++
++	// Writing the answer into a int [] to be read by Sage
++	int size=set_size(s);
++	*list=malloc(sizeof(int)*size);
++	l=0;
++	for (i=0; i<SET_MAX_SIZE(s); i++) {
++		if (SET_CONTAINS(s,i)) {
++		*((*list)+l)=i;
++		l++;
++		}
++	}
++	return size;
++}
++
+ 
++int sage_all_clique_max(graph_t *g,int **list){
++	sage_reset_global_variables();
++	/*
++	find_all=TRUE;
++	find_all=FALSE;
++	only_weight=TRUE;
++	maximal=TRUE;
++
++	quiet++;
++	*/
++	// graph_print(g);
++	quiet++;
++	find_all=TRUE;
++	maximal=TRUE;
++	number1=FALSE;
++	int i,j,l;
++
++	clique_unweighted_find_all(g,min_weight,max_weight,
++				   maximal,sage_init_clique_opt());
++
++	int size=set_size(clique_list[0]);
++	*list=malloc(sizeof(int)*(size+1)*clique_count);
++	l=0;
++
++	for (j=0; j<clique_count; j++) {
++		for (i=0; i<SET_MAX_SIZE(clique_list[j]); i++) {
++			if (SET_CONTAINS(clique_list[j],i)) {
++				*((*list)+l)=i;
++				l++;
++			}
++		}
++		*((*list)+l)=-1;
++		l++;
++	}
++	return (1+size)*clique_count;
++}
++
++
++int sage_clique_number(graph_t *g){
++	sage_reset_global_variables();
++	find_all=FALSE;
++	only_weight=TRUE;
++	maximal=TRUE;
++	number1=FALSE;
++	clique_options *opts;
++	opts=sage_init_clique_opt();
++	return clique_unweighted_max_weight(g,opts);
++}
++
++#ifdef MAIN
+ int main(int argc, char **argv) {
+ 	FILE *fp;
+ 	graph_t *g;
+@@ -332,7 +460,7 @@ void read_options(int argc, char **argv)
+ 	file=argv[optind];
+ 	return;
+ }
+-
++#endif /* MAIN */
+ 
+ /*
+  * Prints a line to stderr indicating what is being searched for.
+diff -up cliquer-1.21/graph.c.orig cliquer-1.21/graph.c
+--- cliquer-1.21/graph.c.orig	2012-05-09 01:22:35.617598603 -0300
++++ cliquer-1.21/graph.c	2012-05-09 01:22:53.578599291 -0300
+@@ -359,7 +359,7 @@ graph_t *graph_read_dimacs(FILE *fp) {
+  *       (mainly generator-specific information) are ignored silently,
+  *       for all others a warning message is printed to stderr.
+  */
+-static boolean parse_input(char *str,graph_t *g) {
++boolean parse_input(char *str,graph_t *g) {
+ 	int i,j,w;
+ 	char tmp[16];
+ 
diff --git a/cliquer.1 b/cliquer.1
new file mode 100644
index 0000000..e1fb9d2
--- /dev/null
+++ b/cliquer.1
@@ -0,0 +1,67 @@
+.TH "CLIQUER" "1" "1.21" "Cliquer" "User Commands"
+.SH "NAME"
+cliquer \- Find cliques in arbitrary weighted graphs
+.SH "SYNOPSIS"
+.B cliquer
+[\fIOPTION\fR]... <\fIDIMACS_FILE\fR>
+.SH "DESCRIPTION"
+.PP
+Cliquer is a set of C routines for finding cliques in an arbitrary weighted
+graph.  It uses an exact branch-and-bound algorithm developed by Patric
+Östergård.  It is designed with the aim of being efficient while still being
+flexible and easy to use.
+.SH "OPTIONS"
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Print the help text.
+.TP
+\fB\-a\fR, \fB\-\-all\fR
+Find all cliques.
+.TP
+\fB\-s\fR, \fB\-\-single\fR
+Find a single clique (the default).
+.TP
+\fB\-w\fR, \fB\-\-weight\fR
+Tell only maximum weight (no faster than \-s).
+.TP
+\fB\-m\fR N, \fB\-\-min\fR N
+Search for cliques with weight at least N.  If N = 0, searches for maximum
+weight clique (default).
+.TP
+\fB\-M\fR N, \fB\-\-max\fR N
+Search for cliques with weight at most N.  If N = 0, no limit is imposed
+(default).  Positive N is incompatible with \fI\-\-min 0\fR (\fI\-\-min 1\fR
+is assumed).
+.TP
+\fB\-x\fR, \fB\-\-maximal\fR
+Require cliques to be maximal.
+.TP
+\fB\-u\fR, \fB\-\-unweighted\fR
+Assume weight 1 for all vertices.
+.TP
+\fB\-0\fR, \fB\-\-from\-0\fR
+Number vertices from 0 to n-1 instead of 1 to n when writing.
+.TP
+\fB\-r\fR F, \fB\-\-reorder\fR F
+Reorder with function F.  The available functions are:
+.IP none
+No ordering (same order as in the file).
+.IP reverse
+Reverse of the order in the file.
+.IP default
+Either unweighted\-coloring or weighted\-coloring, depending on weightedness.
+.IP unweighted\-coloring
+Coloring method efficient for unweighted graphs.
+.IP weighted\-coloring
+Coloring method efficient for weighted graphs.
+.IP degree
+Order by ascending degree.
+.IP random
+Random order.
+.TP
+\fB\-q\fR, \fB\-\-quiet\fR
+Suppresses progress output.  Specifying \-q twice suppresses all output except
+the actual result.
+.SH "AUTHORS"
+Cliquer was written by Sampo Niskanen <sampo.niskanen at iki.fi> and
+Patric Östergård <patric.ostergard at tkk.fi>.
diff --git a/cliquer.spec b/cliquer.spec
new file mode 100644
index 0000000..e6f370f
--- /dev/null
+++ b/cliquer.spec
@@ -0,0 +1,137 @@
+Name:           cliquer
+Version:        1.21
+Release:        4%{?dist}
+Summary:        Find cliques in arbitrary weighted graphs
+
+Group:          Applications/Engineering
+License:        GPLv2+
+URL:            http://users.tkk.fi/pat/cliquer.html
+Source0:        http://users.tkk.fi/~pat/%{name}/%{name}-%{version}.tar.gz
+Source1:        http://users.tkk.fi/~pat/%{name}/%{name}_fm.pdf
+Source2:        http://users.tkk.fi/~pat/%{name}/%{name}.pdf
+Source3:        http://users.tkk.fi/~pat/%{name}/%{name}_bm.pdf
+Source4:        http://users.tkk.fi/~pat/%{name}/basic.c
+Source5:        http://users.tkk.fi/~pat/%{name}/hamming.c
+Source6:        http://users.tkk.fi/~pat/%{name}/poly.c
+Source7:        http://users.tkk.fi/~pat/%{name}/tetromino.h
+# Man page formatting by Jerry James, text from the sources
+Source8:        %{name}.1
+# Sagemath patches and extra files. History can be found in related tracs at:
+#       http://trac.sagemath.org/sage_trac/ticket/6355
+#       http://trac.sagemath.org/sage_trac/ticket/5793
+# A private email was also sent to cliquer author asking for any comments
+# on Fedora cliquer review request and sagemath patches.
+Source9:        cl.h
+Patch0:         %{name}-sagemath.patch
+
+Requires:       %{name}-libs%{?_isa} = %{version}-%{release}
+
+%description
+The main cliquer package contains a command-line interface to the
+cliquer library.  Note that the upstream binary name is "cl", which is
+too generic for Fedora.  Therefore, the binary is named "cliquer".
+
+%package libs
+Summary:        Library to find cliques in arbitrary weighted graphs
+Group:          Development/Libraries
+
+%description libs
+Cliquer is a set of C routines for finding cliques in an arbitrary
+weighted graph.  It uses an exact branch-and-bound algorithm developed
+by Patric Östergård.  It is designed with the aim of being efficient
+while still being flexible and easy to use.
+
+%package devel
+Summary:        Development files for cliquer
+Group:          Development/Libraries
+Requires:       %{name}-libs%{?_isa} = %{version}-%{release}
+
+%description devel
+Development files for cliquer.
+
+%prep
+%setup -q
+cp -p %{SOURCE1} %{SOURCE2} %{SOURCE3} .
+%patch0 -p1
+
+mkdir example
+sed 's|"cliquer.h"|<cliquer/cliquer.h>|' %{SOURCE4} > example/basic.c
+sed 's|"cliquer.h"|<cliquer/cliquer.h>|' %{SOURCE5} > example/hamming.c
+sed 's|"cliquer.h"|<cliquer/cliquer.h>|' %{SOURCE6} > example/poly.c
+cp -p %{SOURCE7} example
+
+sed -i \
+    's/59 Temple Place, Suite 330, Boston, MA  02111-1307/51 Franklin Street, Suite 500, Boston, MA  02110-1335/' \
+    LICENSE
+
+%build
+# The distributed Makefile just builds a binary named "cl".  However, the
+# examples show that the internal code is clearly meant to be used as a
+# library.  So we build a library by hand.
+gcc ${RPM_OPT_FLAGS} -fPIC -c cl.c
+gcc ${RPM_OPT_FLAGS} -fPIC -c cliquer.c
+gcc ${RPM_OPT_FLAGS} -fPIC -c graph.c
+gcc ${RPM_OPT_FLAGS} -fPIC -c reorder.c
+gcc ${RPM_OPT_FLAGS} -fPIC -shared -o libcliquer.so.%{version} \
+  -Wl,-soname=libcliquer.so.1 cl.o cliquer.o graph.o reorder.o
+ln -s libcliquer.so.%{version} libcliquer.so.1
+ln -s libcliquer.so.1 libcliquer.so
+
+# Now build the binary
+gcc ${RPM_OPT_FLAGS} -DENABLE_LONG_OPTIONS -DMAIN -c cl.c
+gcc ${RPM_OPT_FLAGS} -o cliquer cl.o -L. -lcliquer
+
+%install
+# Install the library
+mkdir -p $RPM_BUILD_ROOT%{_libdir}
+cp -pP libcliquer.so* $RPM_BUILD_ROOT%{_libdir}
+chmod 0755 $RPM_BUILD_ROOT%{_libdir}/libcliquer.so.%{version}
+
+# Install the binary
+mkdir -p $RPM_BUILD_ROOT%{_bindir}
+install -m 0755 -p cliquer $RPM_BUILD_ROOT%{_bindir}/cliquer
+
+# Install the header file
+mkdir -p $RPM_BUILD_ROOT%{_includedir}/cliquer
+cp -p %{SOURCE9} cliquer.h cliquerconf.h graph.h misc.h reorder.h set.h $RPM_BUILD_ROOT%{_includedir}/cliquer
+
+# Install the man page
+mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1
+cp -p %{SOURCE8} $RPM_BUILD_ROOT%{_mandir}/man1
+
+%check
+LD_LIBRARY_PATH=. make test CFLAGS="${RPM_OPT_FLAGS}"
+
+%post libs -p /sbin/ldconfig
+
+%postun libs -p /sbin/ldconfig
+
+%files
+%doc cliquer*.pdf
+%{_bindir}/%{name}
+%{_mandir}/man1/*
+
+%files libs
+%doc ChangeLog LICENSE README example
+%{_libdir}/libcliquer.so.*
+
+%files devel
+%{_includedir}/%{name}/
+%{_libdir}/libcliquer.so
+
+%changelog
+* Wed Aug 15 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 1.21-4
+- Do not hardcode version in shell commands (#825494)
+- Correct permission of generated library and binary (#825494)
+
+* Tue Aug 14 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 1.21-3
+- Remove %%defattr from spec (#825494)
+- Correct mixed spaces and tabs in spec (#825494)
+- Correct FSF address (#825494)
+- Update information about sagemath patches to upstream cliquer (#825494)
+
+* Sat May 26 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 1.21-2
+- Add sagemath patch interface
+
+* Wed Nov 16 2011 Jerry James <loganjerry at gmail.com> - 1.21-1
+- Initial RPM
diff --git a/hamming.c b/hamming.c
new file mode 100644
index 0000000..11ab412
--- /dev/null
+++ b/hamming.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include "cliquer.h"
+
+/* Function for determining the Hamming distance between 
+   two words, c1 and c2, of length n */
+int distance(int c1, int c2, int n) {
+    int i, c, d;
+	
+    d = 0;
+    c = c1 ^ c2;
+
+    for (i = 0; i < n; i++) {
+        if(c & 1) d++;
+        c >>= 1;
+    }
+    return d;
+}
+
+int main(int argc, char *argv[]) {
+    int i, j;
+    int n, M, d;
+    int order;
+    int nr;
+    graph_t *g;
+	
+    if (argc!=4) {
+        fprintf(stderr,"%s <length> <size> <dist>\n",argv[0]);
+        return 1;
+    }
+    n = atoi(argv[1]);
+    M = atoi(argv[2]);
+    d = atoi(argv[3]);
+
+    /* no timer */
+    clique_default_options->time_function = NULL; 
+
+    order = 1 << n;
+    g = graph_new(order);
+    for (i = 0; i < order; i++)
+        for (j = i+1; j < order; j++)
+            if(distance(i,j,n) >= d)
+                GRAPH_ADD_EDGE(g,i,j);
+    nr = clique_find_all(g,M,M,FALSE,clique_default_options); 
+    printf("Number of codes: %d\n",nr);
+    return 0;
+}
diff --git a/poly.c b/poly.c
new file mode 100644
index 0000000..cc7c881
--- /dev/null
+++ b/poly.c
@@ -0,0 +1,169 @@
+/* poly.c (needs tetromino.h)
+This program demonstrates packing
+tetrominoes (pieces made of four squares of equal size arranged 
+with coincident sides) on an n x m board so that no more tetrominoes
+can fit.  It takes four command-line arguments: 
+poly n m min max
+where n and m are the dimensions of the board and min and max are 
+passed to clique_find_all as the number of pieces to fit on the 
+board.  For example,
+poly 5 5 3 3 
+prints all the ways to fit three tetrominoes on a 5 x 5 board so that 
+no other tetrominoes could fit, and
+poly 6 5 0 0 
+finds all the ways to fit as many pieces as possible on a 6 x 5 board. 
+This program was inspired by Solomon W. Golomb's Puzzle Column 
+"Placing Pentominoes on Boards" in the IEEE Information Theory Society 
+Newsletter, Vol. 52, No. 2, June 2002, p. 7. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cliquer.h"
+
+#define POLYSIZE 4
+
+struct polynomino {
+	char *name;
+	int sizex, sizey;
+	char block[POLYSIZE*POLYSIZE+1];
+};
+
+#include "tetromino.h"
+
+#define VALUE(p,x,y) ((p)*boardsize+(y)*boardx+(x))
+#define PIECE(p) ((p)/(boardsize))
+#define POSX(p)  ((p)%boardx)
+#define POSY(p)  (((p)%(boardsize))/boardx)
+
+static int boardx,boardy;
+static int boardsize;
+static int minpieces;
+static int maxpieces;
+
+static graph_t *generate_graph(void);
+static boolean print_clique(set_t s, graph_t *g, clique_options *opts);
+
+int main(int argc, char *argv[]) {
+	graph_t *g;
+
+	if (argc!=5) {
+		fprintf(stderr,"%s <size_x> <size_y> <min_pieces> "
+			"<max_pieces>\n",argv[0]);
+		return 1;
+	}
+	boardx=atoi(argv[1]);
+	boardy=atoi(argv[2]);
+	boardsize=boardx*boardy;
+	minpieces=atoi(argv[3]);
+	maxpieces=atoi(argv[4]);
+	if ((boardx <= 0) || (boardy <= 0) || (maxpieces<0) || (minpieces<0)) {
+		fprintf(stderr,"Illegal arguments.\n");
+		return 1;
+	}
+
+	printf("Gen graph...\n");
+	g=generate_graph();
+	printf("Testing...\n");
+	graph_test(g,stdout);
+
+	clique_default_options->output=stderr;
+	clique_default_options->user_function=print_clique;
+	clique_find_all(g,minpieces,maxpieces,TRUE,NULL);
+
+	return 0;
+}
+
+
+static boolean collides(int t1, int x1, int y1, int t2, int x2, int y2) {
+	int x,y;
+
+	for (x=MAX(x1,x2); x<MIN(x1+tetromino[t1].sizex,
+				 x2+tetromino[t2].sizex); x++)
+		for (y=MAX(y1,y2); y<MIN(y1+tetromino[t1].sizey,
+					 y2+tetromino[t2].sizey); y++)
+			if (tetromino[t1].block[(y-y1)*POLYSIZE+(x-x1)]=='#' &&
+			    tetromino[t2].block[(y-y2)*POLYSIZE+(x-x2)]=='#')
+				return TRUE;
+	return FALSE;
+}
+
+static graph_t *generate_graph(void) {
+	graph_t *g;
+	int t1,t2,x1,x2,y1,y2;
+
+	g=graph_new(TETROMINOS*boardsize);
+
+	for (t1=0; t1<TETROMINOS; t1++) {
+		for (x1=0; x1<boardx; x1++) {
+			if (x1+tetromino[t1].sizex > boardx)
+				break;
+			for (y1=0; y1<boardy; y1++) {
+				if (y1+tetromino[t1].sizey > boardy)
+					break;
+		for (t2=0; t2<TETROMINOS; t2++) {
+			for (x2=0; x2<boardx; x2++) {
+				if (x2+tetromino[t2].sizex > boardx)
+					break;
+				for (y2=0; y2<boardy; y2++) {
+					if (y2+tetromino[t2].sizey > boardy)
+						break;
+					if (!collides(t1,x1,y1,t2,x2,y2))
+						GRAPH_ADD_EDGE(g,
+							       VALUE(t1,x1,y1),
+							       VALUE(t2,x2,y2));
+				}
+			}
+		}
+			}
+		}
+	}
+	return g;
+}
+
+
+
+static boolean print_clique(set_t s, graph_t *g, clique_options *opts) {
+	static char *buf=NULL;
+	int i,j,c,n;
+	int t,x,y;
+
+	if (buf==NULL) {
+		buf=malloc((boardx*2+1)*boardy+10);
+	}
+
+	c=0;
+	for (i=0; i<boardy; i++) {
+		for (j=0; j<boardx; j++) {
+			buf[c++]='.';
+			buf[c++]=' ';
+		}
+		buf[c++]='\n';
+	}
+	buf[c]=0;
+
+	n=-1;
+	c='A';
+	while ((n=set_return_next(s,n)) >= 0) {
+		t=PIECE(n);
+		x=POSX(n);
+		y=POSY(n);
+
+		if (x+tetromino[t].sizex > boardx)
+			return TRUE;
+		if (y+tetromino[t].sizey > boardy)
+			return TRUE;
+
+		for (i=0; i<POLYSIZE; i++) {
+			for (j=0; j<POLYSIZE; j++) {
+				if (tetromino[t].block[i+j*POLYSIZE]=='#') {
+					buf[(j+y)*(boardx*2+1)+(i+x)*2]=c;
+				}
+			}
+		}
+		c++;
+	}
+
+	printf("%d pieces:\n%s\n",set_size(s),buf);
+	return TRUE;
+}
+
diff --git a/sources b/sources
index e69de29..c0e79ee 100644
--- a/sources
+++ b/sources
@@ -0,0 +1,4 @@
+ac65de2c89134abe2be36542b9465b16  cliquer-1.21.tar.gz
+92d68e23b023f5abf16da3e5b0636c1b  cliquer.pdf
+a8b8aa86460da3f68b9b403bb09bf0e0  cliquer_bm.pdf
+7eb3790632ef86c7363b684e24e8b21c  cliquer_fm.pdf
diff --git a/tetromino.h b/tetromino.h
new file mode 100644
index 0000000..0c42c9a
--- /dev/null
+++ b/tetromino.h
@@ -0,0 +1,104 @@
+
+#define TETROMINOS 19
+
+struct polynomino tetromino[TETROMINOS] = {
+	{ "straight", 1,4,
+	  "#   "
+	  "#   "
+	  "#   "
+	  "#   " },
+	{ "straight 90deg", 4,1,
+	  "####"
+	  "    "
+	  "    "
+	  "    " },
+
+	{ "l", 2,3,
+	  "#   "
+	  "#   "
+	  "##  "
+	  "    " },
+	{ "l 90deg", 3,2,
+	  "  # "
+	  "### "
+	  "    "
+	  "    " },
+	{ "l 180deg", 2,3,
+	  "##  "
+	  " #  "
+	  " #  "
+	  "    " },
+	{ "l 270deg", 3,2,
+	  "### "
+	  "#   "
+	  "    "
+	  "    " },
+	{ "l mirror", 2,3,
+	  " #  "
+	  " #  "
+	  "##  "
+	  "    " },
+	{ "l mirror 90deg", 3,2,
+	  "### "
+	  "  # "
+	  "    "
+	  "    " },
+	{ "l mirror 180deg", 2,3,
+	  "##  "
+	  "#   "
+	  "#   "
+	  "    " },
+	{ "l mirror 270deg", 3,2,
+	  "#   "
+	  "### "
+	  "    "
+	  "    " },
+	
+	{ "t", 3,2,
+	  "### "
+	  " #  "
+	  "    "
+	  "    " },
+	{ "t 90 deg", 2,3,
+	  "#   "
+	  "##  "
+	  "#   "
+	  "    " },
+	{ "t 180 deg", 3,2,
+	  " #  "
+	  "### "
+	  "    "
+	  "    " },
+	{ "t 270 deg", 2,3,
+	  " #  "
+	  "##  "
+	  " #  "
+	  "    " },
+
+	{ "square", 2,2,
+	  "##  "
+	  "##  "
+	  "    "
+	  "    " },
+
+	{ "skew", 3,2,
+	  "##  "
+	  " ## "
+	  "    "
+	  "    " },
+	{ "skew 90deg", 2,3,
+	  " #  "
+	  "##  "
+	  "#   "
+	  "    " },
+	{ "skew mirror", 3,2,
+	  " ## "
+	  "##  "
+	  "    "
+	  "    " },
+	{ "skew mirror 90deg", 2,3,
+	  "#   "
+	  "##  "
+	  " #  "
+	  "    " }
+};


More information about the scm-commits mailing list