use of core.mino.Mino in project solution-finder by knewjade.
the class SetupEntryPoint method run.
@Override
public void run() throws FinderException {
output("# Setup Field");
// Setup init field
Field initField = settings.getInitField();
Verify.field(initField);
// Setup need filled field
Field needFilledField = settings.getNeedFilledField();
Verify.needFilledField(needFilledField);
// Setup not filled field
Field notFilledField = settings.getNotFilledField();
// Setup max height
int maxHeight = settings.getMaxHeight();
Verify.maxClearLineUnder10(maxHeight);
// Setup reserved blocks
BlockField reservedBlocks = settings.getReservedBlock();
if (settings.isReserved()) {
Verify.reservedBlocks(reservedBlocks);
for (int y = maxHeight - 1; 0 <= y; y--) {
StringBuilder builder = new StringBuilder();
for (int x = 0; x < 10; x++) {
if (reservedBlocks.getBlock(x, y) != null)
builder.append(reservedBlocks.getBlock(x, y).getName());
else if (!initField.isEmpty(x, y))
builder.append('X');
else if (!needFilledField.isEmpty(x, y))
builder.append('*');
else if (!notFilledField.isEmpty(x, y))
builder.append('_');
else
builder.append('.');
}
output(builder.toString());
}
} else {
for (int y = maxHeight - 1; 0 <= y; y--) {
StringBuilder builder = new StringBuilder();
for (int x = 0; x < 10; x++) {
if (!initField.isEmpty(x, y))
builder.append('X');
else if (!needFilledField.isEmpty(x, y))
builder.append('*');
else if (!notFilledField.isEmpty(x, y))
builder.append('_');
else
builder.append('.');
}
output(builder.toString());
}
}
// Setup min depth
// 最低でも必要なミノ数
int minDepth = Verify.minDepth(needFilledField);
output();
// ========================================
// Output user-defined
DropType dropType = settings.getDropType();
output("# Initialize / User-defined");
output("Max height: " + maxHeight);
output("Drop: " + dropType.name().toLowerCase());
output("Searching patterns:");
// Setup patterns
List<String> patterns = settings.getPatterns();
PatternGenerator generator = Verify.patterns(patterns, minDepth);
// Output patterns
for (String pattern : patterns) output(" " + pattern);
// Setup output file
MyFile base = new MyFile(settings.getOutputBaseFilePath());
base.mkdirs();
base.verify();
output();
// ========================================
// Setup core
output("# Initialize / System");
int core = Runtime.getRuntime().availableProcessors();
// Output system-defined
output("Version = " + FinderConstant.VERSION);
output("Available processors = " + core);
output("Need Pieces = " + minDepth);
output();
// ========================================
output("# Search");
output(" -> Stopwatch start");
Stopwatch stopwatch = Stopwatch.createStartedStopwatch();
// Initialize
MinoFactory minoFactory = new MinoFactory();
MinoShifter minoShifter = new MinoShifter();
ColorConverter colorConverter = new ColorConverter();
SizedBit sizedBit = decideSizedBitSolutionWidth(maxHeight);
TaskResultHelper taskResultHelper = new BasicMinoPackingHelper();
SolutionFilter solutionFilter = new ForPathSolutionFilter(generator, maxHeight);
ThreadLocal<BuildUpStream> buildUpStreamThreadLocal = createBuildUpStreamThreadLocal(dropType, maxHeight);
OneFumenParser fumenParser = new OneFumenParser(minoFactory, colorConverter);
// ミノリストの作成
long deleteKeyMask = getDeleteKeyMask(notFilledField, maxHeight);
SeparableMinos separableMinos = SeparableMinos.createSeparableMinos(minoFactory, minoShifter, sizedBit, deleteKeyMask);
// 絶対に置かないブロック
List<InOutPairField> inOutPairFields = InOutPairField.createInOutPairFields(sizedBit, notFilledField);
// 絶対に置く必要があるブロック
ArrayList<BasicSolutions> basicSolutions = new ArrayList<>();
List<ColumnField> needFillFields = InOutPairField.createInnerFields(sizedBit, needFilledField);
{
Field freeze = needFilledField.freeze(sizedBit.getHeight());
for (ColumnField innerField : needFillFields) {
// 最小限の部分だけを抽出する
Field freeze1 = freeze.freeze(sizedBit.getHeight());
for (int y = 0; y < sizedBit.getHeight(); y++) {
int width = sizedBit.getWidth();
for (int x = 0; x < width; x++) freeze1.removeBlock(x, y);
for (int x = width + 3; x < 10; x++) freeze1.removeBlock(x, y);
}
OnDemandBasicSolutions solutions = new OnDemandBasicSolutions(separableMinos, sizedBit, innerField.getBoard(0), freeze1);
basicSolutions.add(solutions);
freeze.slideLeft(sizedBit.getWidth());
}
}
// 探索
SetupPackSearcher searcher = new SetupPackSearcher(inOutPairFields, basicSolutions, sizedBit, solutionFilter, taskResultHelper, needFillFields);
List<Result> results = getResults(initField, sizedBit, buildUpStreamThreadLocal, searcher);
output(" Found solution = " + results.size());
stopwatch.stop();
output(" -> Stopwatch stop : " + stopwatch.toMessage(TimeUnit.MILLISECONDS));
output();
// ========================================
output("# Output file");
HTMLBuilder<FieldHTMLColumn> htmlBuilder = new HTMLBuilder<>("Setup result");
results.parallelStream().forEach(result -> {
List<MinoOperationWithKey> operationWithKeys = result.getMemento().getSeparableMinoStream(sizedBit.getWidth()).map(SeparableMino::toMinoOperationWithKey).collect(Collectors.toList());
Field allField = initField.freeze(maxHeight);
Operations operations = OperationTransform.parseToOperations(allField, operationWithKeys, sizedBit.getHeight());
List<? extends Operation> operationList = operations.getOperations();
for (Operation operation : operationList) {
Mino mino = minoFactory.create(operation.getPiece(), operation.getRotate());
int x = operation.getX();
int y = operation.getY();
allField.put(mino, x, y);
}
// 譜面の作成
String encode = fumenParser.parse(operationWithKeys, initField, maxHeight);
String name = operationWithKeys.stream().map(OperationWithKey::getPiece).map(Piece::getName).collect(Collectors.joining());
String link = String.format("<a href='http://fumen.zui.jp/?v115@%s' target='_blank'>%s</a>", encode, name);
String line = String.format("<div>%s</div>", link);
htmlBuilder.addColumn(new FieldHTMLColumn(allField, maxHeight), line);
});
ArrayList<FieldHTMLColumn> columns = new ArrayList<>(htmlBuilder.getRegisteredColumns());
columns.sort(Comparator.comparing(FieldHTMLColumn::getTitle).reversed());
try (BufferedWriter bufferedWriter = base.newBufferedWriter()) {
for (String line : htmlBuilder.toList(columns, true)) {
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedWriter.flush();
} catch (IOException e) {
throw new FinderExecuteException(e);
}
output();
// ========================================
output("# Finalize");
output("done");
}
use of core.mino.Mino in project solution-finder by knewjade.
the class SetupSettingParser method loadTetfu.
private CommandLineWrapper loadTetfu(String data, CommandLineParser parser, Options options, CommandLineWrapper wrapper, SetupSettings settings) throws FinderParseException {
// テト譜面のエンコード
List<TetfuPage> decoded = encodeTetfu(data);
// 指定されたページを抽出
int page = wrapper.getIntegerOption("page").orElse(1);
TetfuPage tetfuPage = extractTetfuPage(decoded, page);
// コメントの抽出
String comment = tetfuPage.getComment();
List<String> splitComment = Arrays.stream(comment.split(" ")).map(String::trim).filter(s -> !s.isEmpty()).collect(Collectors.toList());
// コマンド引数を配列に変換
String[] commentArgs = new String[splitComment.size()];
splitComment.toArray(commentArgs);
// オプションとして読み込む
try {
CommandLine commandLineTetfu = parseToCommandLine(options, parser, commentArgs);
CommandLineWrapper newWrapper = new NormalCommandLineWrapper(commandLineTetfu);
wrapper = new PriorityCommandLineWrapper(Arrays.asList(wrapper, newWrapper));
} catch (FinderParseException ignore) {
}
// 固定ピースの指定があるか
// Optional<Boolean> reservedOption = wrapper.getBoolOption("reserved");
// reservedOption.ifPresent(settings::setReserved);
// マージン色の指定があるか
Optional<String> fillColorOption = wrapper.getStringOption("fill");
if (fillColorOption.isPresent()) {
settings.setFillColorType(fillColorOption.get());
}
// マージン色の指定があるか
Optional<String> marginColorOption = wrapper.getStringOption("margin");
if (marginColorOption.isPresent()) {
settings.setMarginColorType(marginColorOption.get());
}
// フィールドを設定
ColoredField coloredField = tetfuPage.getField();
if (tetfuPage.isPutMino()) {
ColorType colorType = tetfuPage.getColorType();
Rotate rotate = tetfuPage.getRotate();
int x = tetfuPage.getX();
int y = tetfuPage.getY();
ColorConverter colorConverter = new ColorConverter();
Mino mino = new Mino(colorConverter.parseToBlock(colorType), rotate);
coloredField.putMino(mino, x, y);
}
// 最大削除ラインの設定
Optional<Integer> maxHeightOption = wrapper.getIntegerOption("line");
int maxHeight = maxHeightOption.orElse(coloredField.getUsingHeight());
if (settings.isReserved()) {
Field initField = FieldFactory.createField(maxHeight);
Field needFilledField = FieldFactory.createField(maxHeight);
Field notFilledField = FieldFactory.createField(maxHeight);
ColorType marginColorType = settings.getMarginColorType();
ColorType fillColorType = settings.getFillColorType();
for (int y = 0; y < maxHeight; y++) {
for (int x = 0; x < 10; x++) {
ColorType colorType = coloredField.getColorType(x, y);
if (colorType.equals(marginColorType)) {
coloredField.setColorType(ColorType.Empty, x, y);
} else if (colorType.equals(fillColorType)) {
coloredField.setColorType(ColorType.Empty, x, y);
needFilledField.setBlock(x, y);
} else {
switch(colorType) {
case Gray:
initField.setBlock(x, y);
notFilledField.setBlock(x, y);
coloredField.setColorType(ColorType.Empty, x, y);
break;
case Empty:
notFilledField.setBlock(x, y);
break;
default:
break;
}
}
}
}
settings.setFieldWithReserved(initField, needFilledField, notFilledField, coloredField, maxHeight);
} else {
Field initField = FieldFactory.createField(maxHeight);
Field needFilledField = FieldFactory.createField(maxHeight);
Field notFilledField = FieldFactory.createField(maxHeight);
ColorType marginColorType = settings.getMarginColorType();
ColorType fillColorType = settings.getFillColorType();
for (int y = 0; y < maxHeight; y++) {
for (int x = 0; x < 10; x++) {
ColorType colorType = coloredField.getColorType(x, y);
if (colorType.equals(marginColorType)) {
// skip
} else if (colorType.equals(fillColorType)) {
needFilledField.setBlock(x, y);
} else {
switch(colorType) {
case Empty:
notFilledField.setBlock(x, y);
break;
case Gray:
default:
initField.setBlock(x, y);
notFilledField.setBlock(x, y);
break;
}
}
}
}
settings.setField(initField, needFilledField, notFilledField, maxHeight);
}
return wrapper;
}
use of core.mino.Mino in project solution-finder by knewjade.
the class PathCSVCaseTest method none1.
@Test
void none1() throws Exception {
// フォーマットをCSV
/*
comment: 4 -p I,*p6
X_________
XXXXX_____
XXXXX_____
XXXXX_____
*/
String tetfu = "v115@9gA8IeE8EeE8EeE8OeAgWQA0no2ANI98AwN88AjPEN?B";
int height = 4;
ConfigFileHelper.createFieldFile(FieldFactory.createField(height), height);
ConfigFileHelper.createPatternFile("*p2");
String command = String.format("path -t %s -f csv -k none", tetfu);
Log log = RunnerHelper.runnerCatchingLog(() -> EntryPointMain.main(command.split(" ")));
assertThat(log.getOutput()).contains("I,*p6").contains(Messages.clearLine(4)).contains(Messages.uniqueCount(186)).contains(Messages.minimalCount(142)).contains(Messages.useHold());
assertThat(log.getReturnCode()).isEqualTo(0);
Field field = FieldFactory.createField("" + "X_________" + "XXXXX_____" + "XXXXX_____" + "XXXXX_____");
// unique
PathCSV uniqueCSV = OutputFileHelper.loadPathUniqueNoneCSV();
assertThat(uniqueCSV.operations().stream().map(operations -> {
Field freeze = field.freeze(height);
for (Operation operation : operations.getOperations()) {
freeze.put(new Mino(operation.getPiece(), operation.getRotate()), operation.getX(), operation.getY());
freeze.clearLine();
}
return freeze;
})).hasSize(186).allMatch(Field::isPerfect);
// minimal
PathCSV minimalCSV = OutputFileHelper.loadPathMinimalNoneCSV();
assertThat(minimalCSV.operations().stream().map(operations -> {
Field freeze = field.freeze(height);
for (Operation operation : operations.getOperations()) {
freeze.put(new Mino(operation.getPiece(), operation.getRotate()), operation.getX(), operation.getY());
freeze.clearLine();
}
return freeze;
})).hasSize(142).allMatch(Field::isPerfect);
}
use of core.mino.Mino in project solution-finder by knewjade.
the class Main3 method main.
public static void main(String[] args) {
Field field = FieldFactory.createField("" + "X_______XX" + "X_______XX" + "X_______XX" + "X_______XX");
int maxClearLine = 4;
Field verifyField = field.freeze(maxClearLine);
System.out.println(FieldView.toString(field, maxClearLine));
Stopwatch stopwatch = Stopwatch.createStoppedStopwatch();
stopwatch.start();
Set<List<Piece>> sets = new HashSet<>();
List<Piece> allPieces = Piece.valueList();
List<Piece> pieces = new ArrayList<>(allPieces);
int popCount = (maxClearLine * 10 - field.getNumOfAllBlocks()) / 4;
CombinationIterable<Piece> combinationIterable = new CombinationIterable<>(pieces, popCount);
for (List<Piece> pieceList : combinationIterable) {
pieceList.sort(Comparator.comparingInt(allPieces::indexOf));
sets.add(pieceList);
}
TreeSet<Obj> allObjSet = new TreeSet<>();
int counter = 0;
for (List<Piece> usedPieces : sets) {
counter++;
System.out.println(usedPieces);
System.out.println(counter + " / " + sets.size());
List<List<MinoOperationWithKey>> operationsWithKey = search(usedPieces, field, maxClearLine, verifyField);
List<Obj> objs = operationsWithKey.stream().map(operationWithKeys -> {
boolean isDeleted = false;
BlockField blockField = new BlockField(maxClearLine);
for (MinoOperationWithKey key : operationWithKeys) {
Field test = FieldFactory.createField(maxClearLine);
Mino mino = key.getMino();
test.put(mino, key.getX(), key.getY());
test.insertWhiteLineWithKey(key.getNeedDeletedKey());
blockField.merge(test, mino.getPiece());
if (key.getNeedDeletedKey() != 0L)
isDeleted = true;
}
return new Obj(usedPieces, blockField, isDeleted, operationWithKeys);
}).collect(Collectors.toList());
System.out.println(objs.size());
objs.stream().map(obj -> OperationWithKeyInterpreter.parseToString(obj.operations)).sorted().sequential().forEach(System.out::println);
allObjSet.addAll(objs);
}
System.out.println(allObjSet.size());
System.exit(0);
ArrayList<Obj> allObjs = new ArrayList<>(allObjSet);
allObjs.sort(Main3::blockListComparator);
// System.out.println(operationsWithKey.size());
ColorConverter colorConverter = new ColorConverter();
System.out.println("<h3>各ミノ最大1つずつ & ライン消去なし</h3>");
Predicate<Obj> objPredicate = obj -> !obj.isDouble && !obj.isDeleted;
List<TetfuElement> oneNoDelete = createTetfuElements(field, allObjs, colorConverter, objPredicate);
viewTetfu(oneNoDelete);
System.out.println("<h3>同一ミノを2つ利用 & ライン消去なし</h3>");
Predicate<Obj> objPredicate1 = obj -> obj.isDouble && !obj.isDeleted;
List<TetfuElement> doubleNoDelete = createTetfuElements(field, allObjs, colorConverter, objPredicate1);
viewTetfu(doubleNoDelete);
System.out.println("<h3>各ミノ最大1つずつ & ライン消去あり</h3>");
Predicate<Obj> objPredicate2 = obj -> !obj.isDouble && obj.isDeleted;
List<TetfuElement> oneDeleted = createTetfuElements(field, allObjs, colorConverter, objPredicate2);
viewTetfu(oneDeleted);
System.out.println("<h3>同一ミノを2つ利用 & ライン消去あり</h3>");
Predicate<Obj> objPredicate3 = obj -> obj.isDouble && obj.isDeleted;
List<TetfuElement> doubleDeleted = createTetfuElements(field, allObjs, colorConverter, objPredicate3);
viewTetfu(doubleDeleted);
// List<List<FullLimitedMino>> lists = Arrays.asList(
// singletonList(create(minoFactory, Piece.I, Rotate.Left, PositionLimit.OddX, 0L, 0, 3)),
// singletonList(create(minoFactory, Piece.O, Rotate.Spawn, PositionLimit.OddX, 0L, 0, 1)),
// singletonList(create(minoFactory, Piece.O, Rotate.Spawn, PositionLimit.OddX, 0L, 2, 3)),
// singletonList(create(minoFactory, Piece.L, Rotate.Reverse, PositionLimit.OddX, 0L, 0, 1)),
// singletonList(create(minoFactory, Piece.J, Rotate.Reverse, PositionLimit.OddX, 0L, 0, 1)),
// singletonList(create(minoFactory, Piece.Z, Rotate.Spawn, PositionLimit.EvenX, 0L, 2, 3)),
// singletonList(create(minoFactory, Piece.S, Rotate.Left, PositionLimit.OddX, 1024L, 0, 3)),
// singletonList(create(minoFactory, Piece.Z, Rotate.Left, PositionLimit.EvenX, 1024L, 0, 3)),
// singletonList(create(minoFactory, Piece.T, Rotate.Spawn, PositionLimit.OddX, 0L, 0, 1)),
// singletonList(create(minoFactory, Piece.T, Rotate.Reverse, PositionLimit.EvenX, 0L, 2, 3))
// );
// CrossBuilder crossBuilder = new CrossBuilder(lists, FieldFactory.createField(maxClearLine), maxClearLine);
// List<List<OperationWithKey>> lists1 = crossBuilder.create();
// System.out.println(lists1.size());
// List<List<OperationWithKey>> search = new Search(FieldFactory.createField(4), Arrays.asList(
// create(minoFactory, Piece.O, Rotate.Spawn, PositionLimit.NoLimit, 0L, 0, 1),
// create(minoFactory, Piece.O, Rotate.Spawn, PositionLimit.NoLimit, 0L, 2, 3),
// create(minoFactory, Piece.I, Rotate.Right, PositionLimit.NoLimit, 0L, 0, 3),
// create(minoFactory, Piece.L, Rotate.Reverse, PositionLimit.NoLimit, 0L, 0, 1),
// create(minoFactory, Piece.J, Rotate.Reverse, PositionLimit.NoLimit, 0L, 0, 1),
// create(minoFactory, Piece.T, Rotate.Spawn, PositionLimit.NoLimit, 0L, 0, 1),
// create(minoFactory, Piece.T, Rotate.Reverse, PositionLimit.NoLimit, 0L, 2, 3),
// create(minoFactory, Piece.Z, Rotate.Right, PositionLimit.NoLimit, 0x400L, 0, 3),
// create(minoFactory, Piece.S, Rotate.Right, PositionLimit.NoLimit, 0x400L, 0, 3)
// ), maxClearLine).search();
// System.out.println("--");
// for (List<OperationWithKey> operationWithKeys : search) {
// System.out.println(operationWithKeys);
// }
// MinoFactory minoFactory = new MinoFactory();
// List<List<FullLimitedMino>> lists = Arrays.asList(
// singletonList(create(minoFactory, Piece.J, Rotate.Right, PositionLimit.OddX, 0L, 0, 2)),
// singletonList(create(minoFactory, Piece.L, Rotate.Left, PositionLimit.EvenX, 1048576, 0, 4))
// );
// CrossBuilder crossBuilder = new CrossBuilder(lists, FieldFactory.createField("" +
// "__XXXXXXXX" +
// "__XXXXXXXX" +
// "__XXXXXXXX" +
// "__XXXXXXXX"
// ), maxClearLine);
// List<List<OperationWithKey>> lists1 = crossBuilder.create();
// for (List<OperationWithKey> operationWithKeys : lists1) {
// System.out.println(operationWithKeys);
// }
// System.out.println(lists1.size());
stopwatch.stop();
System.out.println(stopwatch.toMessage(TimeUnit.MILLISECONDS));
}
use of core.mino.Mino in project solution-finder by knewjade.
the class AllFigGenerator method updateMino.
@Override
public void updateMino(ColorType colorType, Rotate rotate, int xIndex, int yIndex) {
Piece piece = colorConverter.parseToBlock(colorType);
Mino mino = minoFactory.create(piece, rotate);
FigColor figColor = FigColor.parse(colorType);
Color color = figColor.getStrongColor();
graphics.setColor(color);
for (int[] positions : mino.getPositions()) {
Rectangle rectangle = positionDecider.getInField(xIndex + positions[0], yIndex + positions[1]);
fillRect(rectangle);
}
}
Aggregations