0

我正在为我的编程课制作一个石头剪刀布游戏,教授希望我们使用 ahash map来存储用户的模式,并且times模式发生在hash map.

因此,我创建了一个Pattern包含值数组的类,并在Computer该类中将其存储在hash map. 我打算让程序工作的方式是程序将首先generate a move基于patterns. hash map如果地图是空的,那么它只会生成一个随机移动。然后在用户移动之后,他的移动将被放入一个数组中以形成一个新的模式,并将该模式​​保存到哈希映射中。如果模式已经在地图内,那么它出现的次数将会增加。

预测的移动是通过将用户的最后三个移动与地图中的模式进行比较来做出的,并查看用户接下来可能会抛出哪个移动。因此,如果用户最后 4 步是:R P S R那么程序将采用P S R然后添加R P S并查看这些模式是否在地图中。如果是,它将查看哪一个最有可能发生。然后,如果用户R接下来播放,数组将被更新P S R R并继续模式。

所以初学者模式是从一​​张空地图开始,而老手模式是加载以前保存的地图。但是,我遇到了一些问题:

  1. 在我put将 Pattern 和 times 放入哈希映射之后,当我尝试遍历它并查看它存储在映射中的模式时,我发现所有模式都是相同的,而且这不会发生。该模式假设为:(R -> R P - > R P S如果用户分别扔石头、纸、剪刀)但现在它只显示R P S -> R P S -> R P S. 这可以在 Computer 中的 getSize() 中看到。
  2. NullPointerException我在第四步之后遇到了一个。如果我能解决前面的问题,这个问题可能会解决,但我不知道为什么会这样。
  3. 当我尝试从文件中读取地图时收到警告,所以我只是想知道警告是否可能会干扰程序。
    Unchecked cast from Object to HashMap<Pattern, Integer>

非常感谢我的程序中出现问题的一些帮助或指示。

计算机:

import java.io.*;
import java.util.*;

public class Computer {
    /**
     * The hashmap that will holds the pattern and how many times it occured.
     */
    private HashMap<Pattern, Integer> map;

    /**
     * Constructor
     */
    public Computer() {
        map = new HashMap<Pattern, Integer>();
    }

    /**
     * Storing the pattern to the map.
     * 
     * @param p
     *            The pattern that will be saved to the map.
     */
    public void storePattern(Pattern p) {
        Integer time = map.get(p);
        // If time is null then the Pattern is not yet in the hashmap
        if (time == null) {
            map.put(p, 1);
        } else {
            map.put(p, time + 1);
        }
    }

    /**
     * Generating the computer's next move.
     * 
     * @return The move that the computer will make.
     */
    public char generateMove(Pattern user) {
        int r = 0, p = 0, s = 0;
        char returns = 'a';
        if (!map.isEmpty()) {
            char[] userPatts = user.getPattern();
            char[] patts = userPatts.clone();
            patts[patts.length - 1] = 'R';
            Pattern testPatt = new Pattern(patts);
            if (map.containsKey(testPatt))
                r = map.get(patts);
            patts[patts.length - 1] = 'P';
            testPatt = new Pattern(patts);
            if (map.containsKey(testPatt))
                p = map.get(patts);
            patts[patts.length - 1] = 'S';
            testPatt = new Pattern(patts);
            if (map.containsKey(testPatt))
                s = map.get(patts);
            if ((s - r) > 0 && (s - p) > 0)
                return 'R';
            if ((p - s) > 0 && (p - r) > 0)
                return 'S';
            if ((r - s) > 0 && (r - p) > 0)
                return 'P';
            if (s == r && r != 0)
                return 'P';
            if (s == p && s != 0)
                return 'R';
            if (r == p && p != 0)
                return 'S';
        }
        // Throwing a random move
        int max = (int) (Math.random() * 3) + 1;
        if (max == 1)
            returns = 'P';
        else if (max == 2)
            returns = 'S';
        else if (max == 3)
            returns = 'R';
        return returns;
    }

    /**
     * Loading the hashmap from a file.
     */
    public void loadMap() {
        File f = new File("HashMap.dat");
        if (f.exists()) {
            try {
                ObjectInputStream in = new ObjectInputStream(
                        new FileInputStream(f));
                map = (HashMap<Pattern, Integer>) in.readObject();
                System.out.println("Successfully loaded.");
                in.close();
            } catch (IOException e) {
                System.out.println("Error processing file.");
            } catch (ClassNotFoundException e) {
                System.out.println("Could not find class.");
            }
        }
    }

    /**
     * Saving the hashmap to a file.
     */
    public void saveMap() {
        File f = new File("HashMap.dat");
        try {
            ObjectOutputStream out = new ObjectOutputStream(
                    new FileOutputStream(f));
            out.writeObject(map);
            System.out.println("Map saved.");
            out.close();
        } catch (IOException e) {
            System.out.println("Error processing file.");
        }
    }

    public void getSize() {
        System.out.println("Map size: " + map.size());
        for (Map.Entry<Pattern, Integer> entry : map.entrySet()) {
            Pattern b = entry.getKey();
            char[] a = b.getPattern();
            for (int i = 0; i < a.length; i++) {// Why a.length allows i to go
                                                // from 0 to 3 if a.length == 4?
                System.out.print(a[i] + " ");// Why are all the patterns the
                                                // same?
            }
            System.out.println();
        }
    }
}

图案:

import java.io.Serializable;
import java.util.Arrays;

public class Pattern implements Serializable {
    /**
     * Array that holds the patterns.
     */
    private char[] pattern;

    /**
     * Constructor.
     */
    public Pattern(char[] patt) {
        pattern = patt;
    }

    /**
     * Getting the pattern array.
     * 
     * @return The pattern array.
     */
    public char[] getPattern() {
        return pattern;
    }

    /**
     * Override the hashCode().
     */
    @Override
    public int hashCode() {
        return Arrays.hashCode(pattern);
    }

    /**
     * Override the equals()
     */
    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof Pattern)) {
            return false;
        }
        Pattern s = (Pattern) o;
        return Arrays.equals(s.getPattern(), pattern);
    }
}

主要的:

import java.util.Scanner;

/**
 * This program allows the user to play Rock Paper Scisors with a computer with
 * a twist: The computer will try to predict the user's next move and try to
 * beat it.
 * 
 * @author:
 */
public class RockPaperScisors {
    public static void main(String[] args) {
        char computer = 'S';
        int playerScore = 0, compScore = 0, tie = 0, full = 0;
        char[] patt = new char[4];
        Computer comp = new Computer();
        boolean stop = false;
        System.out
                .println("Do you want to play veteran or beginner mode?\n1. Veteran\n2. Beginner");
        int mode = input(2, 1);
        if (mode == 1)
            comp.loadMap();
        comp.getSize();
        while (!stop) {
            // Generate computer's move.
            computer = comp.generateMove(new Pattern(patt));
            System.out.println("Enter R P S. Enter Q to quit.");
            char a = input();
            if (a == 'Q') {
                stop = true;
                break;
            }
            System.out.println("You threw: " + a);
            if (full <= (patt.length - 1)) {
                patt[full] = a;
                full++;
            } else {
                for (int i = 0; i <= patt.length - 2; i++) {
                    patt[i] = patt[i + 1];
                }
                patt[patt.length - 1] = a;
            }
            for (int i = 0; i <= patt.length - 1; i++) {
                System.out.print(patt[i]);
            }
            System.out.println();
            // Store the new pattern
            comp.storePattern(new Pattern(patt));
            System.out.println("Computer plays: " + computer);
            // Check for win or tie
            if (a == computer) {
                System.out.println("Tie.");
                tie++;
            } else {
                if (a == 'R' && computer == 'P') {
                    System.out.println("Computer wins.");
                    compScore++;
                }
                if (a == 'R' && computer == 'S') {
                    System.out.println("Player wins.");
                    playerScore++;
                }
                if (a == 'P' && computer == 'S') {
                    System.out.println("Computer wins.");
                    compScore++;
                }
                if (a == 'P' && computer == 'R') {
                    System.out.println("Player wins.");
                    playerScore++;
                }
                if (a == 'S' && computer == 'R') {
                    System.out.println("Computer wins.");
                    compScore++;
                }
                if (a == 'S' && computer == 'P') {
                    System.out.println("Player wins.");
                    playerScore++;
                }
            }
            // Saving the map
            comp.saveMap();
            comp.getSize();
            System.out.println("Your score: " + playerScore + "\tTie: " + tie
                    + "\tComputer score: " + compScore);
        }
        System.out.println("Thank you for playing.");
    }

    public static int input(int upper, int lower) {
        Scanner in = new Scanner(System.in);
        boolean valid = false;
        int validInt = 0;
        while (!valid) {
            if (in.hasNextInt()) {
                validInt = in.nextInt();
                if (validInt <= upper && validInt >= lower) {
                    valid = true;
                } else {
                    System.out.print("Invalid- Retry: ");
                }
            } else {
                in.next();
                System.out.print("Invalid input- Retry: ");
            }
        }
        return validInt;
    }

    public static char input() {
        Scanner in = new Scanner(System.in);
        boolean valid = false;
        char validChar = 'a';
        while (!valid) {
            if (in.hasNext()) {
                validChar = in.next().charAt(0);
                if (validChar == 'R' || validChar == 'P' || validChar == 'S'
                        || validChar == 'Q') {
                    valid = true;
                } else {
                    System.out.print("Invalid- Retry: ");
                }
            } else {
                in.next();
                System.out.print("Invalid input- Retry: ");
            }
        }
        return validChar;
    }
}
4

1 回答 1

1

如果 a.length == 4,为什么 a.length 允许 i 从 0 变为 3?

在计算机科学中,您从0开始计数,因此长度为 4

int array = new array[4];
array[0];
array[1];
array[2];
array[3];

为什么所有的图案都一样?

在你的主要内部while (!stop),你应该尽量patt = new char[4];确保你不要一遍又一遍地使用对该数组的相同引用,因为更改基础对象也会更改所有引用。

只是为了澄清我所说的引用的意思: Java是“按引用传递”还是“按值传递”?

于 2015-03-05T08:25:34.047 回答