Created
July 31, 2020 01:09
-
-
Save arahansa/7834a0a648f8c4ff3dbe2f81cebbd0c3 to your computer and use it in GitHub Desktop.
코딩도장용 지뢰찾기
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.validation.constraints.Max; | |
import javax.validation.constraints.Min; | |
import javax.validation.constraints.NotEmpty; | |
import java.util.*; | |
import java.util.function.Function; | |
import java.util.stream.Collectors; | |
public class CodingDojangMineSweeper { | |
static class Block { | |
private static Block OUTOFGAME = new Block(-1, null); | |
private final int index; | |
private int count; | |
private final Game game; | |
private boolean mine; | |
public Block(int number, Game game) { | |
this.index = number; | |
this.game = game; | |
} | |
public int getIndex() { | |
return index; | |
} | |
public int getWidth() { | |
return this.game.getWidth(); | |
} | |
public Block getBlock(int index) { | |
if (this == Block.OUTOFGAME) return this; | |
return this.game.getBlock(index); | |
} | |
public void plusCount() { | |
this.count++; | |
} | |
public Block layMine() { | |
if (this == OUTOFGAME) throw new IllegalStateException("OUTOFGAME Block can't set mine."); | |
this.mine = true; | |
return this; | |
} | |
public boolean isInGameBlock() { | |
return this != OUTOFGAME; | |
} | |
@Override | |
public String toString() { | |
return String.valueOf(this.mine ? "*" : this.count); | |
} | |
public Set<Block> getAdjacentBlock(MovingStrategy[] strategies) { | |
if (this == OUTOFGAME) throw new IllegalStateException("OUTOFGAME Block can't getAdjacentBlock."); | |
Set<Block> l = new HashSet<>(); | |
for (MovingStrategy s : strategies) | |
l.add(s.apply(this)); | |
return l; | |
} | |
} | |
enum MovingStrategy { | |
UP(b -> b.getBlock(b.getIndex() - b.getWidth())), | |
DOWN(b -> b.getBlock(b.getIndex() + b.getWidth())), | |
LEFT(b -> { | |
if (!b.isInGameBlock()) return b; | |
int index = b.getIndex(); | |
if (index % b.getWidth() == 0) | |
return Block.OUTOFGAME; | |
return b.getBlock(index - 1); | |
}), | |
RIGHT(b -> { | |
if (!b.isInGameBlock()) return b; | |
int width = b.getWidth(); | |
int index = b.getIndex(); | |
if (index % width == (width - 1)) { | |
return Block.OUTOFGAME; | |
} | |
return b.getBlock(index + 1); | |
}), | |
UPLEFT(UP.strategy.andThen(LEFT.strategy)), | |
UPRIGHT(UP.strategy.andThen(RIGHT.strategy)), | |
DOWNLEFT(DOWN.strategy.andThen(LEFT.strategy)), | |
DOWNRIGHT(DOWN.strategy.andThen(RIGHT.strategy)); | |
private Function<Block, Block> strategy; | |
MovingStrategy(Function<Block, Block> strategy) { | |
this.strategy = strategy; | |
} | |
public Block apply(Block block) { | |
return this.strategy.apply(block); | |
} | |
static MovingStrategy[] getEasyStrategy() { | |
return new MovingStrategy[]{UP, DOWN, LEFT, RIGHT}; | |
} | |
} | |
static class Game { | |
private int width; | |
private int height; | |
private final List<Block> blocks; | |
public Game(GameOption gameOption) { | |
this.width = gameOption.getWidth(); | |
this.height = gameOption.getHeight(); | |
int size = width * height; | |
// set blocks | |
this.blocks = new ArrayList<>(size); | |
for (int i = 0; i < size; i++) { | |
this.blocks.add(i, new Block(i, this)); | |
} | |
// mines | |
Set<Integer> mines = gameOption.getMineNums(); | |
mines.stream() | |
.map(this::layMine) | |
.map(block -> block.getAdjacentBlock(MovingStrategy.values())) | |
.flatMap(Collection::stream) | |
.filter(Block::isInGameBlock) | |
.forEach(Block::plusCount); | |
// .flatMap(block -> Arrays.stream(MovingStrategy.values()).map(s-> s.apply(block))) | |
} | |
public String toString() { | |
String res = ""; | |
for (int i = 0; i < width * height; i++) { | |
res += getBlock(i).toString(); | |
if (i % getWidth() == (width - 1)) { | |
res += System.getProperty("line.separator"); | |
} | |
} | |
return res; | |
} | |
public void print() { | |
System.out.print(toString()); | |
System.out.println("======================"); | |
} | |
public int getWidth() { | |
return this.width; | |
} | |
Block getBlock(int index) { | |
if (index < 0 || index >= width * height) { | |
return Block.OUTOFGAME; | |
} | |
return this.blocks.get(index); | |
} | |
private Block layMine(int index) { | |
return getBlock(index).layMine(); | |
} | |
} | |
static class GameOption { | |
int width; | |
int height; | |
Set<Integer> mineNums; | |
public GameOption(int width, int height, Set<Integer> mine) { | |
this.width = width; | |
this.height = height; | |
this.mineNums = mine; | |
} | |
public GameOption(String input) { | |
String[] split = input.split("\n"); | |
String[] s = split[0].split(" "); | |
this.width = Integer.parseInt(s[1]); | |
this.height = Integer.parseInt(s[0]); | |
this.mineNums = new HashSet<>(); | |
List<String> strings = new ArrayList<>(Arrays.asList(split)); | |
strings.remove(0); | |
String collected = strings.stream().collect(Collectors.joining()); | |
for (int i = 0; i < collected.length(); i++) { | |
if (collected.charAt(i) == '*') { | |
mineNums.add(i); | |
} | |
} | |
} | |
public int getWidth() { | |
return width; | |
} | |
public int getHeight() { | |
return height; | |
} | |
public Set<Integer> getMineNums() { | |
return mineNums; | |
} | |
} | |
public static Set<Integer> getRandomNumbers(int max) { | |
Set<Integer> mine = new HashSet<>(); | |
int randomSize = (int) (max * 0.2); | |
while (mine.size() < randomSize) { | |
int i = (int) (Math.random() * (max - 1)); | |
mine.add(i); | |
} | |
return mine; | |
} | |
public static void main(String[] args) { | |
String input = """ | |
4 4 | |
*... | |
.... | |
.*.. | |
.... | |
"""; | |
new Game(new GameOption(input)).print(); | |
input = """ | |
3 5 | |
**... | |
..... | |
.*... | |
"""; | |
new Game(new GameOption(input)).print(); | |
System.out.println("25 칸 짜리"); | |
new Game(new GameOption(5, 5, getRandomNumbers(25))).print(); | |
System.out.println("49 칸 짜리"); | |
new Game(new GameOption(7, 7, getRandomNumbers(49))).print(); | |
System.out.println("100 칸 짜리"); | |
new Game(new GameOption(10, 10, getRandomNumbers(100))).print(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment