Node<Move, GS> selectChild() {
		if (unexpanded() || terminated()) {
			// Leaf node or node of a terminated state, nothing to select.
			return null;
		}
		if (gameState.currentPlayer() == GameState.PLAYER_CHANCE_NODE) {
			assert chanceNodeChildren != null;
			return chanceNodeChildren.get();
		} else {
			if (visitCount == 0) {
				return randomElement(children);
			}
			double maxScore = -Double.MAX_VALUE;
			Node<Move, GS> selected = null;
			ArrayList<Node<Move, GS>> unvisitedChildren = new ArrayList<>();
			for (Node<Move, GS> child : children) {
				if (child.visitCount() == 0) {
					unvisitedChildren.add(child);
					continue;
				}
				if (unvisitedChildren.isEmpty()) {
					double uctScore = child.sumScores() / child.visitCount() +
						UCT_Coef * Math.sqrt(Math.log(visitCount) / child.visitCount());
					if (uctScore > maxScore) {
						maxScore = uctScore;
						selected = child;
					}
				}
			}
			return unvisitedChildren.isEmpty() ? selected : randomElement(unvisitedChildren);
		}
	}