src/strategy/Ranks.java
public static void subgame(Game game, TreeSet<Integer> states, TreeSet<Integer> targets, int reacher) {
		assert(game != null);
		assert(states != null);
		assert(targets != null);
		assert(reacher == 1 || reacher == 2);
		int opponent = (reacher==1)?2:1;
		
		//Set the targets
		for (Integer key : states)
			if (targets.contains(key))
				game.states.get(key).target = true;
			else
				game.states.get(key).target = false;
		
		//Create the tBackw restricted to the subgame
		//I don't need tForw but I have to remember the sizes
		//(for each state, how many forward transitions it has left)
		TreeMap<Integer,AtomicInteger> tForwSize = new TreeMap<Integer,AtomicInteger>();
		TreeMap<Integer,TreeSet<Integer>> tBackw = new TreeMap<Integer,TreeSet<Integer>>();
		for (Integer key : states) {
			tForwSize.put(key, new AtomicInteger(0));
			tBackw.put(key, new TreeSet<Integer>());			
		}
		for (Integer from : states)
			for (Integer into : game.transitions.get(from))
				if (states.contains(into)) {
					tBackw.get(into).add(from);
					tForwSize.get(from).getAndIncrement();					
				}
		
		
		//Transitions and targets are ready, compute the ranks
		LinkedList<Integer> queue1 = new LinkedList<Integer>();
		LinkedList<Integer> queue2 = new LinkedList<Integer>();
		for (Integer key : states) {
			game.states.get(key).rank = -1;
			if (game.states.get(key).target) {
				queue1.add(key);
				queue2.add(null);			
			}
		}
		
		while (queue1.size() > 0) {
			Integer current = queue1.remove();
			Integer currentHead = queue2.remove();
			
			if (game.states.get(current).rank == -1) //Only handle states with rank -1
				if ((currentHead != null) && (game.states.get(current).player == opponent)
						&& (tForwSize.get(current).get() > 1)) {
					//Nontarget states of opponent player where he still has an alternative transition
					tForwSize.get(current).getAndDecrement();
					tBackw.get(currentHead).remove(current);
				} else {
					//Targets, states of reaching player, states of opponent player with no alternative transition
					game.states.get(current).rank =
					((currentHead == null) ? 0 : (game.states.get(currentHead).rank + 1));
					for (Integer tail : tBackw.get(current))
						if (game.states.get(tail).rank == -1) { //Only add states with rank -1
							queue1.add(tail);
							queue2.add(current);
						}
				}
		}
	}
/** Computes the ranks in a subgame
	 *  @param game     Game instance
	 *  @param states	State space of the subgame
	 *  @param targets	Target states in this subgame
	 *  @param reacher	Which player wants to reach the targets
	 * */
Computes the ranks in a subgame
@param game     Game instance
@param states       State space of the subgame
@param targets      Target states in this subgame
@param reacher      Which player wants to reach the targets
Computes the ranks in a subgame @param game Game instance @param states State space of the subgame @param targets Target states in this subgame @param reacher Which player wants to reach the targets
public static void subgame(Game game, TreeSet<Integer> states, TreeSet<Integer> targets, int reacher) {
		assert(game != null);
		assert(states != null);
		assert(targets != null);
		assert(reacher == 1 || reacher == 2);
		int opponent = (reacher==1)?2:1;
		for (Integer key : states)
			if (targets.contains(key))
				game.states.get(key).target = true;
			else
				game.states.get(key).target = false;
		TreeMap<Integer,AtomicInteger> tForwSize = new TreeMap<Integer,AtomicInteger>();
		TreeMap<Integer,TreeSet<Integer>> tBackw = new TreeMap<Integer,TreeSet<Integer>>();
		for (Integer key : states) {
			tForwSize.put(key, new AtomicInteger(0));
			tBackw.put(key, new TreeSet<Integer>());			
		}
		for (Integer from : states)
			for (Integer into : game.transitions.get(from))
				if (states.contains(into)) {
					tBackw.get(into).add(from);
					tForwSize.get(from).getAndIncrement();					
				}
		LinkedList<Integer> queue1 = new LinkedList<Integer>();
		LinkedList<Integer> queue2 = new LinkedList<Integer>();
		for (Integer key : states) {
			game.states.get(key).rank = -1;
			if (game.states.get(key).target) {
				queue1.add(key);
				queue2.add(null);			
			}
		}
		while (queue1.size() > 0) {
			Integer current = queue1.remove();
			Integer currentHead = queue2.remove();
			if (game.states.get(current).rank == -1) 
				if ((currentHead != null) && (game.states.get(current).player == opponent)
						&& (tForwSize.get(current).get() > 1)) {
					tForwSize.get(current).getAndDecrement();
					tBackw.get(currentHead).remove(current);
				} else {
					game.states.get(current).rank =
					((currentHead == null) ? 0 : (game.states.get(currentHead).rank + 1));
					for (Integer tail : tBackw.get(current))
						if (game.states.get(tail).rank == -1) { 
							queue1.add(tail);
							queue2.add(current);
						}
				}
		}
	}
public static void subgame ( Game game , TreeSet < Integer > states , TreeSet < Integer > targets , int reacher ) { assert ( game != null ) ; assert ( states != null ) ; assert ( targets != null ) ; assert ( reacher == 1 || reacher == 2 ) ; int opponent = ( reacher == 1 ) ? 2 : 1 ; for ( Integer key : states ) if ( targets . contains ( key ) ) game . states . get ( key ) . target = true ; else game . states . get ( key ) . target = false ; TreeMap < Integer , AtomicInteger > tForwSize = new TreeMap < Integer , AtomicInteger > ( ) ; TreeMap < Integer , TreeSet < Integer > > tBackw = new TreeMap < Integer , TreeSet < Integer > > ( ) ; for ( Integer key : states ) { tForwSize . put ( key , new AtomicInteger ( 0 ) ) ; tBackw . put ( key , new TreeSet < Integer > ( ) ) ; } for ( Integer from : states ) for ( Integer into : game . transitions . get ( from ) ) if ( states . contains ( into ) ) { tBackw . get ( into ) . add ( from ) ; tForwSize . get ( from ) . getAndIncrement ( ) ; } LinkedList < Integer > queue1 = new LinkedList < Integer > ( ) ; LinkedList < Integer > queue2 = new LinkedList < Integer > ( ) ; for ( Integer key : states ) { game . states . get ( key ) . rank = - 1 ; if ( game . states . get ( key ) . target ) { queue1 . add ( key ) ; queue2 . add ( null ) ; } } while ( queue1 . size ( ) > 0 ) { Integer current = queue1 . remove ( ) ; Integer currentHead = queue2 . remove ( ) ; if ( game . states . get ( current ) . rank == - 1 ) if ( ( currentHead != null ) && ( game . states . get ( current ) . player == opponent ) && ( tForwSize . get ( current ) . get ( ) > 1 ) ) { tForwSize . get ( current ) . getAndDecrement ( ) ; tBackw . get ( currentHead ) . remove ( current ) ; } else { game . states . get ( current ) . rank = ( ( currentHead == null ) ? 0 : ( game . states . get ( currentHead ) . rank + 1 ) ) ; for ( Integer tail : tBackw . get ( current ) ) if ( game . states . get ( tail ) . rank == - 1 ) { queue1 . add ( tail ) ; queue2 . add ( current ) ; } } } }
Computes the ranks in a subgame
  @param game     Game instance
  @param states       State space of the subgame
  @param targets      Target states in this subgame
  @param reacher      Which player wants to reach the targets
Computes the ranks in a subgame @param game Game instance @param states State space of the subgame @param targets Target states in this subgame @param reacher Which player wants to reach the targets
//Set the targets //Create the tBackw restricted to the subgame //I don't need tForw but I have to remember the sizes //(for each state, how many forward transitions it has left) //Transitions and targets are ready, compute the ranks //Only handle states with rank -1 //Nontarget states of opponent player where he still has an alternative transition //Targets, states of reaching player, states of opponent player with no alternative transition //Only add states with rank -1