2016-12-30 39 views
1

所以我正在写一个基本的MasterMind游戏,它大多是功能性的。然而,它的表现奇怪的行为,我不确定为什么。为什么我的类变量在一个不相关的方法运行后重写自己?

这个想法是什么定义了一个代码,它的行为是一个文件,游戏是另一个文件,Main创建一个新游戏并开始播放。当我初始化游戏时,计算机按预期创建一个新的随机字符串4(“密码”);但是一旦我得到了用户猜测的输入,它似乎就会将密码重写为我输入的内容。此外,我的评估匹配方法根本不起作用,但考虑到密码不断变化意味着它没有被设置为开头,我不确定原因。

以下全部三个类。为什么我的游戏中的类变量没有正确设置并且无法通过其他方法访问?

Main.java

class Main { 
    public static void main(String[] args) { 
    Game newGame = new Game(); 
    newGame.play(); 
    } 
} 

Code.java

import java.util.Random; 
import java.util.HashMap; 
import java.util.Collection; 
import java.util.ArrayList; 
import java.util.Set; 

import java.lang.Math; 
import java.lang.StringBuilder; 

class Code { 
    private static HashMap<String,String> PEGS; 
    private static ArrayList<String> pegStrings; 
    protected static String secretCodeString; 


    public static void main(String[] args) { 

    } 

    public Code(String input){ 
    this.secretCodeString = input; 
    } 

    public Code(){ 
    randomize(); 
    } 


    //literally just creates the peghash 
    public static void setPegs(){ 
    PEGS = new HashMap<String,String>(); 

    PEGS.put("C","c"); 
    PEGS.put("Y","y"); 
    PEGS.put("R","r"); 
    PEGS.put("P","p"); 
    PEGS.put("O","o"); 
    PEGS.put("G","g"); 
    } 

    //turns the pegs ito something randomize can use 
public static ArrayList<String> makePegArray(){ 
    setPegs(); 

    pegStrings = new ArrayList<String>(); 

    Collection<String> pegValues = PEGS.values(); 
    Object[] pegObjects = pegValues.toArray(); 

     for (int i = 0; i < pegObjects.length; i++){ 
     pegStrings.add(pegObjects[i].toString()); 
     } 

    return pegStrings; 
    } 

    // sets Class Variable secretCode to a four letter combination 
    public static Code randomize(){ 
    secretCodeString = new String(); 

    Random rand = new Random(); 
    int randIndex = rand.nextInt(makePegArray().size()); 

    for (int i = 0; i < 4; i++){ 
     randIndex = rand.nextInt(makePegArray().size()); 
     secretCodeString = secretCodeString.concat(makePegArray().get(randIndex)); 
    } 

     Code secretCode = parse(secretCodeString); 
     return secretCode; 
    } 

    public static Code parse(String input) { 
    setPegs(); 
    makePegArray(); 

    String[] letters = input.split(""); 
    StringBuilder sb = new StringBuilder(); 

    for (String letter : letters) { 
     if (pegStrings.contains(letter)) { 
     sb.append(letter); 
     } else { 
     System.out.println(letter); 
     throw new RuntimeException(); 

     } 
    } 

    String pegListString = sb.toString(); 
    Code parsedCode = new Code(pegListString); 
    //System.out.println(parsedCode); 
    return parsedCode; 

    } 

    public int countExactMatches(Code guess){ 
    String guessString = guess.secretCodeString; 

    int exactMatches = 0; 

    String[] guessArray = guessString.split(""); 

    String[] winningCodeArray = (this.secretCodeString).split(""); 

    for(int i = 0; i < 4; i++){ 

     if(guessArray[i] == winningCodeArray[i]){ 
     exactMatches++; 
     } 
    } 
    return exactMatches; 
    } 

    public int countNearMatches(Code guess) { 

    String guessString= guess.secretCodeString; 

    HashMap<String,Integer> guessCount = new HashMap<String,Integer>(); 
    HashMap<String,Integer> secretCodeCount = new HashMap<String,Integer>(); 

    Set<String> codeKeys = guessCount.keySet(); 

    int matches = 0; 
    int keys = guessCount.keySet().size(); 


    String[] keyArray = new String[keys]; 



    for(int i = 0; i < guessString.length(); i++) { 
     //removes character from string 
     String codeCharacter = String.valueOf(guessString.charAt(i)); 
     String guessShort = guessString.replace(codeCharacter,""); 

     //counts instances of said character 
     int count = guessString.length() - guessShort.length(); 

     guessCount.put(codeCharacter, count); 
    } 

    for(int i = 0; i < secretCodeString.length(); i++) { 
     //removes character from string 
     String winningString = this.secretCodeString; 

     String winningCodeCharacter = String.valueOf(winningString.charAt(i)); 
     String winningCodeShort = guessString.replace(winningCodeCharacter,""); 

     //counts instances of said character 
     int count = winningString.length() - winningCodeShort.length(); 

     secretCodeCount.put(winningCodeCharacter, count); 
    } 

    for (int i = 0; i < keys; i++) { 
     codeKeys.toArray(keyArray); 
     String keyString = keyArray[i]; 

     if (secretCodeCount.containsKey(keyString)) { 
     matches += Math.min(secretCodeCount.get(keyString), guessCount.get(keyString)); 
     } 
    } 

    int nearMatches = matches - countExactMatches(guess); 

    return nearMatches; 
    } 
} 

Game.java

import java.util.Scanner; 

class Game { 

    protected static Code winningCode; 

    public static void main(String[] args){ 

    } 

    public Game(){ 
    winningCode = new Code(); 
    } 

    protected static Code getGuess() { 

    Scanner userInput = new Scanner(System.in); 

    int count = 0; 
    int maxTries = 5; 
    while(true){ 
     try { 
     String codeToParse = userInput.next(); 
     Code guess = Code.parse(codeToParse); 
     return guess; 

     } catch(RuntimeException notACode) { 
     System.out.println("That's not a valid peg. You have " + (maxTries - count) + " tries left."); 
     if (++count == maxTries) throw notACode; 
     } 
    } 


    } 

    protected static void displayMatches(Code guess){ 

    int nearMatches = winningCode.countNearMatches(guess); 
    int exactMatches = winningCode.countExactMatches(guess); 

    System.out.println("You have " + exactMatches + " exact matches and " + nearMatches + " near matches."); 
    } 

    protected static void play(){ 
    int turnCount = 0; 
    int maxTurns = 10; 

    System.out.println("Greetings. Pick your code of four from Y,O,G,P,C,R."); 

    while(true){ 
     Code guess = getGuess(); 
     displayMatches(guess); 

     if (guess == winningCode) { 
     System.out.print("You win!!"); 
     break; 
     } else if (++turnCount == maxTurns) { 
     System.out.print("You lose!!"); 
     break; 
     } 
    } 
    } 
} 
+4

为什么你声明一切为静态?坏。 http://stackoverflow.com/questions/2671496/java-when-to-use-static-methods – OldProgrammer

+0

我是一个新的程序员,所以我可能做错了。但是,我的许多方法弹出一个错误,说你不能从非静态的上下文中调用静态,反之亦然。我改变他们,因为我需要停止看到错误 –

+2

不,不,不,不。你这样做是因为Main()被声明为静态的。您需要在Main()中创建类(对象)的实例,然后通过该对象引用方法。在评论中阅读链接。 – OldProgrammer

回答

3

在每一个猜测,你叫Code.parseCode.parse创建一个新的Codenew Code(pegListString);)并且构造函数设置了secretCodeString,因为这是静态的,Code的所有实例共享相同的变量。您需要避免可变成员static

另一个提示是要么有一个方法返回一个值或mutate状态(其输入或其自身的实例,this),但避免两者都做。

+0

我明白你的意思,但我有第二个构造函数,它接受输入,并且应该将代码的String值设置为提供'this.secretCodeString = input'的参数。现在有没有随机/无参数构造函数是无效的? –

+0

我明白了,我错过了这一点,它仍然类似于我的想法,因为两个构造函数都改变了共享静态字段'secretCodeString'。 – weston

1

“为什么我的类变量在一个不相关的方法运行后自我重写?”

因为,实际上它并不无关系。将变量和方法声明为static所创建的“混乱”会导致代码不同部分之间出现不必要的耦合。

很难说这里正确的解决方案是什么,因为你的代码被重写弄得很困惑,很难辨别原始的“设计意图”。

我的建议是重新开始。您现在应该对需要哪些功能有更清楚的了解。你需要做的是重做对象设计,以便每个班级都有明确的目的。 (MainGame类是有意义的,但Code似乎是一个功能和状态混搭,没有一致的目的。)

相关问题