2009年11月24日

ああ、やっとなんとかまともなロジックになった気がする

昨日悩んでいたロジック。修正してみたらうまくいったんじゃないコレ?
 import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class WallMazer extends JFrame implements MouseListener, KeyListener {

    boolean[] walls = new boolean[48];
    String output = "";
    JTextField input;
    JPanel canvas;

    /**
     * @param args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new WallMazer();
            }

        });
    }

    public WallMazer() {

        walls[0 + 24] = true;
        walls[12 + 24] = true;
        walls[11 + 24] = true;
        walls[23 + 24] = true;

        canvas = new JPanel() {
            @Override
            public void paintComponent(Graphics g) {
                reflesh((Graphics2D) g);
            }
        };

        addMouseListener(this);
        add(canvas);

        input = new JTextField();
        input.addKeyListener(this);
        add(input, BorderLayout.SOUTH);

        setSize(480, 480);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private void reflesh(Graphics2D g) {
        g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        g.translate(40, 40);
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                g.setColor(Color.WHITE);
                g.drawRect(x * 40, y * 40, 32, 32);
                g.setColor(Color.GREEN);
                if (calcWall(y * 4 + x, 4)) {
                    g.drawLine(x * 40, y * 40, x * 40, y * 40 + 32);
                }
                if (calcWall(y * 4 + x, 5)) {
                    g.drawLine(x * 40, y * 40, x * 40 + 32, y * 40);
                }
                if (calcWall(y * 4 + x, 6)) {
                    g.drawLine(x * 40 + 32, y * 40, x * 40 + 32, y * 40 + 32);
                }
                if (calcWall(y * 4 + x, 7)) {
                    g.drawLine(x * 40, y * 40 + 32, x * 40 + 32, y * 40 + 32);
                }
                g.setColor(Color.BLACK);
                if (calcWall(y * 4 + x, 0)) {
                    g.drawLine(x * 40, y * 40, x * 40, y * 40 + 32);
                }
                if (calcWall(y * 4 + x, 1)) {
                    g.drawLine(x * 40, y * 40, x * 40 + 32, y * 40);
                }
                if (calcWall(y * 4 + x, 2)) {
                    g.drawLine(x * 40 + 32, y * 40, x * 40 + 32, y * 40 + 32);
                }
                if (calcWall(y * 4 + x, 3)) {
                    g.drawLine(x * 40, y * 40 + 32, x * 40 + 32, y * 40 + 32);
                }

            }
        }
        g.drawString(output, 200, 80);
    }

    boolean calcWall(int pos, int quota) {
        int windex = getWallIndex(pos, quota);
        if (windex < 0) {
            return quota < 4;
        } else {
            return walls[windex];
        }
    }

    boolean fitWall(int pos, int wall) {
        for (int i = 0; i < 4; i++) {
            if (calcWall(pos, i)) {
                if ((wall & (1 << i)) == 0) {
                    return false;
                } else {
                    continue;
                }
            }
            if (calcWall(pos, i + 4) && ((wall & (1 << i)) != 0)) {
                return false;
            }
        }
        return true;
    }

    void setWall(int pos, int wall) {
        for (int i = 0; i < 4; i++) {
            int offset = 0;
            if (((1 << i) & wall) == 0) {
                offset = 24;
            }
            int windex = getWallIndex(pos, i + offset / 6);
            if (windex >= 0) {
                walls[windex] = true;
            }
        }
    }

    int getWallIndex(int pos, int aquota) {
        int offset = (aquota / 4) * 24;
        int quota = aquota % 4;
        if (quota % 2 == 0) {
            if (pos % 4 == quota * 3 / 2) {
                return -1;
            }
            return pos - (pos / 4) + (quota / 2) - 1 + offset;
        } else {
            int pos2 = pos + quota * 2 + 6;
            if (pos2 < 12 || 24 <= pos2) {
                return -1;
            }
            return pos2 + offset;
        }
    }

    void parse(String str) {
        // set wall mode
        String[] tokens = str.split(" ");
        int floor = -1;
        int wall = -1;
        if (tokens.length < 2) {
            output = "no token match";
            canvas.repaint();
            input.setText("");
            return;
        }
        try {
            floor = Integer.parseInt(tokens[0]);
            wall = Integer.parseInt(tokens[1]);
        } catch (Exception e) {
            output = "number parse error";
            canvas.repaint();
            input.setText("");
            return;
        }
        if (floor < 0 || 16 < floor) {
            output = "0 <= floor <= 16";
            canvas.repaint();
            input.setText("");
            return;
        }
        if (wall < 0 || 16 < wall) {
            output = "0 <= wall <= 16";
            canvas.repaint();
            input.setText("");
            return;
        }
        boolean fit = fitWall(floor, wall);
        output = "fitTest=" + fit;
        if (fit) {
            setWall(floor, wall);
        }
        canvas.repaint();
        input.setText("");
    }

    public void mouseClicked(MouseEvent e) {
        int x = (e.getX() / 40) - 1;
        int y = ((e.getY() - getInsets().top) / 40) - 1;
        if (x < 0 || 3 < x) {
            return;
        }
        if (y < 0 || 3 < y) {
            return;
        }
        for (int i = 0; i < 16; i++) {
            String out = "0000" + Integer.toString(i, 2);
            if (fitWall(y * 4 + x, i)) {
                System.out.println("+" + out.substring(out.length() - 4));
            } else {
                System.out.println("-" + out.substring(out.length() - 4));
            }
        }
        System.out.println("----");

    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            parse(input.getText());
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            input.setText(input.getText() + ((int) (Math.random() * 16)));
        }
    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }
}
posted by LoyalTouch at 14:54| Comment(0) | TrackBack(0) | 5つの宝島 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.seesaa.jp/tb/133786194

この記事へのトラックバック