Add ECO opening codes

This commit is contained in:
Aprijal Pasaribu 2016-10-18 03:14:46 +07:00
parent 503390c19f
commit f666cc9f04
7 changed files with 11858 additions and 2 deletions

11716
DroidFish/assets/eco.pgn Normal file

File diff suppressed because it is too large Load Diff

View File

@ -68,6 +68,11 @@
android:layout_height="32dp">
</ImageButton>
</LinearLayout>
<TextView
android:id="@+id/eco_code"
android:textSize="12sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/status"
android:layout_width="fill_parent"

View File

@ -76,6 +76,11 @@
</ImageButton>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/eco_code"
android:textSize="12sp"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<view
class="org.petero.droidfish.MyRelativeLayout"
android:orientation="vertical"

View File

@ -21,6 +21,7 @@ package org.petero.droidfish;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
@ -43,6 +44,7 @@ import org.petero.droidfish.activities.EditPGNLoad;
import org.petero.droidfish.activities.EditPGNSave;
import org.petero.droidfish.activities.LoadFEN;
import org.petero.droidfish.activities.LoadScid;
import org.petero.droidfish.activities.PGNFile;
import org.petero.droidfish.activities.Preferences;
import org.petero.droidfish.book.BookOptions;
import org.petero.droidfish.engine.EngineUtil;
@ -162,7 +164,6 @@ public class DroidFish extends Activity
// FIXME!!! Show extended book info. (Win percent, number of games, performance rating, etc.)
// FIXME!!! Green color for "main move". Red color for "don't play in tournaments" moves.
// FIXME!!! ECO opening codes
// FIXME!!! Option to display coordinates in border outside chess board.
@ -262,6 +263,11 @@ public class DroidFish extends Activity
private boolean guideShowOnStart;
private TourGuide tourGuide;
private Thread thread;
private TextView eco_tv;
private PGNFile eco_pgn;
private String prevMoves;
/** Defines all configurable button actions. */
@ -417,6 +423,8 @@ public class DroidFish extends Activity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initECO();
Pair<String,String> pair = getPgnOrFenIntent();
String intentPgnOrFen = pair.first;
@ -759,6 +767,8 @@ public class DroidFish extends Activity
tourGuide.cleanUp();
tourGuide = null;
}
clearECO();
updateECO();
}
/** Return true if the current orientation is landscape. */
@ -787,6 +797,7 @@ public class DroidFish extends Activity
overrideViewAttribs();
// title lines need to be regenerated every time due to layout changes (rotations)
eco_tv = (TextView)findViewById(R.id.eco_code);
firstTitleLine = findViewById(R.id.first_title_line);
secondTitleLine = findViewById(R.id.second_title_line);
whiteTitleText = (TextView)findViewById(R.id.white_clock);
@ -1880,6 +1891,7 @@ public class DroidFish extends Activity
int y = (line - 1) * moveList.getLineHeight();
moveListScroll.scrollTo(0, y);
}
updateECO();
}
@Override
@ -2109,6 +2121,7 @@ public class DroidFish extends Activity
ctrl.startGame();
setBoardFlip(true);
updateEngineTitle();
clearECO();
}
private final Dialog promoteDialog() {
@ -3929,4 +3942,69 @@ public class DroidFish extends Activity
currNode = node;
}
}
private void initECO(){
(new Thread(new Runnable() {
@Override
public void run() {
File f = new File(getFilesDir()+"/eco.pgn");
try {
InputStream is = getAssets().open("eco.pgn");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
FileOutputStream fos = new FileOutputStream(f);
fos.write(buffer);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
eco_pgn = new PGNFile(f.getPath());
}
})).start();
}
private void clearECO(){
prevMoves = "";
eco_tv.setText("");
}
private void updateECO(){
if(eco_pgn == null) return;
if(thread != null && thread.isAlive()) thread.interrupt();
thread = new Thread(new Runnable() {
@Override
public void run() {
Pair<List<Node>, Integer> mvList = ctrl.getMvList();
String lsMove = "";
String ECO = null;
for(int i = 0; i < (mvList.first.size() > 28 ? 28 : mvList.first.size()); i++){
if(thread.isInterrupted()) return;
lsMove = lsMove + mvList.first.get(i).moveStr + " ";
}
if(lsMove.length() <= 0) return;
if(lsMove.equals(prevMoves)) return;
prevMoves = lsMove;
while ((lsMove.lastIndexOf(" ") > 0 || lsMove.length() == 2) && !thread.isInterrupted()) {
ECO = eco_pgn.getECO(lsMove);
if (ECO != null)
break;
lsMove = lsMove.substring(0, lsMove.lastIndexOf(" "));
}
if(!thread.isInterrupted())
writeECO(ECO);
}
});
thread.start();
}
public void writeECO(final String ECO){
runOnUIThread(new Runnable() {
@Override
public void run() {
if(ECO != null) eco_tv.setText(ECO);
}
});
}
}

View File

@ -335,4 +335,52 @@ public class PGNFile {
final boolean delete() {
return fileName.delete();
}
public final String getECO(String pgn) {
try {
BufferedRandomAccessFileReader f = new BufferedRandomAccessFileReader(fileName.getAbsolutePath());
String ECO = null;
String Opening = null;
String Variation = null;
while (true) {
String line = f.readLine();
if (line == null)
break; // EOF
int len = line.length();
if (len == 0)
continue;
if (line.startsWith("[ECO ")) {
if (len >= 9) {
ECO = line.substring(6, len - 2);
continue;
}
}
if (line.startsWith("[Opening ")) {
if (len >= 9) {
Opening = line.substring(10, len - 2);
continue;
}
}
if (line.startsWith("[Variation ")) {
if (len >= 9) {
Variation = line.substring(12, len - 2);
continue;
}
}
if(line.startsWith(pgn)){
if(line.length() >= pgn.length() + 2){
String text = line.substring(line.indexOf(pgn), line.indexOf(pgn) + pgn.length() + 2);
if(text.contains("*")){
if(Variation != null)
return ECO + ": " + Opening + ", " + Variation;
else
return ECO + ": " + Opening;
}
}
}
Variation = null;
}
}catch (IOException e){}
return null;
}
}

View File

@ -1189,4 +1189,8 @@ public class DroidChessController {
if (game.getGameState() != GameState.ALIVE) return true;
return false;
}
public Pair<List<Node>, Integer> getMvList(){
return game.tree.getMoveList();
}
}

View File

@ -999,7 +999,7 @@ public class GameTree {
* The root node is special in that it doesn't have a move.
*/
public static class Node {
String moveStr; // String representation of move leading to this node. Empty string in root node.
public String moveStr; // String representation of move leading to this node. Empty string in root node.
String moveStrLocal; // Localized version of moveStr
Move move; // Computed on demand for better PGN parsing performance.
// Subtrees of invalid moves will be dropped when detected.