CS106A Assignment4: Hangman

来源:互联网 发布:js switch case语句 编辑:程序博客网 时间:2024/05/29 11:58

做完了Breakout之后,感觉做Hangman的速度明显快了不少。估计也是和用了三个类,加上stub implement有关系吧!这个程序我并没有使用太多的Decomposition,原因是整个游戏比较直观,虽然步骤多,但是一个接一个的步骤写代码基本不会错。其实写代码的风格还可以简洁一些的,这一点还要多加练习。下面贴上代码:

以下是第一部分(Hangman.java)的代码:

import acm.program.*;import acm.util.*;public class Hangman extends ConsoleProgram {private static final int GUESS_NUM = 8;public void init() {canvas = new HangmanCanvas();add(canvas);}    public void run() {/**========================================     * @author Andrew Garcia     * 1、从列表中随机选择一个单词     * 2、让用户输入猜测的字母并进行跟踪     * 3、根据游戏规则进行游戏     * ========================================*/    setFont("serif-20");    canvas.reset();    //以随机方式选取一个单词       int x = rgen.nextInt(0,hl.getWordCount());    ans = hl.getWord(x);                //提示用户单词的形式,并进行猜测    hintStr = "";    for (int i=0;i<ans.length();i++){    hintStr += "-";    }    println("The word now looks like this: "+hintStr);        //猜多个字母    for (int i=0;i<GUESS_NUM;i++){    if ((GUESS_NUM-i)!=1){println("You have " + (GUESS_NUM-i) + " guesses left.");} else println("You have only one guess left.");    //检查并反馈猜测的结果    /********************************************************/        while (true){    guess();    canvas.displayWord(check);  //输出图像的单词形式    if (done){    println("That guess is correct!");        check(); //检查是否已经猜到完整的单词        if (!flag){        println("The word now looks like: "+check);        if ((GUESS_NUM-i)!=1){        println("You have " + (GUESS_NUM-i) + " guesses left.");        } else println("You have only one guess left.");        } else break;        } else {        println("There are no "+ guess +"'s in the word.");            println("The word now looks like: "+check);            canvas.noteIncorrectGuess(guess.charAt(0));        }    if (done==false) break;    }        /***********************************************************/        if (flag) break;    }    /*=========End: For Block=====================================================*/    if (!flag) {    println("You lose.");    println("The word is "+ans);    }    }        private void check() {if (check.equals(ans)){println("You guessed the word: "+ans);println("You win!");flag = true;}}private void guess(){    //追踪猜测的字符    guess = readLine("Your guess is: ");    while (guess.length()!= 1 || Character.isLetter(guess.charAt(0))!= true){    println("Illegal guess!");    guess = readLine("Your guess is: ");    }    guess = guess.toUpperCase();    //检查并反馈猜测的结果    check = hintStr;    done = false;    char ch = guess.charAt(0);    for (int j=0;j<ans.length();j++){    if (ch == ans.charAt(j)){    check = hintStr.substring(0,j) + ch;    if (j != ans.length()-1){    check = check + hintStr.substring(j+1);    }    hintStr = check;    done = true;    }    }    }        private HangmanLexicon hl = new HangmanLexicon();    private RandomGenerator rgen = new RandomGenerator();    private HangmanCanvas canvas;    private String ans;    private String guess;    private String hintStr;    private boolean done;    private String check;    private boolean flag;}

以下是第二部分(HangmanCanvas.java)的代码:
import acm.graphics.*;public class HangmanCanvas extends GCanvas {/** Resets the display so that only the scaffold appears */public void reset() {removeAll();x_beam = getWidth()/2 - BEAM_LENGTH;y_beam = 5;GLine beam = new GLine(x_beam,y_beam,getWidth()/2,y_beam);GLine scaffold = new GLine(x_beam,y_beam,x_beam,y_beam+SCAFFOLD_HEIGHT);GLine rope = new GLine(getWidth()/2,y_beam,getWidth()/2,y_beam+ROPE_LENGTH);add(beam);add(scaffold);add(rope);}/** * 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) {if (label == null){label = new GLabel(word);label.setFont("serif-24");add(label,x_beam,y_beam+SCAFFOLD_HEIGHT+label.getAscent()+5);} else {remove(label);label = new GLabel(word);label.setFont("serif-24");add(label,x_beam,y_beam+SCAFFOLD_HEIGHT+label.getAscent()+5);}}/** * 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) {str += letter;int x1 = getWidth()/2 - UPPER_ARM_LENGTH;int x2 = getWidth()/2;int x3 = getWidth()/2 + UPPER_ARM_LENGTH;int x4 = getWidth()/2 - HIP_WIDTH;int x5 = getWidth()/2 + HIP_WIDTH;int x6 = x4 - FOOT_LENGTH;int x7 = x5 + FOOT_LENGTH;int y1 = y_beam+ROPE_LENGTH+2*HEAD_RADIUS+ARM_OFFSET_FROM_HEAD;int y2 = y1 + LOWER_ARM_LENGTH;int y3 = y_beam+ROPE_LENGTH+2*HEAD_RADIUS+BODY_LENGTH;int y4 = y3 + LEG_LENGTH;switch (str.length()){case 1:GOval head = new GOval(2*HEAD_RADIUS,2*HEAD_RADIUS);add(head,getWidth()/2-HEAD_RADIUS,y_beam+ROPE_LENGTH);break;case 2:GLine body = new GLine(getWidth()/2,y_beam+ROPE_LENGTH+2*HEAD_RADIUS,getWidth()/2,y_beam+ROPE_LENGTH+2*HEAD_RADIUS+BODY_LENGTH);add(body);break;case 3:GLine leftArm1 = new GLine(x1,y1,x2,y1);GLine leftArm2 = new GLine(x1,y1,x1,y2);add(leftArm1);add(leftArm2);break;case 4:GLine rightArm1 = new GLine(x2,y1,x3,y1);GLine rightArm2 = new GLine(x3,y1,x3,y2);add(rightArm1);add(rightArm2);break;case 5:GLine leftLeg1 = new GLine(x4,y3,x2,y3); GLine leftLeg2 = new GLine(x4,y3,x4,y4);add(leftLeg1);add(leftLeg2);break;case 6:GLine rightLeg1 = new GLine(x5,y3,x2,y3);GLine rightLeg2 = new GLine(x5,y3,x5,y4);add(rightLeg1);add(rightLeg2);break;case 7:GLine leftFoot = new GLine(x4,y4,x6,y4);add(leftFoot);break;case 8:GLine rightFoot = new GLine(x5,y4,x7,y4);add(rightFoot);break;default:GLabel error = new GLabel("ERROR!");add(error,(getWidth()-error.getWidth())/2, (getHeight()-error.getAscent())/2);}GLabel err = new GLabel(str);add(err,x_beam,y_beam+SCAFFOLD_HEIGHT+label.getAscent()+err.getAscent()+ 10);}/* Constants for the simple version of the picture (in pixels) */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;/*Instance variables*/private int x_beam;private int y_beam;private GLabel label;private String str = "";}

以下是第三部分(HangmanLexicon.java)的代码:
import acm.util.*;import java.io.*;import java.util.*;public class HangmanLexicon {/**Stores the wordlist.*/ArrayList<String> strList = new ArrayList<String>();BufferedReader rd = OpenFile();/** Returns the number of words in the lexicon. */public int getWordCount() {BufferedReader rd = OpenFile();try{while (true){String line = rd.readLine();if (line == null) break;strList.add(line);}rd.close();} catch (IOException ex){throw new ErrorException(ex);}return strList.size(); }/** Returns the word at the specified index. */public String getWord(int index) {return strList.get(index);}/**Retunes the BufferedReader pointing to HangmanLexicon.txt.*/private BufferedReader OpenFile(){BufferedReader rd = null;try{String name = "HangmanLexicon.txt";rd = new BufferedReader(new FileReader(name));} catch (IOException ex){throw new ErrorException(ex);}return rd;}}



另外上传一张游戏的效果图做为结尾:


原创粉丝点击