-
Notifications
You must be signed in to change notification settings - Fork 228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
next: Support Read/Write Sgf with Variation, AW/AB & Comment #364
Conversation
|
||
// close file | ||
builder.append(')'); | ||
writer.append(builder.toString()); | ||
} | ||
|
||
// Generate node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useless comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
|
||
// close file | ||
builder.append(')'); | ||
writer.append(builder.toString()); | ||
} | ||
|
||
// Generate node | ||
private static String generateNode(Board board, Writer writer, BoardHistoryNode node) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need the writer
argument here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Garbage code, deleted.
@@ -250,65 +285,92 @@ private static void saveToStream(Board board, Writer writer) throws IOException | |||
builder.append(String.format("[%c%c]", x, y)); | |||
} | |||
} | |||
} else { | |||
// Process the AW/AB stone |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand that else. Can you explain why this should be executed only when handicap == 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When has handicap, there is Black stones only, the original code already is processed.
The first time I modified the code for lizzie, I didn't want to destroy the original structure too much.
So just add a else.
if (isMultiGo) { | ||
break PARSE_LOOP; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also remove the PARSE_LOOP
label (outside the parsing loop)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
if (((int) b & 0x80) != 0) { | ||
continue; | ||
} | ||
// Suppoert unicode charactors (UTF-8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo Suppoert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I think you should remove that comment. After your changes the code supports unicode because it uses charAt instead of looking that bytes, so it will be hard to understand the comment out of context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
// Initialize the step count | ||
subTreeStepMap.put(Integer.valueOf(subTreeDepth), Integer.valueOf(0)); | ||
} else { | ||
if (i > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain the i > 0
here? It seems that if we are inside a tag we always want to append that '('
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For skip first '(' that at the top of the Sgf file.
if (isMultiGo) { | ||
break PARSE_LOOP; | ||
// Restore to the variation node | ||
for (int s = 0; s < subTreeStepMap.get(Integer.valueOf(subTreeDepth)).intValue(); s++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit suspicious to recompute subTreeStepMap.get(Integer.valueOf(subTreeDepth)).intValue()
at every step of the loop. Any reason for doing that instead of computing that just outside of the for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@@ -134,15 +152,26 @@ private static boolean parse(String value) { | |||
if (move == null) { | |||
Lizzie.board.pass(Stone.BLACK); | |||
} else { | |||
// Save the step count | |||
subTreeStepMap.put(Integer.valueOf(subTreeDepth), Integer.valueOf(subTreeStepMap.get(Integer.valueOf(subTreeDepth)).intValue() + 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation is off here and a bit all over the PR... Could you configure your text editor to output spaces instead of tabs? The output should look nicer on GitHub and it would also be more consistent with the rest of the lizzie code base.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I have ignored this problem because with multiple editors.
Fixed it.
Lizzie.board.place(move[0], move[1], Stone.BLACK); | ||
} | ||
} else if (tag.equals("W")) { | ||
int[] move = convertSgfPosToCoord(tagContent); | ||
if (move == null) { | ||
Lizzie.board.pass(Stone.WHITE); | ||
} else { | ||
// Save the step count | ||
subTreeStepMap.put(Integer.valueOf(subTreeDepth), Integer.valueOf(subTreeStepMap.get(Integer.valueOf(subTreeDepth)).intValue() + 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line seams to be copy pasted. Is a way to avoid the duplication?
@@ -96,14 +101,27 @@ private static boolean parse(String value) { | |||
case '(': | |||
if (!inTag) { | |||
subTreeDepth += 1; | |||
// Initialize the step count | |||
subTreeStepMap.put(Integer.valueOf(subTreeDepth), Integer.valueOf(0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in Java it's not required to explicitly convert between int and Integer, the java compiler will automatically box and unbox int
and Integers
to make things work. Concretely this line could be simplified to subTreeStepMap.put(subTreeDepth, 0);
This comment applies for the entirety of this PR, it would be nice if you could go over the diff and remove all the Integer.valueOf()
and .intValue()
calls that would be automatically inserted, I think the result would be simpler to read!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right.
The previous IDE compiler reported error, now there is no such problem.
Fixed.
@zsalch These are some really good additions! The only thing that worries be is the absence of tests. The code seams to be rather low level and fragile, and it very hard just by looking at the diff to make sure that you didn't break anything. Also, how is this code going to evolve in the future? In the absence of tests, it would very easy for someone to accidentally break the support for comments of variations without noticing. My suggestion to move forward would be to add integration tests to this PR. I would like this parsing code to be accompanied with a set of sample games that demonstrate all the features handled by the parser, and a few tests to show that the parser doesn't crash on these games and produces the expected output. You could maybe start from this commit efc8fe3 where I setup JUnit for the project, and write a simple test for the parser. If you need help with that I might also be able to contribute a test sample to kick start the effort. Also I think I will wait for this PR to be ready to merge before looking at #365. |
Thank you for your review, so the code is much clearer. Introducing JUnit is a good idea and I will add some JUnit use cases. For the test variations and comments, I think sgf e-book will be a good choice, of course, we have just added the AB / AW and C tag processing, for other tags have yet to be added. I will upload some sgf for testing, but most of them are in Chinese. Maybe you can provide some English sgf files. Regarding the test points, I think the first thing is the following:
Since the structure of the Node and the NodeList is not modified, the general operation should be normal when variations are correctly displayed. But this also requires testing to verify. Before do JUnit testing, you may be want to refer #356 . Here are some simple test cases. |
@OlivierBlanvillain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
Closes #350
Support following features when Read/Write the SGF file: