编写填字游戏Java ACM图形

时间:2014-03-24 13:56:49

标签: java crossword

问题是要求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并运行它。这是结果。

Crossword solution

你在上半场表现不错,但你错过了下半场的下注数据。

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

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);
        }
    }

}

1 个答案:

答案 0 :(得分:0)

我听从了自己的意见。我创建了填字游戏答案,编号填字游戏答案,最后绘制了填字游戏答案。

这是小程序结果:

Crossword answer

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

对于每个填字游戏,我都会跟踪它是否是一个字母,以及它是否是一个黑暗的空间。

在确定数字的位置时,我遵循了2条规则。

  1. 数字左边的单元格是空的或黑暗的,并且有三个或更多字母。

  2. 向下的数字位于单元格上方的单元格为空或黑暗,有三个或更多字母向下,并且没有跨数字。

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

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

    以下是代码:

    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();
            }
    
        }
    
    }