我正在为我的编程课工作一个石头剪刀游戏,教授希望我们使用hash 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
,并且模式将继续。
所以初学者模式是从空地图开始,退伍军人是加载以前保存的地图。但是,我遇到了一些问题:
put
模式和时间进入哈希映射之后,当我尝试遍历它并查看它存储在地图中的模式时,我看到所有模式都是相同的,并且不会假设即将发生。该模式假设为:R -> R P - > R P S
(如果用户分别投掷摇滚,纸张,剪刀),但现在它只显示R P S -> R P S -> R P S
。这可以在计算机中的getSize()中看到。NullPointerException
。如果我可以解决上一个问题,但我不知道为什么会发生这个问题,问题可能会得到解决。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;
}
}
答案 0 :(得分: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];
以确保您不会反复使用对该数组的相同引用,因为更改基础对象也会更改所有引用。
只是为了澄清我的意思是参考: Is Java “pass-by-reference” or “pass-by-value”?