![見出し画像](https://assets.st-note.com/production/uploads/images/71921254/rectangle_large_type_2_50ea5f2d54bacedc754f0cbd9d3c2192.png?width=800)
【Processing & Java】マインスイーパー💣 をライブコーディングしてみた。
マインスイーパー x Java
前回
環境
Java1.8
Processing
Maven
Intellij
作った画面
![](https://assets.st-note.com/img/1644493819892-FDOArYHQo3.png?width=800)
ソースコード
盤面の定義
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);
}
}
}
この記事が気に入ったらサポートをしてみませんか?