我发现assignment4有两种版本,除了上篇文章写的Yahtzee游戏,还有一种要求写一个叫做hangman的猜单词游戏的版本。大概是同一课程不同年份的内容有些出入的原因。这个作业我也做了。代码如下:
首先是Hangman.java的
/* * File: Hangman.java * ------------------ * This program will eventually play the Hangman game from * Assignment #4. */ import acm.graphics.*; import acm.program.*; import acm.util.*; import java.awt.*; public class Hangman extends ConsoleProgram { public void run() { fordisplaying.reset(); String secretword=getsecretword(forguessing);//生成待猜的单词 int length=secretword.length(); char[] display=new char[length];//初始化用来指示被猜中情况的字符数组 for(int i=0;i<length;i++){ display[i]='-'; } String fordisplay=new String(display);//此字符串用来显示被猜中的字母 println("Welcome to Hangman!"); int guesscount=8; while(guesscount>0&&!fordisplay.equals(secretword)){ println("The word now looks like this : "+fordisplay); println("You have "+guesscount+" guess left"); String guess=readLine("You guess :"); String lowerguess=guess.toLowerCase();//得到玩家输入字符的小写版本,用于对比是否猜中 String upperguess=guess.toUpperCase();//得到玩家输入字符的大写版本,目的同上 char guesschar=guess.charAt(0);//得到玩家输入的字符,注意前面得到的是字符串 char lowerguesschar=Character.toLowerCase(guesschar);//得到小写版本 char upperguesschar=Character.toUpperCase(guesschar);//得到大写版本 if(guess.length()>1||Character.isLetter(guesschar)!=true){//输入了不止一个字符,或者输入的字符非英文字母,则提示错误输入 println("Illegal guess,only one letter is accept"); continue; } if(secretword.indexOf(lowerguess)==-1&&secretword.indexOf(upperguess)==-1){//如果用大写和小写版本都无法在secretword里面检测到,说明并未猜中 println("There are no "+guess+" in the word."); guesscount--; fordisplaying.noteIncorrectGuess(guesschar, guesscount); } else{ println("That guess is correct."); for(int i=0;i<length;i++){//用小写和大写字符逐个对比secretword中的字符,发生相符的情况则用该字符替换显示用的‘-’ if(lowerguesschar==secretword.charAt(i)||upperguesschar==secretword.charAt(i)){ display[i]=secretword.charAt(i); } } String tem=new String(display); fordisplay=tem; fordisplaying.displayWord(fordisplay); } } if(guesscount==0){ println("You lose."); } if(fordisplay.equals(secretword)){ println("You win!"); } } public void init() { add(fordisplaying); } private HangmanCanvas fordisplaying=new HangmanCanvas(); private HangmanLexicon forguessing= new HangmanLexicon(); private String getsecretword(HangmanLexicon a){ RandomGenerator rgen = RandomGenerator.getInstance(); int n=a.getWordCount(); int m=rgen.nextInt(0,n-1); String secretword=a.getWord(m); return secretword; } }
然后是HangmanLexicon.java
* File: HangmanLexicon.java * ------------------------- * This file contains a stub implementation of the HangmanLexicon * class that you will reimplement for Part III of the assignment. */ import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import acm.util.*; public class HangmanLexicon { // This is the HangmanLexicon constructor public HangmanLexicon() { try { rd = new BufferedReader(new FileReader("HangmanLexicon.txt")); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } while(true){ String line=null; try { line = rd.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(line==null) break; strlist.add(line); } } // rest of HangmanLexicon class... /** Returns the number of words in the lexicon. */ public int getWordCount() { return strlist.size(); } /** Returns the word at the specified index. */ public String getWord(int index) { return strlist.get(index); } private BufferedReader rd; private ArrayList<String> strlist=new ArrayList<String>(); }
最后是画Hangman用的HangmanCanvas.java
* File: HangmanCanvas.java * ------------------------ * This file keeps track of the Hangman display. */ import acm.graphics.*; public class HangmanCanvas extends GCanvas { /** Resets the display so that only the scaffold appears */ public void reset() { removeAll(); GLine beam=new GLine(getWidth()/2-144,18,getWidth()/2,18); GLine rope=new GLine(getWidth()/2,18,getWidth()/2,36); GLine scaffold=new GLine(getWidth()/2-144,18,getWidth()/2-144,378); add(scaffold); add(rope); add(beam); } private void addhead(){ GOval head=new GOval(getWidth()/2-HEAD_RADIUS,36,2*HEAD_RADIUS,2*HEAD_RADIUS); add(head); } private void addbody(){ GLine body=new GLine(getWidth()/2,36+2*HEAD_RADIUS,getWidth()/2,36+2*HEAD_RADIUS+BODY_LENGTH); add(body); } private void addleftarm(){ GLine leftarm1=new GLine(getWidth()/2,36+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD,getWidth()/2-UPPER_ARM_LENGTH,36+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD); GLine leftarm2=new GLine(getWidth()/2-UPPER_ARM_LENGTH,36+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD,getWidth()/2-UPPER_ARM_LENGTH,36+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD+LOWER_ARM_LENGTH); add(leftarm1); add(leftarm2); } private void addrightarm(){ GLine rightarm1=new GLine(getWidth()/2,36+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD,getWidth()/2+UPPER_ARM_LENGTH,36+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD); GLine rightarm2=new GLine(getWidth()/2+UPPER_ARM_LENGTH,36+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD,getWidth()/2+UPPER_ARM_LENGTH,36+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD+LOWER_ARM_LENGTH); add(rightarm1); add(rightarm2); } private void addleftleg(){ GLine leftleg1=new GLine(getWidth()/2,36+2*HEAD_RADIUS+BODY_LENGTH,getWidth()/2-HIP_WIDTH,36+2*HEAD_RADIUS+BODY_LENGTH); GLine leftleg2=new GLine(getWidth()/2-HIP_WIDTH,36+2*HEAD_RADIUS+BODY_LENGTH,getWidth()/2-HIP_WIDTH,36+2*HEAD_RADIUS+BODY_LENGTH+LEG_LENGTH); add(leftleg1); add(leftleg2); } private void addrightleg(){ GLine rightleg1=new GLine(getWidth()/2,36+2*HEAD_RADIUS+BODY_LENGTH,getWidth()/2+HIP_WIDTH,36+2*HEAD_RADIUS+BODY_LENGTH); GLine rightleg2=new GLine(getWidth()/2+HIP_WIDTH,36+2*HEAD_RADIUS+BODY_LENGTH,getWidth()/2+HIP_WIDTH,36+2*HEAD_RADIUS+BODY_LENGTH+LEG_LENGTH); add(rightleg1); add(rightleg2); } private void addleftfoot(){ GLine leftfoot=new GLine(getWidth()/2-HIP_WIDTH,36+2*HEAD_RADIUS+BODY_LENGTH+LEG_LENGTH,getWidth()/2-HIP_WIDTH-FOOT_LENGTH,36+2*HEAD_RADIUS+BODY_LENGTH+LEG_LENGTH); add(leftfoot); } private void addrightfoot(){ GLine rightfoot=new GLine(getWidth()/2+HIP_WIDTH,36+2*HEAD_RADIUS+BODY_LENGTH+LEG_LENGTH,getWidth()/2+HIP_WIDTH+FOOT_LENGTH,36+2*HEAD_RADIUS+BODY_LENGTH+LEG_LENGTH); add(rightfoot); } /** * Updates the word on the screen to correspond to the current * state of the game. The argument string shows what letters have * been guessed so far; unguessed letters are indicated by hyphens. */ public void displayWord(String word) { current.setLabel(word); add(current,getWidth()/2-144,getHeight()-40); } /** * Updates the display to correspond to an incorrect guess by the * user. Calling this method causes the next body part to appear * on the scaffold and adds the letter to the list of incorrect * guesses that appears at the bottom of the window. */ public void noteIncorrectGuess(char letter,int guesscount) { if(guesscount==7){ addhead(); } if(guesscount==6){ addbody(); } if(guesscount==5){ addleftarm(); } if(guesscount==4){ addrightarm(); } if(guesscount==3){ addleftleg(); } if(guesscount==2){ addrightleg(); } if(guesscount==1){ addleftfoot(); } if(guesscount==0){ addrightfoot(); } incorrectguess.setLabel(incorrectguess.getLabel()+letter); add(incorrectguess,getWidth()/2-144,getHeight()-18); } /* Constants for the simple version of the picture (in pixels) */ private GLabel current=new GLabel(""); private GLabel incorrectguess=new GLabel(""); private static final int SCAFFOLD_HEIGHT = 360; private static final int BEAM_LENGTH = 144; private static final int ROPE_LENGTH = 18; private static final int HEAD_RADIUS = 36; private static final int BODY_LENGTH = 144; private static final int ARM_OFFSET_FROM_HEAD = 28; private static final int UPPER_ARM_LENGTH = 72; private static final int LOWER_ARM_LENGTH = 44; private static final int HIP_WIDTH = 36; private static final int LEG_LENGTH = 108; private static final int FOOT_LENGTH = 28; }