-
-
Notifications
You must be signed in to change notification settings - Fork 708
queen-attack: add to track #171
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
Conversation
@jtigger no idea what caused that failure. Any clues? If not, how can I trigger a rebuild? Thanks! |
Never mind, rebuild seems to be working just fine! |
hmmmmmm. From the logs:
... but like you said, the next build succeeded. |
Yeah, likely to be a CI hiccup I'm thinking. |
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.
Good as-is. My comments focus on API design and bringing in domain concepts to increase engagement.
|
||
private final int[] queen2Coordinates; | ||
|
||
public QueenAttackCalculator(final int[] queen1Coordinates, final int[] queen2Coordinates) |
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 definitely gets the job done. That said, I detect a hint of primitive obsession.
What do you think of codifying the concept of Coordinate
?
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 know that the README doesn't call it out, but what do you think of naming the parameters blackQueenCoordinates
and whiteQueenCoordinates
?
Personally, I find exercises that immerse me in the domain a bit more engaging... as if I'm solving a trimmed down version of "the real thing."
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.
Just as an FYI: I'm proposing to the group to switch to SAN: exercism/problem-specifications#446. That is a significant change and should not hold up this work.
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.
R.E. a Coordinate
type - I agree that primitive types are a little ugly here, but I avoided introducing a second separate type that requires implementation as I did not find another example which follows that pattern. (This is probably why other exercises used e.g. Guava to provide a nicer parameter type, though I agree with the removal of that third party dependency moving forward). It shouldn't be hard to adapt the problem, however, so I'll make the change to use a separate Coordinate
type and we can see how that feels!
R.E. renaming to white/black - yep, great call, will make the change!
R.E. notation change - there's a note about using chess notation in the canonical data set that mentions it, but IMO it's not really clear how the note should be interpreted:
Some languages implement tests beyond this set, such as checking for two pieces being placed on the same position, representing the board graphically, or using standard chess notation. Those tests can be offered as extra credit.
Is there build-in support in Exercism for optional/extra credit tests? If not, I'm guessing this means we could expose two methods that accept differently-formatted Coordinate
types and require implementations that satisfy both to consider the problem complete. That feels like relatively uninteresting duplication, however.
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.
subject Coordinates
:
It is absolutely "in bounds" to include other bits in the starter code (i.e. main
sourceset). There are examples of this in other exercises (Allergen
for one).
The way I think about it, we are defining the API for the exercising programmer. We are free to define as little as an interface and as much as a whole class as we see appropriate.
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.
subject "SAN":
There is not currently a mechanism for extra-credit, per se. It's merely a mention of where the exercising programmer could go from here.
Personally, I'd like to see this exercise be defined as using SAN, but that takes rough consensus across the tracks (read: not happening, today).
It could be an interesting exercise to declare two contracts (one with cartesian coordinate and another for SAN coordinates) and a test class for both of those interfaces. The SAN test class would have to make it clear that it is optional; there ought to be additional readme (EXTRA-CREDIT.md
?) to provide a proper framing.
None of that is at all required for this PR. I'm just thinking out loud, now.
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.
R.E. Coordinates
: ah, thanks for the reference to the allergies exercise; symlinking into the example source set is a nice solution there. What are your thoughts, then, for the queen-attack exercise: require the implementer to build the Coordinate
class, or provide it and allow the implementer to focus on the attack logic only?
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.
R.E. notation: all good points! Perhaps you could open a new issue to capture the ideas you described regarding extra credit, etc.?
public final class QueenAttackCalculatorTest { | ||
|
||
@Rule | ||
public ExpectedException expectedException = ExpectedException.none(); |
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.
Nice. This is a lovely JUnit idiom to introduce here.
At this time, this is the first time we've used JUnit Rules. What would be the "right" user experience here?
- just discover it and have her/him do her/his own research to discover how this mechanism works?
- see a comment that's a URL to an introduction to JUnit Rules?
- see a comment that references a markdown file in the fetched exercise?
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 like the second option - we can save a search and provide a link to: https://github.com/junit-team/junit4/wiki/Rules, but still leave reading and discovery to the user?
@@ -24,6 +24,7 @@ include 'pangram' | |||
include 'pascals-triangle' | |||
include 'phone-number' | |||
include 'pig-latin' | |||
include 'queen-attack' |
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 really appreciate the little ways you keep things tidy, @stkent. This is a small thing, but instead of just adding this to the end of the list, you included it alphabetically👍 . You're probably just enabling my OCD. 😉
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.
Hah, everything in its right place!
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.
The actual "request changes" part is the seemingly extraneous Coordinate
.
I can't help myself, so I also included some other suggestions; feel free to ignore, @stkent — this is really lovely, as is.
@@ -0,0 +1,5 @@ | |||
public final class Coordinate { |
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 suspect this was left over from an intermediate effort?
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.
Ah, yes, I did mean to leave a BoardCoordinate
class in here since that's a required part of the exercise API; renamed!
|
||
private final int file; | ||
|
||
public BoardCoordinate(final int rank, final int file) throws IllegalArgumentException { |
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 is not at all a request/demand... just a thought: value objects often come with come with a factory method (usually with a short name). Then, in places where it is used, they employ a static import.
public static BoardCoordinate at(final int rank, final int file) {
return new BoardCoordinate(rank, file);
}
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.
While I'm familiar with the practice, in this particular code I felt that it would hurt readability. For example, I think that the context provided by the class name here:
new QueenAttackCalculator(new BoardCoordinate(2, 4), new BoardCoordinate(6, 6));
makes that code easier to comprehend than, say:
new QueenAttackCalculator(at(2, 4), at(6, 6));
This is especially true given that users must attempt to reverse-engineer the APIs required in their implementations from reading the tests (static imports of non-test-framework classes definitely make this harder!)
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.
oooohhhh! I missed the part where BoardCoordinates
is in the example
sourceset. I absolutely agree.
import static org.junit.Assert.assertTrue; | ||
|
||
public final class QueenAttackCalculatorTest { | ||
|
||
/* |
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.
👍
@jtigger thanks for the comments - replied/updated! |
import org.junit.Test; | ||
import org.junit.Ignore; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; |
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.
OMG, you're going to kill me — this is a long PR; thank you for your patience.
Looks like we have a freeloader, 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.
The pitfalls of auto-optimized imports! Fixed this commit :)
Rebased to fix conflicts after largest-series-product was merged. |
Thanks again, @stkent. Good add. |
@jtigger I don't see this exercise on the website (http://exercism.io/languages/java/exercises) 4 days after the merge. Is there a periodic rebuild of the website that will expose the new exercise, or did I miss something in implementing this PR? Thanks! |
Hah, as I suspected. Thanks for confirming! |
Test data sourced from https://github.com/exercism/x-common/blob/master/exercises/queen-attack/canonical-data.json