public double EV() {
    	double ev = 0;
    	double ev_fold;
    	double ev_check;
    	double ev_raise;
    	switch(nodeType) {
    	case SHOWDOWN :
	    // if it's a showdown node, ev is based and chance of winning and amount bet 
    		double winPossibility = gameInfo.opponentModel.winPossibility(actionHistory, gameInfo, knownCards.evaluate());
    		ev = winPossibility * opponentBetAmount - ((1 - winPossibility) * playerBetAmount);
    		// System.out.println("Win%: " + winPossibility + " BetAmt: " + opponentBetAmount + " ev: " + ev);
    		break;
    		
    	case CHANCE :
	    // if chance node, ev is equal to ev of successor
	    // TODO:  calculate and average EV of all possible chance outcomes (not just one)
    		ev = successor(null).EV();
    		break;
    		
    	case PLAYER :
	    // EV of player node is max EV of player checking, raising or folding
    		ev_fold = -playerBetAmount;
    		ev_check = successor(Action.CHECK).EV();
    		if(reachedMaxRaises()) {
    			ev = Math.max(ev_fold, ev_check);
    		} else {
    			ev_raise = successor(Action.RAISE).EV();
    			ev = Math.max(Math.max(ev_fold, ev_check), ev_raise);
    		}
    		break;
    	
	case OPPONENT :
	    // EV of opponent node is EV of each of opponent's actions multiplied
	    // by estimated probability of them taking that action
	        
			double[] actionProbabilities = gameInfo.opponentModel.actionProbabilities(actionHistory, this);
			double p_fold = actionProbabilities[0];
			double p_check = actionProbabilities[1];
			double p_raise = actionProbabilities[2];
			
    		ev_fold = opponentBetAmount;
    		ev_check = successor(Action.CHECK).EV();
    		
    		if(reachedMaxRaises()) {
    			ev = ev_check;
    		} else {
    			ev_raise = successor(Action.RAISE).EV();
    			ev = p_fold * ev_fold + p_check * ev_check + p_raise * ev_raise;
    		}
    		break;
    	}

    	return ev;
    }