private void construct(Constraint[] constraints, int nconstraints) {
	this.constraints=constraints;
	this.nconstraints=nconstraints;
	VERBOSE=CSPStrategy.VERBOSE;

	variables=null;
	nodes = new ConstraintList[nconstraints*2];
	nvariables=0;

	min=0;
	max=0;
	bestProbe=null;
	
	// tally variables and count maximum mines
	for (int i=0; i<nconstraints; ++i) {
	    BoardPosition[] vararray = constraints[i].getVariables();
	    for (int j=0; j<vararray.length; ++j) {
		boolean found=false;
		for (int k=0; k<nvariables; ++k)
		    if (nodes[k].variable.equals(vararray[j])) {
			nodes[k].addConstraint(constraints[i]);
			found=true;
			break;
		    }
		if (!found) {
		    if (nvariables>=nodes.length) {
			// reallocate variables
			ConstraintList[] newnodes = 
			    new ConstraintList[nvariables*2];
			System.arraycopy(nodes,0,newnodes,0,nvariables);
			nodes=newnodes;
		    }
		    nodes[nvariables++] = 
			new ConstraintList(constraints[i],vararray[j]);
		}
	    }
	    min+=constraints[i].getConstant();
	}

	/* Note: we used min here to tally the absolute maximum number of mines
	 * expected because this number is a good initial value for the minimum
	 * mines variables.
	 */

	// sort variables in decending order by number of constraints
	Arrays.sort(nodes,0,nvariables);
	if (nodes[0].nconstraints<nodes[nvariables-1].nconstraints)
	    System.err.println("WRONG ORDER!!!");

	// create variables array
	variables = new BoardPosition[nvariables];
	for (int i=0; i<nvariables; ++i)
	    variables[i] = nodes[i].variable;

	// create needed arrays
	solutions = new int[min+1];
	mines = new int[min+1][];
	for (int i=0; i<=min; ++i)
	    mines[i] = new int[nvariables];
    }