Search in sources :

Example 1 with IfCategory

use of com.faendir.zachtronics.bot.inf.model.IfCategory in project zachtronics-leaderboard-bot by F43nd1r.

the class IfController method getRecord.

@GetMapping(path = "/puzzle/{puzzleId}/category/{categoryId}/record", produces = MediaType.APPLICATION_JSON_VALUE)
public IfRecordDTO getRecord(@PathVariable String puzzleId, @PathVariable String categoryId) {
    IfPuzzle puzzle = findPuzzle(puzzleId);
    IfCategory category = findCategory(categoryId);
    IfRecord record = repository.find(puzzle, category);
    if (record != null)
        return IfRecordDTO.fromCategoryRecord(new CategoryRecord<>(record, EnumSet.of(category)));
    else
        return null;
}
Also used : IfRecord(com.faendir.zachtronics.bot.inf.model.IfRecord) IfPuzzle(com.faendir.zachtronics.bot.inf.model.IfPuzzle) IfCategory(com.faendir.zachtronics.bot.inf.model.IfCategory) CategoryRecord(com.faendir.zachtronics.bot.repository.CategoryRecord)

Example 2 with IfCategory

use of com.faendir.zachtronics.bot.inf.model.IfCategory in project zachtronics-leaderboard-bot by F43nd1r.

the class IfRecordDTO method fromCategoryRecord.

@NotNull
public static IfRecordDTO fromCategoryRecord(@NotNull CategoryRecord<IfRecord, IfCategory> categoryRecord) {
    IfRecord record = categoryRecord.getRecord();
    Set<IfCategory> categories = categoryRecord.getCategories();
    return new IfRecordDTO(IfScoreDTO.fromScore(record.getScore()), record.getScore().toDisplayString(DisplayContext.plainText()), record.getAuthor(), record.getDataLink(), UtilsKt.smartFormat(categories, UtilsKt.toMetricsTree(record.getPuzzle().getSupportedCategories())));
}
Also used : IfRecord(com.faendir.zachtronics.bot.inf.model.IfRecord) IfCategory(com.faendir.zachtronics.bot.inf.model.IfCategory) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with IfCategory

use of com.faendir.zachtronics.bot.inf.model.IfCategory in project zachtronics-leaderboard-bot by F43nd1r.

the class IfSolution method unmarshal.

@NotNull
public static IfSolution unmarshal(@NotNull String[] fields) {
    assert fields.length == 4;
    IfScore score = Objects.requireNonNull(IfScore.parseScore(fields[0]));
    String author = fields[1];
    String displayLinks = fields[2];
    String categories = fields[3];
    IfSolution solution = new IfSolution(score, author, List.of(displayLinks.split(",")));
    if (categories != null)
        Pattern.compile(",").splitAsStream(categories).map(IfCategory::valueOf).forEach(solution.categories::add);
    return solution;
}
Also used : IfScore(com.faendir.zachtronics.bot.inf.model.IfScore) IfCategory(com.faendir.zachtronics.bot.inf.model.IfCategory) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with IfCategory

use of com.faendir.zachtronics.bot.inf.model.IfCategory in project zachtronics-leaderboard-bot by F43nd1r.

the class IfSolutionRepository method archiveOne.

/**
 * @param solutions the list is modified with the updated state
 */
@Override
@NotNull
protected SubmitResult<IfRecord, IfCategory> archiveOne(@NotNull GitRepository.ReadWriteAccess access, @NotNull List<IfSolution> solutions, @NotNull IfSubmission submission) {
    IfPuzzle puzzle = submission.getPuzzle();
    Path puzzlePath = getPuzzlePath(access, puzzle);
    List<CategoryRecord<IfRecord, IfCategory>> beatenCategoryRecords = new ArrayList<>();
    IfSolution candidate = new IfSolution(submission.getScore(), submission.getAuthor(), submission.getDisplayLinks());
    try {
        for (ListIterator<IfSolution> it = solutions.listIterator(); it.hasNext(); ) {
            IfSolution solution = it.next();
            int r = dominanceCompare(candidate.getScore(), solution.getScore());
            if (r > 0) {
                // TODO actually return all of the beating sols
                CategoryRecord<IfRecord, IfCategory> categoryRecord = solution.extendToCategoryRecord(puzzle, makeArchiveLink(puzzle, solution.getScore()), makeArchivePath(puzzlePath, solution.getScore()));
                return new SubmitResult.NothingBeaten<>(Collections.singletonList(categoryRecord));
            } else if (r < 0) {
                // allow same-score solution changes only if you are the original author
                if (candidate.getScore().equals(solution.getScore()) && !candidate.getAuthor().equals(solution.getAuthor())) {
                    return new SubmitResult.AlreadyPresent<>();
                }
                // remove beaten score and get categories
                candidate.getCategories().addAll(solution.getCategories());
                Files.delete(makeArchivePath(puzzlePath, solution.getScore()));
                // the beaten record has no data anymore
                beatenCategoryRecords.add(solution.extendToCategoryRecord(puzzle, null, null));
                it.remove();
            }
        }
        // the new record may have gained categories of records it didn't pareto-beat, do the transfers
        for (IfSolution solution : solutions) {
            EnumSet<IfCategory> lostCategories = EnumSet.noneOf(IfCategory.class);
            for (IfCategory category : solution.getCategories()) {
                if (category.supportsScore(candidate.getScore()) && category.getScoreComparator().compare(candidate.getScore(), solution.getScore()) < 0) {
                    lostCategories.add(category);
                }
            }
            if (!lostCategories.isEmpty()) {
                // add a CR holding the lost categories, then correct the solutions
                CategoryRecord<IfRecord, IfCategory> beatenCR = new CategoryRecord<>(solution.extendToRecord(puzzle, makeArchiveLink(puzzle, solution.getScore()), makeArchivePath(puzzlePath, solution.getScore())), lostCategories);
                beatenCategoryRecords.add(beatenCR);
                solution.getCategories().removeAll(lostCategories);
                candidate.getCategories().addAll(lostCategories);
            }
        }
        int index = Collections.binarySearch(solutions, candidate, COMPARATOR);
        if (index < 0) {
            index = -index - 1;
        }
        solutions.add(index, candidate);
        String filename = makeScoreFilename(candidate.getScore());
        Path solutionPath = puzzlePath.resolve(filename);
        // ensure there is one and only one newline at the end
        String data = submission.getData().replaceFirst("\\s*$", "\n");
        Files.writeString(solutionPath, data, StandardOpenOption.CREATE_NEW);
        marshalSolutions(solutions, puzzlePath);
    } catch (IOException e) {
        // failures could happen after we dirtied the repo, so we call reset&clean on the puzzle dir
        access.resetAndClean(puzzlePath.toFile());
        return new SubmitResult.Failure<>(e.toString());
    }
    if (access.status().isClean()) {
        // the same exact sol was already archived,
        return new SubmitResult.AlreadyPresent<>();
    }
    String result = commit(access, submission, puzzlePath);
    return new SubmitResult.Success<>(result, beatenCategoryRecords);
}
Also used : Path(java.nio.file.Path) CategoryRecord(com.faendir.zachtronics.bot.repository.CategoryRecord) IfCategory(com.faendir.zachtronics.bot.inf.model.IfCategory) SubmitResult(com.faendir.zachtronics.bot.repository.SubmitResult) IOException(java.io.IOException) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with IfCategory

use of com.faendir.zachtronics.bot.inf.model.IfCategory in project zachtronics-leaderboard-bot by F43nd1r.

the class IfSolutionRepository method writeToRedditLeaderboard.

@Override
protected void writeToRedditLeaderboard(IfPuzzle puzzle, Path puzzlePath, @NotNull List<IfSolution> solutions, String updateMessage) {
    if (// TODO
    true)
        return;
    Map<IfCategory, IfRecord> recordMap = new EnumMap<>(IfCategory.class);
    for (IfSolution solution : solutions) {
        IfRecord record = solution.extendToRecord(puzzle, makeArchiveLink(puzzle, solution.getScore()), makeArchivePath(puzzlePath, solution.getScore()));
        for (IfCategory category : solution.getCategories()) {
            recordMap.put(category, record);
        }
    }
    List<String> lines = Pattern.compile("\\r?\\n").splitAsStream(redditService.getWikiPage(Subreddit.INFINIFACTORY, "index")).collect(// mutable list
    Collectors.toList());
    Pattern puzzleRegex = Pattern.compile("^\\| \\[" + Pattern.quote(puzzle.getDisplayName()));
    ListIterator<String> it = lines.listIterator();
    // |                        | [(**c**/pp/l)](https://cl.txt) |                                | [(c/pp/**l**)](https://lp.txt)
    while (it.hasNext()) {
        String line = it.next();
        if (puzzleRegex.matcher(line).find()) {
            it.remove();
            break;
        }
    }
    while (it.hasNext()) {
        String line = it.next();
        if (line.equals("|") || line.isBlank()) {
            it.previous();
            break;
        } else {
            it.remove();
        }
    }
    for (int rowIdx = 0; rowIdx < 2; rowIdx++) {
        StringBuilder row = new StringBuilder("| ");
        if (rowIdx == 0)
            row.append(Markdown.linkOrText(puzzle.getDisplayName(), puzzle.getLink()));
        IfCategory[] blockCategories = CATEGORIES[rowIdx];
        boolean usefulLine = false;
        for (int i = 0; i < 3; i++) {
            IfCategory thisCategory = blockCategories[i];
            row.append(" | ");
            IfRecord thisRecord = recordMap.get(thisCategory);
            if (rowIdx == 0 || thisRecord != recordMap.get(CATEGORIES[0][i])) {
                DisplayContext<IfCategory> displayContext = new DisplayContext<>(StringFormat.REDDIT, thisCategory);
                String cell = thisRecord.toDisplayString(displayContext);
                row.append(cell);
                usefulLine = true;
            }
        }
        if (usefulLine)
            it.add(row.toString());
    }
    redditService.updateWikiPage(Subreddit.INFINIFACTORY, "index", String.join("\n", lines), updateMessage);
}
Also used : Pattern(java.util.regex.Pattern) DisplayContext(com.faendir.zachtronics.bot.model.DisplayContext) IfCategory(com.faendir.zachtronics.bot.inf.model.IfCategory)

Aggregations

IfCategory (com.faendir.zachtronics.bot.inf.model.IfCategory)6 NotNull (org.jetbrains.annotations.NotNull)4 IfPuzzle (com.faendir.zachtronics.bot.inf.model.IfPuzzle)2 IfRecord (com.faendir.zachtronics.bot.inf.model.IfRecord)2 CategoryRecord (com.faendir.zachtronics.bot.repository.CategoryRecord)2 IfScore (com.faendir.zachtronics.bot.inf.model.IfScore)1 DisplayContext (com.faendir.zachtronics.bot.model.DisplayContext)1 SubmitResult (com.faendir.zachtronics.bot.repository.SubmitResult)1 IOException (java.io.IOException)1 Path (java.nio.file.Path)1 Pattern (java.util.regex.Pattern)1 Pair (kotlin.Pair)1