-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds com.fathzer.jchess.uci.helper.DeferredReadMoveLibrary
- Loading branch information
Showing
3 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
99 changes: 99 additions & 0 deletions
99
src/main/java/com/fathzer/jchess/uci/helper/DeferredReadMoveLibrary.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package com.fathzer.jchess.uci.helper; | ||
|
||
import java.io.File; | ||
import java.io.FileNotFoundException; | ||
import java.io.IOException; | ||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.util.Optional; | ||
|
||
import com.fathzer.games.MoveGenerator; | ||
import com.fathzer.games.ai.evaluation.EvaluatedMove; | ||
import com.fathzer.games.movelibrary.MoveLibrary; | ||
|
||
/** A move library that encapsulates another move library and read its content outside of its constructor. | ||
* <br>This typically allows an UCI engine to instantiate a move library during the launch process, and | ||
* deferred the effective read of the moves during the <i>isReady</i> command execution as specified in | ||
* UCI protocol. | ||
* @param <M> The type of a move | ||
* @param <B> The type of the move generator used by the UCI engine | ||
*/ | ||
public class DeferredReadMoveLibrary<M, B extends MoveGenerator<M>> implements MoveLibrary<M, B> { | ||
/** A interface that can read an object from an URL and sends an IOException if sommething goes wrong. | ||
* @param <T> The type of the read object | ||
*/ | ||
@FunctionalInterface | ||
public static interface IOReader<T> { | ||
/** Reads an object. | ||
* @param url The url where to read the object | ||
* @return The object | ||
* @throws IOException If something went wrong | ||
*/ | ||
T read(URL url) throws IOException; | ||
} | ||
|
||
private final String url; | ||
private final IOReader<MoveLibrary<M, B>> reader; | ||
private MoveLibrary<M, B> internal; | ||
|
||
/** Constructor. | ||
* @param url The url where to read the MoveLibrary | ||
* @param reader The reader to read the library. | ||
*/ | ||
public DeferredReadMoveLibrary(String url, IOReader<MoveLibrary<M,B>> reader) { | ||
if (url==null || reader==null) { | ||
throw new IllegalArgumentException(); | ||
} | ||
this.url = url; | ||
this.reader = reader; | ||
} | ||
|
||
/** {@inheritDoc} | ||
* <br>If the move library is not initialized, an empty optional is returned. | ||
*/ | ||
@Override | ||
public Optional<EvaluatedMove<M>> apply(B board) { | ||
if (internal==null) { | ||
return Optional.empty(); | ||
} | ||
return internal.apply(board); | ||
} | ||
|
||
/** Tests if this move library should be initialized. | ||
* @return false if initialization has been made and succeeded. | ||
* @see #init() | ||
*/ | ||
public boolean isInitRequired() { | ||
return internal==null; | ||
} | ||
|
||
/** Initializes this move library. | ||
* @throws IOException | ||
*/ | ||
public void init() throws IOException { | ||
if (isInitRequired()) { | ||
internal = reader.read(toURL(this.url)); | ||
} | ||
} | ||
|
||
static URL toURL(String path) throws IOException { | ||
URL url; | ||
try { | ||
url = new URL(path); | ||
} catch (MalformedURLException e) { | ||
File file = new File(path); | ||
if (!file.exists()) { | ||
throw new FileNotFoundException(); | ||
} | ||
url = file.toURI().toURL(); | ||
} | ||
return url; | ||
} | ||
|
||
/** Gets the URL where the data should be/has been read. | ||
* @return A String | ||
*/ | ||
public String getUrl() { | ||
return url; | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
src/test/java/com/fathzer/jchess/uci/helper/DeferredReadBookTest.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.fathzer.jchess.uci.helper; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
import java.io.IOException; | ||
import java.net.URI; | ||
import java.net.URL; | ||
import java.util.Optional; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import com.fathzer.games.MoveGenerator; | ||
import com.fathzer.games.ai.evaluation.EvaluatedMove; | ||
import com.fathzer.games.ai.evaluation.Evaluation; | ||
import com.fathzer.games.movelibrary.MoveLibrary; | ||
|
||
class DeferredReadMoveLibraryTest { | ||
|
||
@SuppressWarnings("unchecked") | ||
private final MoveGenerator<String> mv = mock(MoveGenerator.class); | ||
|
||
@Test | ||
void test() throws Exception { | ||
String httpsURL = "https://myApp.org/file.gz"; | ||
assertEquals(URI.create(httpsURL).toURL(), DeferredReadMoveLibrary.toURL(httpsURL)); | ||
|
||
assertThrows(IOException.class, () -> DeferredReadMoveLibrary.toURL("httpx://myApp.org/file.gz")); | ||
assertThrows(IOException.class, () -> DeferredReadMoveLibrary.toURL("src/test/resources/unknownFile.json")); | ||
|
||
final String path = "src/test/resources/FakeOpenings.txt"; | ||
final DeferredReadMoveLibrary<String, MoveGenerator<String>> rb = new DeferredReadMoveLibrary<>(path, this::readOpenings); | ||
assertTrue(rb.isInitRequired()); | ||
assertTrue(rb.apply(mv).isEmpty()); | ||
rb.init(); | ||
assertFalse(rb.isInitRequired()); | ||
assertFalse(rb.apply(mv).isEmpty()); | ||
// A second init call should no throw any exception | ||
rb.init(); | ||
} | ||
|
||
private MoveLibrary<String, MoveGenerator<String>> readOpenings(URL url) { | ||
return new MoveLibrary<String, MoveGenerator<String>>() { | ||
@Override | ||
public Optional<EvaluatedMove<String>> apply(MoveGenerator<String> board) { | ||
return mv.equals(board) ? Optional.of(new EvaluatedMove<>("ok", Evaluation.score(100))) : Optional.empty(); | ||
} | ||
}; | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
File required by src/test/com.fathzer.jchess.uci.helper.DeferredReadBookTest.java |