1

问题要求 acm 图形程序读取这样的 txt 文件:

      R      
     FUN     
    SALES    
   RECEIPT   
  MERE@FARM  
 DOVE@@@RAIL 
MORE@@@@@DRAW
 HARD@@@TIED 
  LION@SAND  
   EVENING   
    EVADE    
     ARE     
      D      

并做一个填字游戏,字母上有空白方块,“@”上有黑色方块,空白处什么也没有。该问题还要求“如果方块位于跨越、向下或两者的单词的开头,则方块应包含一个在拼图中按顺序分配的数字。”

我有方形绘图工作,但我坚持正确绘制数字。我检测零空间和黑色方块的方式有问题。有人可以告诉我我做错了什么吗?

这是代码:

import acm.program.*;
import java.io.*;
import java.util.*;
import acm.graphics.*;
import java.awt.*;

public class Crossword extends GraphicsProgram {
public void run() {
    String fileName = "crosswordfile.txt";
    makeCrosswordPuzzle(fileName);
}
private static final int sqCon = 15; // constant for square x and y dimensions
private int y = 0;
public void makeCrosswordPuzzle(String fileName) {
    BufferedReader rd;
    int y = 0; // y value for the square being added during that loop. increments by sqCon after every line
    int wordNumber = 1; // variable for numbers added to certain boxes. increments every time the program adds a number
    try {
        rd = new BufferedReader(new FileReader(fileName));
        String line = rd.readLine(); //reads one line of the text document at a time and makes it a string

        while (line != null) {
            int x = 0;


            for (int i = 0; i < line.length(); i++) {

                char lineChar = line.charAt(i);// the character being examined for each loop

                GRect whiteSq = new GRect(sqCon,sqCon); //GRect for blank squares

                GRect blackSq = new GRect(sqCon,sqCon);//GRect for black squares
                blackSq.setFilled(true);
                blackSq.setFillColor(Color.BLACK);

                if (lineChar == '@'){
                    add (blackSq,x,y);

                }
                if (Character.isLetter(lineChar)) {

                    add (whiteSq, x, y);

                    // if the element above or to the left of the current focus is null or blackSq, place the number and then increment wordNumber
                    GObject above = getElementAt(x+sqCon/2,y-sqCon/2);
                    GObject left = getElementAt(x-sqCon/2, y+sqCon/2);

                    GLabel wordNumberLabel = new GLabel(Integer.toString(wordNumber));
                    if (above == null || left == null || above == blackSq || left == blackSq) {

                        add(wordNumberLabel,x,y+sqCon);
                        wordNumber++;
                    }
                }
                x += sqCon;
            }
            line = rd.readLine();
            y += sqCon;
        }
        rd.close();
    }
    catch (IOException e) {
        throw new ErrorException(e);
    }
}

}

编辑添加:

我将您的代码复制到我的 Eclipse 并运行它。这是结果。

填字游戏

你在上半部分做得很好,但你错过了下半部分的倒数。

这是相同的代码,重新格式化以便更容易阅读。

import java.awt.Color;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import acm.graphics.GLabel;
import acm.graphics.GObject;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
import acm.util.ErrorException;

public class Crossword extends GraphicsProgram {
    private static final long   serialVersionUID    = -7971434624427958742L;

    public void run() {
//      String fileName = "crosswordfile.txt";
        String fileName = "C:/Eclipse/eclipse-4.2-work/com.ggl.testing/crosswordfile.txt";
        makeCrosswordPuzzle(fileName);
    }

    private static final int    sqCon   = 15;   // constant for square x and y
                                                // dimensions
    private int                 y       = 0;

    public void makeCrosswordPuzzle(String fileName) {
        BufferedReader rd;
        int y = 0; // y value for the square being added during that loop.
                    // increments by sqCon after every line
        int wordNumber = 1; // variable for numbers added to certain boxes.
                            // increments every time the program adds a number
        try {
            rd = new BufferedReader(new FileReader(fileName));
            String line = rd.readLine(); // reads one line of the text document
                                            // at a time and makes it a string

            while (line != null) {
                int x = 0;

                for (int i = 0; i < line.length(); i++) {

                    char lineChar = line.charAt(i);// the character being
                                                    // examined for each loop

                    GRect whiteSq = new GRect(sqCon, sqCon); // GRect for blank
                                                                // squares

                    GRect blackSq = new GRect(sqCon, sqCon);// GRect for black
                                                            // squares
                    blackSq.setFilled(true);
                    blackSq.setFillColor(Color.BLACK);

                    if (lineChar == '@') {
                        add(blackSq, x, y);

                    }
                    if (Character.isLetter(lineChar)) {

                        add(whiteSq, x, y);

                        // if the element above or to the left of the current
                        // focus is null or blackSq, place the number and then
                        // increment wordNumber
                        GObject above = getElementAt(x + sqCon / 2, y - sqCon
                                / 2);
                        GObject left = getElementAt(x - sqCon / 2, y + sqCon
                                / 2);

                        GLabel wordNumberLabel = new GLabel(
                                Integer.toString(wordNumber));
                        if (above == null || left == null || above == blackSq
                                || left == blackSq) {

                            add(wordNumberLabel, x, y + sqCon);
                            wordNumber++;
                        }
                    }
                    x += sqCon;
                }
                line = rd.readLine();
                y += sqCon;
            }
            rd.close();
        } catch (IOException e) {
            throw new ErrorException(e);
        }
    }

}
4

1 回答 1

0

我听从了我自己评论的建议。我创建了填字游戏的答案,给填字游戏的答案编号,最后画出了填字游戏的答案。

这是小程序结果:

填字游戏答案

我保留了一个填字游戏单元格的列表。这样,我可以通过一行上的字符数和输入文本文件的行数来确定拼图的长度和宽度。我不必对尺寸进行硬编码。

对于每个填字游戏单元,我都记录了它是否是一个字母,以及它是否是一个黑暗的空间。

在确定将数字放在哪里时,我遵循了 2 条规则。

  1. 横线数字放置在单元格左侧的单元格为空或暗的位置,并且有三个或三个以上的字母。

  2. 向下数字放置在单元格上方的单元格为空或暗处,向下有三个或更多字母,并且没有交叉数字。

您可以在代码中看到我必须进行一些调试打印才能使填字游戏线索编号正确。我将这个过程分解为许多方法,以使每种方法都尽可能简单。

最后,我从列表中的信息中得出了填字游戏的答案。

这是代码:

import java.awt.Color;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import acm.graphics.GLabel;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
import acm.util.ErrorException;

public class Crossword extends GraphicsProgram {
    private static final boolean DEBUG = false;

    private static final long serialVersionUID = -7971434624427958742L;

    private List<CrosswordCell> crosswordCellList;

    @Override
    public void run() {
        this.crosswordCellList = new ArrayList<CrosswordCell>();
//      String fileName = "crosswordfile.txt";
        String fileName = "C:/Eclipse/eclipse-4.2-work/" + 
                "com.ggl.testing/crosswordfile.txt";
        try {
            readCrosswordAnswer(fileName);
            if (DEBUG) printCrosswordAnswer();
            numberCrosswordCells();
            if (DEBUG) printCrosswordAnswer();
            drawCrosswordAnswer();
        } catch (FileNotFoundException e) {
            throw new ErrorException(e);
        } catch (IOException e) {
            throw new ErrorException(e);
        }
    }

    private void readCrosswordAnswer(String fileName) 
            throws FileNotFoundException, IOException {
        BufferedReader reader = 
                new BufferedReader(new FileReader(fileName));
        String line = "";
        int row = 0;
        while ((line = reader.readLine()) != null) {
            for (int column = 0; column < line.length(); column++) {
                CrosswordCell cell = new CrosswordCell(column, row);
                char lineChar = line.charAt(column);
                if (lineChar == '@') {
                    cell.setDarkCell(true);
                } else if (Character.isLetter(lineChar)) {
                    cell.setLetter(true);
                }
                crosswordCellList.add(cell);
            }
            row++;
        }
        reader.close();
    }

    public void printCrosswordAnswer() {
        for (CrosswordCell cell : crosswordCellList) {
            System.out.println(cell);
        }
    }

    private void numberCrosswordCells() {
        int clueNumber = 1;
        for (CrosswordCell cell : crosswordCellList) {
            if (cell.isLetter()) {
                clueNumber = testCell(cell, clueNumber);
            }
        }
    }

    private int testCell(CrosswordCell cell, int clueNumber) {
        Point p = cell.getLocation();
        CrosswordCell leftCell = getLeftCell(p.x, p.y);
        List<CrosswordCell> acrossList = getRightCells(p.x, p.y);
        if (DEBUG) {
            System.out.print(p);
            System.out.println(", " + leftCell + " " + 
                    acrossList.size());
        }
        if ((leftCell == null) && (acrossList.size() >= 3)) {
            cell.setClueNumber(clueNumber++);
        } else {
            CrosswordCell aboveCell = getAboveCell(p.x, p.y);
            List<CrosswordCell> downList = getBelowCells(p.x, p.y);
            if (DEBUG) {
                System.out.print(p);
                System.out.println(", " + aboveCell + " " + 
                        downList.size());
            }
            if ((aboveCell == null) && (downList.size() >= 3)) {
                cell.setClueNumber(clueNumber++);
            }
        }
        return clueNumber;
    }

    private CrosswordCell getAboveCell(int x, int y) {
        int yy = y - 1;
        return getCell(x, yy);
    }

    private CrosswordCell getLeftCell(int x, int y) {
        int xx = x - 1;
        return getCell(xx, y);
    }

    private List<CrosswordCell> getBelowCells(int x, int y) {
        List<CrosswordCell> list = new ArrayList<CrosswordCell>();
        for (int i = y; i < (y + 3); i++) {
            CrosswordCell cell = getCell(x, i);
            if (cell != null) {
                list.add(cell);
            }
        }
        return list;
    }

    private List<CrosswordCell> getRightCells(int x, int y) {
        List<CrosswordCell> list = new ArrayList<CrosswordCell>();
        for (int i = x; i < (x + 3); i++) {
            CrosswordCell cell = getCell(i, y);
            if (cell != null) {
                list.add(cell);
            }
        }
        return list;
    }

    private CrosswordCell getCell(int x, int y) {
        for (CrosswordCell cell : crosswordCellList) {      
            Point p = cell.getLocation();
            if ((p.x == x) && (p.y == y)) {
                if (cell.isDarkCell()) {
                    return null;
                } else if (cell.isLetter()){
                    return cell;
                } else {
                    return null;
                }
            }
        }
        return null;
    }

    private void drawCrosswordAnswer() {
        int sqCon = 32;
        for (CrosswordCell cell : crosswordCellList) {
            Point p = cell.getLocation();
            if (cell.isDarkCell()) {
                drawDarkCell(p, sqCon);
            } else if (cell.isLetter()) {
                drawLetterCell(cell, p, sqCon);
            }
        }
    }

    private void drawDarkCell(Point p, int sqCon) {
        GRect blackSq = new GRect(sqCon, sqCon);
        blackSq.setFilled(true);
        blackSq.setFillColor(Color.BLACK);
        add(blackSq, p.x * sqCon, p.y * sqCon);
    }

    private void drawLetterCell(CrosswordCell cell, Point p, int sqCon) {
        GRect whiteSq = new GRect(sqCon, sqCon);
        add(whiteSq, p.x * sqCon, p.y * sqCon);
        if (cell.getClueNumber() > 0) {
            String label = Integer.toString(cell.getClueNumber());
            GLabel wordNumberLabel = new GLabel(label);
            add(wordNumberLabel, p.x * sqCon + 2, p.y * sqCon + 14);
        }
    }

    class CrosswordCell {
        private boolean darkCell;
        private boolean isLetter;

        private int clueNumber;

        private Point location;

        public CrosswordCell(int x, int y) {
            this.location = new Point(x, y);
            this.clueNumber = 0;
            this.darkCell = false;
            this.isLetter = false;
        }

        public boolean isDarkCell() {
            return darkCell;
        }

        public void setDarkCell(boolean darkCell) {
            this.darkCell = darkCell;
        }

        public boolean isLetter() {
            return isLetter;
        }

        public void setLetter(boolean isLetter) {
            this.isLetter = isLetter;
        }

        public int getClueNumber() {
            return clueNumber;
        }

        public void setClueNumber(int clueNumber) {
            this.clueNumber = clueNumber;
        }

        public Point getLocation() {
            return location;
        }

        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append("CrosswordCell [location=");
            builder.append(location);
            builder.append(", clueNumber=");
            builder.append(clueNumber);
            builder.append(", darkCell=");
            builder.append(darkCell);
            builder.append(", isLetter=");
            builder.append(isLetter);
            builder.append("]");
            return builder.toString();
        }

    }

}
于 2014-03-24T17:44:24.273 回答