cs106a编程方法学作业解答(4)(Hangman)

我发现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;

}

 

posted on 2014-10-25 01:14  livingisgood  阅读(876)  评论(0编辑  收藏  举报