-
-
Notifications
You must be signed in to change notification settings - Fork 554
Add exercise: state-of-tic-tac-toe #1991
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
@ErikSchierboom the order of this is all wrong but I think you have a script to fix that, guessing based on #1960? (perhaps that should be part of |
These arrays should be multi-line as in #1968. |
Some example solutions in Juliafunction gamestate(bs)
# Parse to Matrix
b = hcat(split.(split(bs, "\n"), "")...)
# Invalid boards
nₒ = count(x -> x == "O", b)
nₓ = count(x -> x == "X", b)
# Not taking turns in order
if nₒ > nₓ || abs(nₒ - nₓ) > 1
throw(DomainError(b, "Invalid board: did not take turns in order"))
end
wins = 0
for i in 1:3
# Row victory
wins += b[i, 1] != " " && (b[i, 1] == b[i, 2] == b[i, 3]) ? 1 : 0
# Col victory
wins += b[1, i] != " " && (b[1, i] == b[2, i] == b[3, i]) ? 1 : 0
end
# Diagonal victories
wins += b[1, 1] != " " && (b[1, 1] == b[2, 2] == b[3, 3]) ? 1 : 0
wins += b[1, 3] != " " && (b[1, 3] == b[2, 2] == b[3, 1]) ? 1 : 0
if wins == 1
return :win
elseif wins > 1
throw(DomainError(b, "Invalid board: more than one win"))
end
# Draw
" " ∉ b && return :draw
:ongoing
end using LinearAlgebra
function gamestate(bs)
# Parse to Int Matrix
b_str = hcat(split.(split(bs, "\n"), "")...)
replace!(b_str, "X" => "1")
replace!(b_str, " " => "0")
replace!(b_str, "O" => "-1")
b = parse.(Int, b_str)
# It's a win if any of the rows, columns, or diagonals add up to ±3
wins = count(sum(row) in (-3, 3) for row in eachrow(b)) + count(sum(col) in (-3, 3) for col in eachcol(b)) + (sum(diag(b)) in (-3, 3) ? 1 : 0) + (sum(diag(rotr90(b))) in (-3, 3) ? 1 : 0)
if wins == 1
:win
elseif wins > 1
error("Too many wins!")
elseif sum(b) == 1 && !any(x == 0 for x in b)
:draw
elseif sum(b) ∉ (0, 1)
error("Must take turns in order")
else
:ongoing
end
end |
Do we want a test with an empty board? Would that state be ongoing? Do we want to group the cases into scenarios? |
I'm happy to add it as ongoing or leave it as undefined. I don't think it really makes a difference for any solutions.
What grouping do you have in mind? Groups based on game state? |
Yes, that's what I was thinking. |
This is based on the research exercise julia-1-a Extensions of this might be possible in the future, hence tic-tac-toe may not be ideal as a slug, so I'm going with state-of-tic-tac-toe
@glennj I've grouped them based on game state now. @petertseng Could you please confirm that I've configured the array formatter correctly? |
@exercism/reviewers |
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.
Yes, I confirm that this is the correct configuration for the array formatter.
The reason I haven't Approved, in the GitHub sense of the word, is just that I haven't reviewed the other contents, but you don't need to wait for me to do that if there are others who are doing that. I just wanted to quickly get a confirmation to you that that configuration was correct.
That's a really good point, I missed that you could win "twice" with one move. Fixed in de82efb, I moved them into wins because I think they could be interesting edge cases. |
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 making Suggestions (in the GitHub sense of the word) to remove trailing whitespace, they're not required. If we really want to avoid that we should probably have something that automatically checks for it.
Co-authored-by: Peter Tseng <petertseng@users.noreply.github.com>
I thought prettier did it but perhaps it's ignored in code blocks or something 🤷 |
"cases": [ | ||
{ | ||
"uuid": "b42ed767-194c-4364-b36e-efbfb3de8788", | ||
"description": "Draw", |
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.
Should the descriptions be unique? Is this being used for test functionality (function names, etc?) when generated?
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.
That's not part of the spec and therefore would be an issue the generators would have to fix.
That said, the descriptions don't describe why the test exists all that well, so if someone wants to improve those, a follow-up PR would be appreciated. The description is mutable and I'd rather get this merged and improved later on according to the usual optimistic merging strategy.
- The players took turns out of order (remember that `X` starts). | ||
- The game was played after it already ended. | ||
|
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.
How do we test for out of order? Are there tests for out of order? I only noticed snapshots and any snapshot that has equal or one less "O" than "X" can not indicate play order on its own. I also do not see an example in "Examples" that shows what this might look like.
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 only noticed snapshots and any snapshot that has equal or one less "O" than "X" can not indicate play order on its own.
A board that has more Os than Xs is impossible to reach when the right turn order is followed. We only care if the snapshot is a valid board, i.e. reachable through legal turns.
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.
So nothing to clarify about this in the description? Line 24 mentions it, and I looked through and did not notice an example of an "out of order" state. But does this matter? Are we testing for this? (Yes, a board that has more than 2 less "O"'s than "X" would an invalid state, etc.
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.
There are two tests for it towards the end of the file. I'll add an example.
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.
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, that works.
Thanks for the reviews :) |
This is based on the research exercise julia-1-a
Extensions of this might be possible in the future, hence tic-tac-toe may not be ideal as a slug, so I'm going with state-of-tic-tac-toe.