Package grammar.output

Source Code of grammar.output.AbstractTester$Question

package grammar.output;

import grammar.input.stdin.Command;
import grammar.input.stdin.CommandFactory;
import grammar.input.stdin.Command.Action;
import grammar.input.stdin.Command.ExitCommand;
import grammar.input.stdin.Command.HelpCommand;
import grammar.model.Language;
import grammar.util.Utilities;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

public abstract class AbstractTester {
  private static final BigDecimal CORRECT_ANSWER_SCORE_INCREMENT           = new BigDecimal(1);
  private static final BigDecimal PARTIALLY_CORRECT_ANSWER_SCORE_INCREMENT = new BigDecimal("0.5");
  private static final int        MAX_SCOPE_ITEMS_TO_PRINT                 = 6;
 
  public abstract String getHelpText();
 
  public abstract Question getNextQuestion();
 
  public interface Question {
    public String getCorrectAnswer();
    public String getQuestionText();
    public boolean isCorrect(String response);
    public String isPartiallyCorrect(String response);
    public String getHintText();
    public String getTextToRead();
  }
 
  private Language language;
 
  public AbstractTester(Language language) {
    this.language = language;
  }
 
  public void play() throws IOException {
    BigDecimal score = new BigDecimal(0);
    BigDecimal highScore = new BigDecimal(0);
    BigDecimal totalQuestionsAnswered = new BigDecimal(0);
    BigDecimal totalCorrectAnswers = new BigDecimal(0);
   
    System.out.println("Type help for commands.");
    while (true) {
      Question q = getNextQuestion();
     
      System.out.println();
      System.out.println(q.getQuestionText());
      String correctAnswer = q.getCorrectAnswer();
      String response = Utilities.readLineFromStdin();
     
      try {
        while (true) { // loop broken by exception being thrown
          try {
            processCommand(response);
            if (exit)
              return;
          }
          catch (IllegalStateException e) {
            System.out.println("Command ignored - it would leave nothing in scope!");
          }
          response = Utilities.readLineFromStdin();
        }
      }
      catch (IllegalArgumentException e) {
        // not a command
      }
     
      if (q.isCorrect(response)) {
        totalCorrectAnswers = totalCorrectAnswers.add(new BigDecimal(1));
        totalQuestionsAnswered = totalQuestionsAnswered.add(new BigDecimal(1));;
        score = score.add(CORRECT_ANSWER_SCORE_INCREMENT);
        System.out.println("CORRECT! "+score.toPlainString()+
            " point"+(score.compareTo(new BigDecimal(1)) != 0?"s":"")+" ("+
            totalCorrectAnswers.multiply(new BigDecimal(100)).divideToIntegralValue(totalQuestionsAnswered).round(MathContext.DECIMAL128)+
            "% answered correctly thus far)!");
        if (score.compareTo(highScore) > 0)
          highScore = score;
      }
      else if (q.isPartiallyCorrect(response) != null) {
        totalCorrectAnswers = totalCorrectAnswers.add(new BigDecimal(1));
        totalQuestionsAnswered = totalQuestionsAnswered.add(new BigDecimal(1));;
        score = score.add(PARTIALLY_CORRECT_ANSWER_SCORE_INCREMENT);
        System.out.println("ALMOST! "+q.isPartiallyCorrect(response)+"Correct answer: "+correctAnswer+". "+
            score.toPlainString()+" point"+
            (score.compareTo(new BigDecimal(1)) >= 0?"s":"")+" ("+
            totalCorrectAnswers.multiply(new BigDecimal(100)).divideToIntegralValue(totalQuestionsAnswered).round(MathContext.DECIMAL128)+
            "% answered correctly thus far)!");
        if (score.compareTo(highScore) > 0)
          highScore = score;
      }
      else {
        totalQuestionsAnswered = totalQuestionsAnswered.add(new BigDecimal(1));;
        System.out.println("WRONG! Correct answer: "+correctAnswer+
          ". Score this time: "+score+"; highest so far: "+highScore+" ("+
          totalCorrectAnswers.multiply(new BigDecimal(100)).divideToIntegralValue(totalQuestionsAnswered).round(MathContext.DECIMAL128)+
          "% answered correctly thus far).");
        score = new BigDecimal(0);
      }
      System.out.println(q.getHintText());
     
      if (language.isSpeechSynthesisSupported())
        language.getSpeechSynthesiser().say(q.getTextToRead());
    }
  }
 
  private boolean exit = false;
 
  private void processCommand(String in) {
    Command command = CommandFactory.interpret(language, in);
    Action action = command.getAction();
   
    if (command instanceof ExitCommand) {
      exit = true;
    }
    else if (command instanceof HelpCommand) {
      System.out.println(getHelpText());
    }
    else if (processCommand(command, action)) {
      return;
    }
    else {
      throw new Error("Unimplemented command type: "+command);
    }
  }
 
  public abstract boolean processCommand(Command command, Action action);
 
  protected static <T> void updateScope(Set<T> scope, Set<T> update, Action action) {
    Set<T> scopeTmp = new HashSet<T>(scope);
    if (action.equals(Action.ADD))
      scopeTmp.addAll(update);
    else if (action.equals(Action.USE)) {
      scopeTmp.clear();
      scopeTmp.addAll(update);
    }
    else if (action.equals(Action.REMOVE))
      scopeTmp.removeAll(update);
    else
      throw new IllegalStateException();
    if (scopeTmp.size() == 0)
      throw new IllegalStateException("Nothing left in scope!");
    scope.clear();
    scope.addAll(scopeTmp);
  }
 
  protected static <S> void printScope(SortedSet<S> scope, String type) {
    StringBuilder sb = new StringBuilder();
    sb.append(type+": ");
    Set<S> s = new TreeSet<S>();
    if (scope.size() > MAX_SCOPE_ITEMS_TO_PRINT) {
      Iterator<S> iterator = scope.iterator();
      for (int i = 0; i < MAX_SCOPE_ITEMS_TO_PRINT; i++) {
        s.add(iterator.next());
      }
    }
    else {
      s.addAll(scope);
    }
   
    int sz = s.size();
    int i = 0;
    for (Object o : s) {
      sb.append(Utilities.asHumanReadableName(o.toString()));
      if (i < sz-1)
        sb.append(", ");
      i++;
    }
    if (scope.size() > MAX_SCOPE_ITEMS_TO_PRINT) {
      sb.append("... (");
      sb.append(scope.size()-MAX_SCOPE_ITEMS_TO_PRINT);
      sb.append(" more)");
    }
    String str = sb.toString();
    System.out.println(str);
  }

  public Language getLanguage() {
    return language;
  }
}
TOP

Related Classes of grammar.output.AbstractTester$Question

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.