-
Notifications
You must be signed in to change notification settings - Fork 0
/
SubmissionPackager.java
182 lines (148 loc) · 6.72 KB
/
SubmissionPackager.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package codecup2022.tools;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SubmissionPackager {
private final String outputFileName;
private static final boolean MINIMIZE = true;
public static void main(String[] args) throws IOException {
Path mainClass = Paths.get("src", "codecup2022", "runner", "PlayerRunner.java");
List<Path> inputFiles = Arrays.asList(
Paths.get("src", "codecup2022", "data", "Move.java"),
Paths.get("src", "codecup2022", "data", "Board.java"),
Paths.get("src", "codecup2022", "data", "Paths.java"),
Paths.get("src", "codecup2022", "data", "ArrayBoard.java"),
Paths.get("src", "codecup2022", "data", "BitBoard.java"),
Paths.get("src", "codecup2022", "data", "RolloutBoard.java"),
Paths.get("src", "codecup2022", "tools", "XoRoShiRo128PlusRandom.java"),
Paths.get("src", "codecup2022", "stopcriterion", "StopCriterion.java"),
Paths.get("src", "codecup2022", "stopcriterion", "IterationCount.java"),
Paths.get("src", "codecup2022", "stopcriterion", "EqualTurnTime.java"),
Paths.get("src", "codecup2022", "player", "Player.java"),
Paths.get("src", "codecup2022", "player", "LimitedValueUCTPlayer.java"),
Paths.get("src", "codecup2022", "movegenerator", "MoveGenerator.java"),
Paths.get("src", "codecup2022", "movegenerator", "AllMoves.java"),
mainClass
);
Path outputFile = Paths.get("src", "Amatriciana.java");
new SubmissionPackager(inputFiles, mainClass, outputFile);
}
private SubmissionPackager(List<Path> inputFiles, Path mainClass, Path outputFile) throws IOException {
outputFileName = outputFile.getFileName().toString();
// Gather all necessary imports
Set<String> imports = gatherNecessaryImports(inputFiles);
// Write everything
try (BufferedWriter out = Files.newBufferedWriter(outputFile)) {
// Imports first
for (String line : imports) {
out.write(line);
out.newLine();
}
if (!MINIMIZE) {
out.newLine();
}
// Then the main class
appendClass(mainClass, out, true);
// Finally the others
for (Path file : inputFiles) {
if (file != mainClass) {
appendClass(file, out, false);
}
}
}
}
private Set<String> gatherNecessaryImports(List<Path> sourceFiles) throws IOException {
// Add all imports that aren't of included classes
HashSet<String> imports = new HashSet<>();
for (Path file : sourceFiles) {
try (BufferedReader in = Files.newBufferedReader(file)) {
String line = in.readLine();
while (line != null) {
if (line.contains("import java") || line.contains("import sun")) {
imports.add(line);
}
if (line.contains("{")) {
// Class starts; no imports after this
break;
}
line = in.readLine();
}
}
}
return imports;
}
private void appendClass(Path sourceFile, BufferedWriter out, boolean isMainClass) throws IOException {
try (BufferedReader in = Files.newBufferedReader(sourceFile)) {
String line = in.readLine();
// Skip to the start of the class
while (line != null && !line.startsWith("public ")) {
line = in.readLine();
}
if (line == null) {
return;
}
// Remove 'public' if this is not the main class
if (isMainClass) {
// Replace the name of the main class with the name of the output file
String fileName = sourceFile.getFileName().toString();
String className = fileName.substring(0, fileName.lastIndexOf('.'));
out.write(line.replace(className, outputFileName.substring(0, outputFileName.lastIndexOf('.'))));
out.newLine();
} else {
out.write(line.trim().substring("public ".length()));
out.newLine();
}
// Copy the remainder of the file
line = in.readLine();
while (line != null) {
if (MINIMIZE) {
// Remove indentation and comments
line = pack(line);
while (line.contains("/*") && line.contains("*/")) {
int start = line.indexOf("/*");
int end = line.indexOf("*/", start + 2);
if (end != -1) {
line = line.substring(0, start).trim() + " " + line.substring(end + 2).trim();
}
}
if (line.contains("/*")) {
// Start of a multi-line block comment
line = line.substring(0, line.indexOf("/*"));
String temp = in.readLine();
while (!temp.contains("*/")) {
temp = in.readLine();
}
temp = temp.substring(temp.indexOf("*/") + 2);
if (temp.contains("/*")) {
System.err.println("WARNING: new block comment starting on the same line where the previous finished. This case isn't handled correctly by the code minimizer. It is recommended that you start the new block comment on the next line instead.");
}
line += pack(temp);
}
}
// Skip empty lines when minimizing
if (!MINIMIZE || !line.isEmpty()) {
out.write(line);
out.newLine();
}
line = in.readLine();
}
if (!MINIMIZE) {
out.newLine();
}
}
}
private String pack(String line) {
return line
.replaceAll("//.*$", "")
.replaceAll("([\\(\\)\\{\\}\\[\\],+\\-/%*=?:;<>|\\&\\^!]) ", "$1")
.replaceAll(" ([\\(\\)\\{\\}\\[\\],+\\-/*=?:;<>|\\&\\^!])", "$1")
.trim();
}
}