更多:开源围棋…
掌中围棋2.4版本源码,包含一个完善的SGF棋谱文件解析器,速度快,内存占用低适合Android使用
https://github.com/uestccokey/HandsGo
掌中围棋2.4版本源码下载:
链接: https://pan.baidu.com/s/19DAsA0HlBKfJ9L7SUjgdhQ 提取码: p9fz
SGFTree.java
package com.soyomaker.handsgo.go.sgf; import java.io.BufferedReader; import java.io.IOException; import java.util.Vector; /** * This is a class wich contains a TreeNode. It used to store complete game * trees. * */ public class SGFTree { protected TreeNode History; // the game history private final int maxbuffer = 4096; private char[] Buffer = new char[maxbuffer]; // the buffer for reading of // files private int BufferN; private static int lastnl = 0; /** initlialize with a specific Node */ public SGFTree(Node n) { History = new TreeNode(n); History.node().main(true); } /** return the top node of this game tree */ public TreeNode top() { return History; } char readNext(BufferedReader in) throws IOException { int c = readChar(in); while (c == '\n' || c == '\t' || c == ' ') { if (c == -1) throw new IOException(); c = readChar(in); } return (char) c; } char readChar(BufferedReader in) throws IOException { int c; while (true) { c = in.read(); if (c == -1) throw new IOException(); if (c == 13) { if (lastnl == 10) lastnl = 0; else { lastnl = 13; return '\n'; } } else if (c == 10) { if (lastnl == 13) lastnl = 0; else { lastnl = 10; return '\n'; } } else { lastnl = 0; return (char) c; } } } // read a node assuming that ; has been found // return the character, which did not fit into node properties, // usually ;, ( or ) char readNode(TreeNode p, BufferedReader in) throws IOException { boolean sgf = true; char c = readNext(in); Action a; Node n = new Node(((Node) p.content()).number()); String s; loop: while (true) // read all actions { BufferN = 0; while (true) { if (c >= 'A' && c <= 'Z') store(c); // note only capital letters else if (c == '(' || c == ';' || c == ')') break loop; // last property reached // BufferN should be 0 then else if (c == '[') break; // end of porperty type, arguments starting else if (c < 'a' || c > 'z') throw new IOException(); // this is an error c = readNext(in); } if (BufferN == 0) throw new IOException(); s = new String(Buffer, 0, BufferN); if (s.equals("L")) a = new LabelAction(); else if (s.equals("M")) a = new MarkAction(); else a = new Action(s); while (c == '[') { BufferN = 0; while (true) { c = readChar(in); if (c == '\\') { c = readChar(in); if (sgf && c == '\n') { if (BufferN > 1 && Buffer[BufferN - 1] == ' ') continue; else c = ' '; } } else if (c == ']') break; store(c); } c = readNext(in); // prepare next argument String s1; if (BufferN > 0) s1 = new String(Buffer, 0, BufferN); else s1 = ""; if (!expand(a, s1)) a.addArgument(s1); } // no more arguments n.addAction(a); if (a.type().equals("B") || a.type().equals("W")) { n.number(n.number() + 1); } } // end of actions has been found // append node n.main(p); TreeNode newp; if (((Node) p.content()).actions() == null) p.content(n); else { p.addChild(newp = new TreeNode(n)); n.main(p); p = newp; if (p.parentPos() != null && p != p.parentPos().firstChild()) ((Node) p.content()).number(2); } return c; } /** * Store c into the Buffer extending its length, if necessary. This is a fix * by Bogdar Creanga from 2000-10-17 (Many Thanks) */ private void store(char c) { try { Buffer[BufferN] = c; BufferN++; } catch (ArrayIndexOutOfBoundsException e) { int newLength = Buffer.length + maxbuffer; char[] newBuffer = new char[newLength]; System.arraycopy(Buffer, 0, newBuffer, 0, Buffer.length); Buffer = newBuffer; Buffer[BufferN++] = c; } } // Check for the terrible compressed point list and expand into // single points boolean expand(Action a, String s) { String t = a.type(); if (!(t.equals("MA") || t.equals("SQ") || t.equals("TR") || t.equals("CR") || t.equals("AW") || t.equals("AB") || t.equals("AE") || t.equals("SL"))) return false; if (s.length() != 5 || s.charAt(2) != ':') return false; String s0 = s.substring(0, 2), s1 = s.substring(3); int i0 = Field.i(s0), j0 = Field.j(s0); int i1 = Field.i(s1), j1 = Field.j(s1); if (i1 < i0 || j1 < j0) return false; int i, j; for (i = i0; i <= i1; i++) for (j = j0; j <= j1; j++) { a.addArgument(Field.string(i, j)); } return true; } /** * Read the nodes belonging to a tree. this assumes that ( has been found. */ void readNodes(TreeNode p, BufferedReader in) throws IOException { char c = readNext(in); while (true) { if (c == ';') { c = readNode(p, in); if (p.hasChildren()) p = p.lastChild(); continue; } else if (c == '(') { readNodes(p, in); } else if (c == ')') break; c = readNext(in); } } /** * Read the tree from an BufferedReader in SGF format. The BoardInterfaces * is only used to determine the "sgfcomments" parameter. */ public static Vector<SGFTree> load(BufferedReader in) throws IOException { Vector<SGFTree> v = new Vector<SGFTree>(); boolean linestart = true; int c; reading: while (true) { SGFTree T = new SGFTree(new Node(1)); while (true) // search for ( at line start { try { c = T.readChar(in); } catch (IOException ex) { break reading; } if (linestart && c == '(') break; if (c == '\n') linestart = true; else linestart = false; } T.readNodes(T.History, in); // read the nodes v.addElement(T); } return v; } public int getSize() { try { return Integer.parseInt(History.getAction("SZ")); } catch (Exception e) { return 19; } } }