问题回顾
在简单版本的程序中,玩家只要猜中任意一格,计数器就+1,而没有考虑是否这一格是否被猜中过。
使用ArrayList
游戏的完全版
需要改变的类
- DotCom类要增加名称变量来区别不同的网站;
- 游戏的类(DotComBust):要创建三个DotCom并指定他们的名称、将DotCom放在方阵上(GameHelper实现)、每次猜测检查3个DotCom、击沉3个DotCom后才结束游戏、脱离main();
- 辅助性类;
DotCom类
import java.util.*;
public class DotCom {
private ArrayList<String> locationCells; //保存位置的ArrayList
private String name;
public void setLocationCells(ArrayList<String> loc) { //更新位置的方法
locationCells = loc;
}
public void setName(String n) {
name = n;
}
public String checkYourself(String userInput) {
String result = "miss";
int index = locationCells.indexOf(userInput);//把玩家输入坐标的下标赋给index,没找到返回-1
if (index >= 0) {
locationCells.remove(index);
if (locationCells.isEmpty()) {
result = "kill";
System.out.println("Oh! You sunk " + name);
} else {
result = "hit";
}
}
return result;
}
}
DotComBust类的伪码
声明GameHelper实例helper;
声明一个ArrayList实例dotComList来放置三个网站;
声明一个int类型的变量NumOfGuess来记录玩家猜测次数,初始化为0;
声明setUpGame()方法:创建并初始化三个DotCom实例,并分别取名,放置到方阵上,给玩家一个简短的介绍;
声明startPlaying()方法:重复询问并获取玩家猜测,调用checkUserGuess()方法,直到所有DotCom被移除;
声明checkUserGuess()方法:遍历所有DotCom实例,并让他们调用自身checkYourself()方法;
声明finishGame()方法:基于猜测次数输出玩家成绩;
void setUpGame()
创建三个DotCom实例;
分别命名;
把它们加入dotComList;
遍历dotComList:
调用placeDotCom()方法(helper实例中),初始化三个网站位置;
用DotCom的setLocationCells()设定位置;
void start playing()
while (dotComList中还有元素):
调用helper中的getUserInput()方法获取玩家猜测;
调用checkUserGuess()方法验证猜测;
void checkUserGuess()
numOfGuess++;
声明并设置局部变量result为"miss";
遍历dotComList:
调用checkYourself()方法来验证玩家猜测;
在需要的情况下改变result为"hit"或"kill";
if (result == "kill")
从dotComList移除该实例;
显示result值;
void finishGame()
显示gameover
if 猜测数少:
祝贺的信息
else:
继续努力的信息
编写测试方法的代码
最重要的方法是checkUserGuess():初始化一个网站,假定网站位置和用户猜测来测试方法。
其次是初始化的setUpGame():可以打印出设置的信息来查看(在DotCom类中增加方法)。
剩余两个方法实现比较简单,个人认为不需要专门的测试。
下面是自己写的测试代码:
import java.util.*;
public class MethodTestDrive {
public static void main(String[] args) {
System.out.println("Testing setUpGame()...");
DotComBust game1 = new DotComBust();
game1.setUpGames();
for (DotCom x : game1.dotComsList) {
System.out.println(x.getName() + " postion: " + x.getLocationCells());
}
System.out.println("Testing chekUserGuess()...");
DotComBust game2 = new DotComBust();
DotCom d1 = new DotCom();
d1.setName("163.com");
ArrayList<String> pos = new ArrayList<String>();
pos.add("C5");
pos.add("C6");
pos.add("C7");
d1.setLocationCells(pos);
game2.dotComsList.add(d1);
System.out.println("Result should be \"miss\" \"hit\" \"hit\" \"kill\" ");
game2.checkUserGuess("C4");
game2.checkUserGuess("C5");
game2.checkUserGuess("C6");
game2.checkUserGuess("C7");
System.out.println("Number of guesses: " + game2.numOfGuesses);
}
}
类的实现
import java.util.*;
public class DotComBust {
private GameHelper helper = new GameHelper();
private ArrayList<DotCom> dotComsList = new ArrayList<DotCom>();
private int numOfGuesses = 0;
private void setUpGames() {
DotCom one = new DotCom();
one.setName("Pets.com");
DotCom two = new DotCom();
two.setName("qq.com");
DotCom three = new DotCom();
three.setName("163.com");
dotComsList.add(one);
dotComsList.add(two);
dotComsList.add(three);
System.out.println("共有三个网站,尝试用最少的次数打掉他们!");
for (DotCom dotComToSet : dotComsList) {
ArrayList<String> newLocation = helper.placeDotCom(3);
dotComToSet.setLocationCells(newLocation);
}
}
private void startPlaying() {
while (!dotComsList.isEmpty()) {
String userGuess = helper.getUserInput("Enter a guess");
checkUserGuess(userGuess);
}
finishGame();
}
private void checkUserGuess(String userGuess) {
numOfGuesses++;
String result = "miss";
for (DotCom dotComToTest : dotComsList) {
result = dotComToTest.checkYourself(userGuess);
if (result.equals("hit")) {
break;
}
if (result.equals("kill")) {
dotComsList.remove(dotComToTest);
break;
}
}
System.out.println(result);
}
private void finishGame() {
System.out.println("你打掉了所有网站!");
if (numOfGuesses <= 18) {
System.out.println("你只用了" + numOfGuesses + "次!" );
} else {
System.out.println("你用了" + numOfGuesses + "次!次数太多了" );
}
}
public static void main(String[] args) {
DotComBust game = new DotComBust();
game.setUpGames();
game.startPlaying();
}
}
- 程序中除了main都是private,很好地保护了数据。
GameHelper
import java.io.*;
import java.util.*;
public class GameHelper {
private static final String alphabet = "abcdefg";
private int gridLength = 7;
private int gridSize = 49;
private int [] grid = new int[gridSize];
private int comCount = 0;
public String getUserInput(String prompt) {
String inputLine = null;
System.out.print(prompt + " ");
try {
BufferedReader is = new BufferedReader(
new InputStreamReader(System.in));
inputLine = is.readLine();
if (inputLine.length() == 0 ) return null;
} catch (IOException e) {
System.out.println("IOException: " + e);
}
return inputLine.toLowerCase();
}
public ArrayList<String> placeDotCom(int comSize) { // line 19
ArrayList<String> alphaCells = new ArrayList<String>();
String [] alphacoords = new String [comSize]; // holds 'f6' type coords
String temp = null; // temporary String for concat
int [] coords = new int[comSize]; // current candidate coords
int attempts = 0; // current attempts counter
boolean success = false; // flag = found a good location ?
int location = 0; // current starting location
comCount++; // nth dot com to place
int incr = 1; // set horizontal increment
if ((comCount % 2) == 1) { // if odd dot com (place vertically)
incr = gridLength; // set vertical increment
}
while ( !success & attempts++ < 200 ) { // main search loop (32)
location = (int) (Math.random() * gridSize); // get random starting point
//System.out.print(" try " + location);
int x = 0; // nth position in dotcom to place
success = true; // assume success
while (success && x < comSize) { // look for adjacent unused spots
if (grid[location] == 0) { // if not already used
coords[x++] = location; // save location
location += incr; // try 'next' adjacent
if (location >= gridSize){ // out of bounds - 'bottom'
success = false; // failure
}
if (x>0 & (location % gridLength == 0)) { // out of bounds - right edge
success = false; // failure
}
} else { // found already used location
// System.out.print(" used " + location);
success = false; // failure
}
}
} // end while
int x = 0; // turn good location into alpha coords
int row = 0;
int column = 0;
// System.out.println("\n");
while (x < comSize) {
grid[coords[x]] = 1; // mark master grid pts. as 'used'
row = (int) (coords[x] / gridLength); // get row value
column = coords[x] % gridLength; // get numeric column value
temp = String.valueOf(alphabet.charAt(column)); // convert to alpha
alphaCells.add(temp.concat(Integer.toString(row)));
x++;
// System.out.print(" coord "+x+" = " + alphaCells.get(x-1));
}
// System.out.println("\n");
return alphaCells;
}
}