public int slideChar() {
		AlignWin win = curAli.randWin(2);
		AlignCol col1 = win.first, col2 = win.last;
		int[] inds1 = col1.inds, inds2 = col2.inds;
		int s = 0;	// slidables
		for(int i = 0; i < inds1.length; i++)
			if(inds1[i] >= 0 ^ inds2[i] >= 0)
				rows[s++] = i;
		if(s > 0) {
			// choose a random slidable
			s = rows[Utils.generator.nextInt(s)];

			if((inds1[s] >= 0 ? col1.singOrd : col2.singOrd) < 0) {		// disallow sliding character from singular column
				// evaluate swap
				int ch1 = inds1[s], ch2 = inds2[s];	// characters to swap
				int newDist = curDist;
				newDist -= distCalc.distSingle(inds1, s, ch1)+distCalc.distSingle(inds2, s, ch2);
				newDist += distCalc.distSingle(inds1, s, ch2)+distCalc.distSingle(inds2, s, ch1);
				if(Utils.DEBUG) {
					inds1[s] = ch2; inds2[s] = ch1;
					int testDist = distCalc.dist(curAli);
					inds1[s] = ch1; inds2[s] = ch2;
					if(testDist != newDist)
						throw new Error("Inconsistency in distance calculation in slideChar");
				}
				double newPi = logPi(newDist);
//				double mh = newPi/curPi;
				double logMh = newPi-curPi;
				if(logMh >= 0 || Utils.generator.nextDouble() < Math.exp(logMh)) {
					scAccept.inc();
					inds1[s] = ch2; inds2[s] = ch1;
					curAli.updateSing(col1); curAli.updateSing(col2);
					curDist = newDist;
					curPi = newPi;
					return 1;
				} else {
					scReject.inc();
				}
			} else {
				scSing.inc();	// shift from singular column was selected
			}
		} else {
			scNoMoves.inc();	// no rows with possible shift (i.e. gap - nongap pair)
		}
		return 0;
	}