2017-04-07 52 views
1

我正在制作基于文本的冒险游戏。我试图让游戏根据他们对某些问题的回答为玩家选择一个“课堂”。 (例如,如果玩家选择偷偷摸摸的或隐身的倾斜答案,那么游戏将向他们分配适合这种类型的人的“流氓”类。如何向用户询问一组问题并存储答案

到目前为止,我已经创建了这个方法,我想稍后调用主程序,然后基于返回值是什么,我将使用另一个条件语句通过调用设置方法来设置玩家类别。

这是我的方法到目前为止。将有非常非常长的chooseSpec方法,因为我想要至少10个问题。我的问题具体是什么是最有效的方法来写出来,并在一个方法中以正确的方式去做这一切?

public static int chooseSpec(Scanner in) { 
    int war = 0; //counter for warrior class 
    int rog = 0; //counter for rogue class 
    int mag = 0; //counter for magic class 
    int choice; //users choice, a number between 1 and 3. 

    System.out.println("While out hunting, you come across a deer which has been badly mauled by a wolf. What do you do?" + "\n" + 
         "1. Draw your dagger and end it's suffering" + "\n" + 
         "2. Attempt to heal it with a herbal concoction, knowing it may not work." + "\n" + 
         "3. Leave it, and allow nature to take it's course."); 
    choice = in.nextInt(); 

    switch (choice) { 
     case 1: 
      war += 1; 
      break; 

     case 2: 
      mag += 1; 
      break; 
     case 3: 
      rog +=1; 
    } 
    return choice; 
} 
+1

这是一个实现flavory,不是技术问题,请google;) –

+0

欢迎来到Stack Overflow!如果你还没有参加[旅游],请看[问]。无论如何,我认为你应该更多地关注面向对象编程(OOP)。查看[classes](https://docs.oracle.com/javase/tutorial/java/concepts/class.html)和[collections](https://docs.oracle.com/javase/7/docs/api /java/util/Collections.html)。你可以用任何东西做一堂课。对于初学者来说,可能会尝试创建一个名为“Question”的类,其中包含与问题相关的所有信息。 – PJvG

+0

另外,如果您有关于*软件设计*的问题,那么这些更适合http://softwareengineering.stackexchange.com/。如果您希望获得有关代码的反馈,则可以尝试http://codereview.stackexchange.com/。 – PJvG

回答

2

您应该将所有问题和答案存储在一个对象中。这样,你可以混合每个问题的答案,目前选择总是1将保证相同的答案。

其次它允许您在每个问题中添加任意数量的答案,甚至在每次开始游戏时混合他们的顺序。

这也很好用更多的Java抽象这里:

public ClassType chooseSpec(List<Question> questions, Scanner in) { 

    List<ClassType> selectedAnswers = new ArrayList<>(questions.size()); 
     // iterate over all your questions 
    for(Question question: questions) { 
     // print question and all answers 
     System.out.println(question.getQuestion() + "\n" 
       + question.getAnswers().stream().map(Answer::getQuestion) 
       .collect(Collectors.joining("\n"))); 

     int choice = in.nextInt(); 
     if(choice >= question.getAnswers().size()){ 
      // check if answer is within the scope 
      throw IllegalArgumentException("There are only "+question.getAnswers() +" answers"); 
     } 
     // add selected answer type to global result list 
     selectedAnswers.add(question.getAnswers().get(choice-1).getClassType()); 
    } 

    return findMostPolularClass(selectedAnswers); 
} 

private ClassType findMostPolularClass(List<ClassType> selectedAnswers){ 
    // might be too fancy, but it will find most frequent answer 
    Map<ClassType, Long> occurences = selectedAnswers.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting())); 
    return occurences.entrySet().stream() 
      .max(Comparator.comparing(Map.Entry::getValue)).get().getKey(); 
} 

举行的问题,所有的答案:

static class Question { 

    private final String question; 
    private final List<Answer> answers; 

    public Question(String question, List<Answer> answers) { 
     this.question = question; 
     this.answers = answers; 
    } 

    public String getQuestion() { 
     return question; 
    } 

    public List<Answer> getAnswers() { 
     return answers; 
    } 
} 

每个答案定义的答复文件,以及它属于最好

哪一类
class Answer { 

    private final String question; 
    private final ClassType classType; 
    // static constructors, help to work with this model 
    public static Answer mageAnswer(String question) { 
     return new Answer(question, ClassType.MAGE); 
    } 

    public static Answer wariorAnswer(String question) { 
     return new Answer(question, ClassType.WARIOR); 
    } 

    private Answer(String question, ClassType classType) { 
     this.question = question; 
     this.classType = classType; 
    } 

    public ClassType getClassType() { 
     return classType; 
    } 

    public String getQuestion() { 
     return question; 
    } 
} 

//将您的所有课程存储在这里,它比可记忆的数字更具可读性小号:)

enum ClassType { 
    MAGE, WARIOR, ARCHER 
} 
0

您应该将所有问题存储在一个集合中。像arraylist。假设你有10个问题,这个方法应该在迭代问题arraylist的foreach循环中调用。这样你的方法将被重用。

0

从你的要求,你要处理三个不同Professions

  • 战士
  • 盗贼
  • 法师

这些职业不抱任何状态并且新实例不是动态构建的。因此,一个Enumeration将是一个不错的人选,以表示它们:

public enum Profession { 
    WARRIOR, 
    ROGUE, 
    MAGE; 
} 

接下来你要求玩家选择哪个与1. Profession和2相关的Answer。用Token,输入你从键盘读取:

public class Answer { 

    public static Answer of(Profession profession, String token, String description) { 
     return new Answer(description, profession, token); 
    } 

    private final String description; 
    private final Profession profession; 
    private final String token; 

    public Answer(String description, Profession profession, String token) { 
     this.description = requireNonNull(description); 
     this.profession = requireNonNull(profession); 
     this.token = requireNonNull(token); 
    } 

    public String getDescription() { 
     return description; 
    } 

    public Profession getProfession() { 
     return this.profession; 
    } 

    public String getToken() { 
     return token; 
    } 

    public boolean isMatch(String token) { 
     return this.token.equals(token); 
    } 
} 

你想与Answer做的是:

  • 它呈现给玩家。
  • 检查从玩家处获得的令牌是否与Answer所关联的令牌匹配。以可读形式构建Answer

AnswersQuestions的一部分,它们不保持状态或动态创建。再一次的Enumeration将代表他们很好:

public enum Question { 

    MAULED_DEER("While out hunting, you come across a deer which has been badly mauled by a wolf. What do you do?", 
     Answer.of(WARRIOR, "1", "Draw your dagger and end it's suffering."), 
     Answer.of(ROGUE, "2", "Attempt to heal it with a herbal concoction, knowing it may not work."), 
     Answer.of(MAGE, "3", "Leave it, and allow nature to take it's course.")), 

    GAME_DEVELOPMENT("While playing games you decided to develop your very own. Which language do you choose?", 
      Answer.of(MAGE, "a", "OOD with Java."), 
      Answer.of(WARRIOR, "b", "OOD and FP using Scala."), 
      Answer.of(ROGUE, "c", "Pure FP with Haskel.")); 

    private final String description; 
    private final List<Answer> answers; 

    Question(String description, Answer... answers) { 
     this.description = description; 
     this.answers = Arrays.asList(answers); 
    } 

    public String getDescription() { 
     return description; 
    } 

    public List<Answer> getAnswers() { 
     return answers; 
    } 

    public Set<Answer> getMatches(String token) { 
     return answers.stream() 
       .filter(answer -> answer.isMatch(token)) 
       .collect(Collectors.toSet()); 
    } 
} 

Questions必须是:

  • 他们Answers一起渲染。
  • 应该确定哪个Answers确实匹配给定的令牌(从玩家处获得)。

但是你要问玩家很多Questions并且想跟踪他给出的Answers。更准确地说,Profession你与Answer相关联。你想跟踪每个Profession当前比分:

public class Scores { 

    private Map<Profession, AtomicInteger> scores = new HashMap<Profession, AtomicInteger>() {{ 
     for (Profession profession : Profession.values()) { 
      put(profession, new AtomicInteger()); 
     } 
    }}; 

    private int max = 0; 

    public void incrementIf(boolean isTrue, Profession profession) { 
     if (isTrue) { 
      int score = scores.get(profession).incrementAndGet(); 
      max = Math.max(max, score); 
     } 
    } 

    public Set<Profession> getWinners() { 
     return Arrays.stream(Profession.values()) 
       .filter(profession -> scores.get(profession).get() == max) 
       .collect(Collectors.toSet()); 
    } 
} 

类型Scores的责任确定和哪个Profession递增的得分。最后,应当计算查询的Winners

public class Inquiry { 

    public Set<Profession> obtainChoice(Scanner scanner) { 
     Scores scores = new Scores(); 
     for (Question question : Question.values()) { 
      String token = ask(question, scanner); 
      question.getAnswers().forEach(answer -> 
        scores.incrementIf(answer.isMatch(token), answer.getProfession())); 
     } 
     return scores.getWinners(); 
    } 

    private String ask(Question question, Scanner scanner) { 
     System.out.println(question.getDescription()); 
     question.getAnswers().forEach(answer -> 
       System.out.println(answer.getToken() + ") " + answer.getDescription())); 
     do { 
      String token = scanner.nextLine(); 
      for (Answer answer : question.getAnswers()) { 
       if (token.equals(answer.getToken())) { 
        return token; 
       } 
      } 
      System.out.println("Try again and select a valid answer please!"); 
     } while (true); 
    } 
} 

的最后一块拼图缺少的是应用程序本身,这会触发查询:

public class Game { 

    public static void main(String[] args) { 
     try (Scanner scanner = new Scanner(System.in)) { 
      Set<Profession> choices = new Inquiry().obtainChoice(scanner); 
      if (choices.size() == 1) { 
       System.out.println("You are a true " + choices.iterator().next()); 
      } else { 
       System.out.println("You havn't found your path yet and hence must choose between:"); 
       choices.forEach(profession -> System.out.println(" - " + profession)); 
      } 
     } 
    } 
} 

这种设计致力成为readableextendable等等你可以轻松地改变事物。

玩得开心!

相关问题