見出し画像

【Processing & Java】マインスイーパー💣 をライブコーディングしてみた。

マインスイーパー x Java


前回


環境

  • Java1.8

  • Processing

  • Maven

  • Intellij

作った画面


ソースコード

盤面の定義

public final class Board {
    static { init(); }

    private static PanelStatus[][] map;

    public static void init() {

        Board.map = new PanelStatus[Config.TROUT][Config.TROUT];
        for (int i = 0; i < Config.TROUT; i++) {
            for (int j = 0; j < Config.TROUT; j++) {
                Board.map[i][j] = PanelStatus.None;
            }
        }
    }

    public static boolean isInside (final int x, final int y) {
        return x >= 0 && x < Board.map.length && y >= 0 && y < Board.map[x].length;
    }

    public static boolean setBom(final int x, final int y) {
        if (!Board.isInside(x, y)) return false;
        Board.map[x][y] = PanelStatus.Bomb;
        return true;
    }

    public static void setRandBombs(int n) {
        final Random rand = new Random();
        for (int i = 0; i < n; i++) {
            Board.setBom(rand.nextInt(Config.TROUT), rand.nextInt(Config.TROUT));
        }
    }

    public static PanelStatus getValue(final int x, final int y) {
        if (!Board.isInside(x, y)) throw new OutSideException(x, y);
        return map[x][y];
    }

    public static void open(final int x, final int y) {
        if (!Board.isInside(x, y)) throw new OutSideException(x, y);
        Board.map[x][y] = PanelStatus.Opened;
    }
}

爆弾に接していない盤面の探索

 public List<Counter> eatPanels(final int x, final int y) {
        if (Board.getValue(x, y).equals(PanelStatus.Opened) || !Board.isInside(x, y)) return Collections.emptyList();
        if (Board.getValue(x, y).equals(PanelStatus.Bomb)) return Collections.singletonList(new Counter(x, y, PanelStatus.Bomb));

        Board.open(x, y);
        final Counter counter = new Counter(x, y, PanelStatus.None);
        for (int i = -1; i < 2; i++) {
            for (int j = -1; j < 2; j++) {
                if ((i == 0 && j == 0) || !Board.isInside(x+i, y+j)) continue;
                if (Board.getValue(x+i, y+j).equals(PanelStatus.Bomb)) counter.countAround++;
            }
        }

        final List<Counter> counters = new ArrayList<>(Collections.singletonList(counter));
        if (counter.countAround == 0) {
            for (int i = -1; i < 2; i++) {
                for (int j = -1; j < 2; j++ ) {
                    if (i == 0 && j == 0) continue;
                    if (Board.isInside(x+i, y+j)) counters.addAll(eatPanels(x+i, y+j));
                }
            }
        }

        return counters;
    }

Processingとロジックの結合部分

public class Processing extends PApplet {
    private final SearchUseCase useCase = new UseCase();
    private boolean isEnd = false;

    @Override
    public void settings() {
        size(HW,HW);
    }

    @Override
    public void setup() {
        frameRate(30);
        initPanels();
    }

    @Override
    public void draw() {
        if (this.isEnd) {
            delay(1000);
            this.initPanels();
            this.isEnd = false;
        }
    }

    @Override
    public void mousePressed(){
        final int x = mouseX *TROUT/HW;
        final int y = mouseY *TROUT/HW;
        final List<Crawler.Counter> counters = this.useCase.getReversiblePoints(x, y);
        counters.forEach(c -> openPanel(c.getX(), c.getY(), c.getStatus(), c.getCountAround()));
    }

    private void openPanel(final int x, final int y, final PanelStatus s, final int n)  {
        final float ratio = (float)HW / (float)TROUT;
        final float fontSize = 11;

        fill(255, 255, 255);
        rect(ratio*x + 1, ratio*y+1, ratio - 1, ratio - 1);


        if (s.equals(PanelStatus.Bomb)) {
            fill(0);
            ellipse(ratio*x + ratio/2, ratio*y + ratio/2, (float) (ratio*0.6), (float) (ratio*0.6));
            this.isEnd = true;
        } else if (n > 0) {
            fill(0);
            textSize(fontSize);
            text(String.valueOf(n), ratio*x+(ratio/2) - fontSize/2, ratio*y+(ratio/2) + fontSize/2);
        }
    }

    private void initPanels() {
        this.useCase.initBoard((int) ((float)TROUT*(float)TROUT*(float)0.1));
        background(200, 200, 200);
        final int ratio = HW /TROUT;
        for (int i = 0; i <TROUT; i ++) {
            line(0, i * (ratio),HW, i * (ratio));
            line(i * (ratio), 0, i * (ratio),HW);
        }
    }
}


この記事が気に入ったらサポートをしてみませんか?