private DataInstance scoreRack(int turns){
		DataInstance max_score = null;
		double rack_size = game.rack_size;
		
		//Loop through every long usable sequence for this rack
		double rack_de = rack.scoreRackDE(game.dist_flat, null),
				rack_de_skew = rack.scoreRackDE(game.dist_flat, game.dist_skew);
		for (Rack.LUS lus: rack.getLUS(USE_COMBOS)){
			/* Other features to consider:
				- scoreDensityAdjacent weighted by probabilities or distribution-error
				- scoreClumpDE weighted by probabilities or density
				- scoreProbability weighted by distribution-error
				- bonusMode: may optimize for denser clumps to get bonus points
				- min_streak/rack_size: optimize for dense clumps to actually win the game

				Tree traversal techniques:
				- just take output of getLSU()
				- use probabilities/density/clumpDE as a UsableMetric for getLSU()
				- use probabilties/... to generate new sequences from getLSU() output
			
				TODO:
				- use other player's visible cards in rack to see if discarding would lose the game
				- train with deep learning enabled
				- fix probability calculator
				- train with bonus_mode & min_streak features
			*/
			DataInstance d = new DataInstance(FEATURES);
			//if closer to one, the game is close to ending; may want to get more points before game ends
			d.addFeature(turns > rack_size*2 ? rack_size*2 : turns, rack_size);
			//maximize points scored (possibly, when turn_ratio is high and sequence length is low)
			d.addFeature(rack.scorePoints(game.bonus_mode), max_points);
			//maximize usable sequence length
			d.addFeature(lus.cards.length, rack_size);
			//get a rack with flat, spread out distribution
			d.addFeature(rack_de, 1);
			//same as previous, except ignoring unusable cards
			d.addFeature(rack.scoreClumpDE(lus, game.dist_flat, null), 1);
			//maximize probability of getting a larger sequence
			d.addFeature(rack.scoreProbability(lus, null, false, true, 0), 1);
			//same as previous, except does not penalize as much for low probabilities
			d.addFeature(rack.scoreProbability(lus, null, true, true, 0), 1);
			//minimize density error of adjacent cards of clumps in a sequence
			d.addFeature(rack.scoreDensityAdjacent(lus, null, 0), 1);
			//same as previous, except penalizes for clumps of only length 1
			d.addFeature(rack.scoreDensityAdjacent(lus, null, 1), 1);
			//minimize density error of cards to clump centroids
			d.addFeature(rack.scoreDensityCenter(lus, null), 1);

			//SKEWED FEATURES
			//All the same as before, except optimizes for a higher score if the player doesn't win
			d.addFeature(rack_de_skew, 1);
			d.addFeature(rack.scoreClumpDE(lus, game.dist_flat, game.dist_skew), 1);
			d.addFeature(rack.scoreProbability(lus, game.dist_skew, false, true, 0), 1);
			d.addFeature(rack.scoreProbability(lus, game.dist_skew, true, true, 0), 1);
			d.addFeature(rack.scoreDensityAdjacent(lus, game.dist_skew, 0), 1);
			d.addFeature(rack.scoreDensityAdjacent(lus, game.dist_skew, 1), 1);
			d.addFeature(rack.scoreDensityCenter(lus, game.dist_skew), 1);

			//Run it through the neural network
			score_net.compute(d.inputs);
			d.output = score_net.getOutput(0);
			if (max_score == null || d.output > max_score.output)
				max_score = d;
		}
		
		return max_score;
	}