Checking for win on a wrap-around Connect 6 board

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
I have a method, that checks win conditions on a "Torus" board, which is a board without any borders. This means that if you place 4 diagonal stones on the top left, and 2 diagonal stones in the bottom right, if they are in the same diagonal and would connect if you ignored the border, which then would lead to a win. Basically it's a Connect 6 Game.
size() returns the size of the board which either is 18 or 20.
currentPlayer is a String like : "P1" or "P2".
r and c are the row and column where a move has just been made.
public boolean checkTorusWinner(int r, int c)
int count = 0;
boolean hasWinner = false;
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
/*
Checks Horizontally for a Win.
*/
for (int i = c; i < hSize; i++)
if (board[r][i] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
hSize = size() - 2;
for (int j = 0; j < hSize; j++)
if (board[r][j] == currentPlayer)
count++;
else
count = 0;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Vertically for a Win
*/
for (int i = r; i < vSize; i++)
if (board[i][c] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
i = -1;
vSize = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Diagonally from Top left to Bottom right
*/
if (c - r >= 0)
int startingC;
startingC = c - r;
int size = size();
for (int i = r, j = c; j < size; i++, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (j == size() - 1)
j = startingC - 1;
i = -1;
size = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
else
int size = size();
int startingR;
startingR = r - c;
for (int i = r, j = c; i < size; i++, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
j = -1;
i = startingR - 1;
size = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Diagonally from bottom left to top right;
*/
if (r + c <= 17)
int loop = 0;
int startingR;
startingR = r + c;
for (int i = r, j = c; i >= 0; i--, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == 0 && loop == 0)
i = startingR + 1;
j = -1;
loop++;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
else if (r + c > 17)
int loop = 0;
int startingC;
startingC = (r + c) - (size() - 1);
for (int i = r, j = c; i >= startingC; i--, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == startingC && loop == 0)
i = size();
j = startingC - 1;
loop++;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
return hasWinner;
Unfortunately this method's length doesn't meet the requirement for my university: it has to be a maximum of 80 lines. I don't know how I'm supposed to shorten this code so that it still works.
java homework connect-four
add a comment |Â
up vote
3
down vote
favorite
I have a method, that checks win conditions on a "Torus" board, which is a board without any borders. This means that if you place 4 diagonal stones on the top left, and 2 diagonal stones in the bottom right, if they are in the same diagonal and would connect if you ignored the border, which then would lead to a win. Basically it's a Connect 6 Game.
size() returns the size of the board which either is 18 or 20.
currentPlayer is a String like : "P1" or "P2".
r and c are the row and column where a move has just been made.
public boolean checkTorusWinner(int r, int c)
int count = 0;
boolean hasWinner = false;
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
/*
Checks Horizontally for a Win.
*/
for (int i = c; i < hSize; i++)
if (board[r][i] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
hSize = size() - 2;
for (int j = 0; j < hSize; j++)
if (board[r][j] == currentPlayer)
count++;
else
count = 0;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Vertically for a Win
*/
for (int i = r; i < vSize; i++)
if (board[i][c] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
i = -1;
vSize = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Diagonally from Top left to Bottom right
*/
if (c - r >= 0)
int startingC;
startingC = c - r;
int size = size();
for (int i = r, j = c; j < size; i++, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (j == size() - 1)
j = startingC - 1;
i = -1;
size = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
else
int size = size();
int startingR;
startingR = r - c;
for (int i = r, j = c; i < size; i++, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
j = -1;
i = startingR - 1;
size = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Diagonally from bottom left to top right;
*/
if (r + c <= 17)
int loop = 0;
int startingR;
startingR = r + c;
for (int i = r, j = c; i >= 0; i--, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == 0 && loop == 0)
i = startingR + 1;
j = -1;
loop++;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
else if (r + c > 17)
int loop = 0;
int startingC;
startingC = (r + c) - (size() - 1);
for (int i = r, j = c; i >= startingC; i--, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == startingC && loop == 0)
i = size();
j = startingC - 1;
loop++;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
return hasWinner;
Unfortunately this method's length doesn't meet the requirement for my university: it has to be a maximum of 80 lines. I don't know how I'm supposed to shorten this code so that it still works.
java homework connect-four
1
for the record... are you mandated to solve the problem in a single method?
â Vogel612â¦
Mar 3 at 18:39
I think it is shorter to write a method that ignores which was the last move and just loops the entire board to find any winning combination, and if so, by which player.
â JanErikGunnar
Mar 3 at 20:00
This doesn't look like it returns the correct result. Have you checked it? In particular, what happens if the newest piece is in the middle of a horizontal sequence?
â mdfst13
Mar 3 at 23:28
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I have a method, that checks win conditions on a "Torus" board, which is a board without any borders. This means that if you place 4 diagonal stones on the top left, and 2 diagonal stones in the bottom right, if they are in the same diagonal and would connect if you ignored the border, which then would lead to a win. Basically it's a Connect 6 Game.
size() returns the size of the board which either is 18 or 20.
currentPlayer is a String like : "P1" or "P2".
r and c are the row and column where a move has just been made.
public boolean checkTorusWinner(int r, int c)
int count = 0;
boolean hasWinner = false;
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
/*
Checks Horizontally for a Win.
*/
for (int i = c; i < hSize; i++)
if (board[r][i] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
hSize = size() - 2;
for (int j = 0; j < hSize; j++)
if (board[r][j] == currentPlayer)
count++;
else
count = 0;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Vertically for a Win
*/
for (int i = r; i < vSize; i++)
if (board[i][c] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
i = -1;
vSize = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Diagonally from Top left to Bottom right
*/
if (c - r >= 0)
int startingC;
startingC = c - r;
int size = size();
for (int i = r, j = c; j < size; i++, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (j == size() - 1)
j = startingC - 1;
i = -1;
size = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
else
int size = size();
int startingR;
startingR = r - c;
for (int i = r, j = c; i < size; i++, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
j = -1;
i = startingR - 1;
size = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Diagonally from bottom left to top right;
*/
if (r + c <= 17)
int loop = 0;
int startingR;
startingR = r + c;
for (int i = r, j = c; i >= 0; i--, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == 0 && loop == 0)
i = startingR + 1;
j = -1;
loop++;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
else if (r + c > 17)
int loop = 0;
int startingC;
startingC = (r + c) - (size() - 1);
for (int i = r, j = c; i >= startingC; i--, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == startingC && loop == 0)
i = size();
j = startingC - 1;
loop++;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
return hasWinner;
Unfortunately this method's length doesn't meet the requirement for my university: it has to be a maximum of 80 lines. I don't know how I'm supposed to shorten this code so that it still works.
java homework connect-four
I have a method, that checks win conditions on a "Torus" board, which is a board without any borders. This means that if you place 4 diagonal stones on the top left, and 2 diagonal stones in the bottom right, if they are in the same diagonal and would connect if you ignored the border, which then would lead to a win. Basically it's a Connect 6 Game.
size() returns the size of the board which either is 18 or 20.
currentPlayer is a String like : "P1" or "P2".
r and c are the row and column where a move has just been made.
public boolean checkTorusWinner(int r, int c)
int count = 0;
boolean hasWinner = false;
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
/*
Checks Horizontally for a Win.
*/
for (int i = c; i < hSize; i++)
if (board[r][i] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
hSize = size() - 2;
for (int j = 0; j < hSize; j++)
if (board[r][j] == currentPlayer)
count++;
else
count = 0;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Vertically for a Win
*/
for (int i = r; i < vSize; i++)
if (board[i][c] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
i = -1;
vSize = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Diagonally from Top left to Bottom right
*/
if (c - r >= 0)
int startingC;
startingC = c - r;
int size = size();
for (int i = r, j = c; j < size; i++, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (j == size() - 1)
j = startingC - 1;
i = -1;
size = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
else
int size = size();
int startingR;
startingR = r - c;
for (int i = r, j = c; i < size; i++, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == size() - 1)
j = -1;
i = startingR - 1;
size = size() - 2;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
/*
Checks Diagonally from bottom left to top right;
*/
if (r + c <= 17)
int loop = 0;
int startingR;
startingR = r + c;
for (int i = r, j = c; i >= 0; i--, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == 0 && loop == 0)
i = startingR + 1;
j = -1;
loop++;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
else if (r + c > 17)
int loop = 0;
int startingC;
startingC = (r + c) - (size() - 1);
for (int i = r, j = c; i >= startingC; i--, j++)
if (board[i][j] == currentPlayer)
count++;
else
count = 0;
if (i == startingC && loop == 0)
i = size();
j = startingC - 1;
loop++;
if (count == 6)
boardType = "none";
hasWinner = true;
break;
return hasWinner;
Unfortunately this method's length doesn't meet the requirement for my university: it has to be a maximum of 80 lines. I don't know how I'm supposed to shorten this code so that it still works.
java homework connect-four
edited Mar 3 at 23:09
mdfst13
16.8k42055
16.8k42055
asked Mar 3 at 14:32
Gilles Chen
163
163
1
for the record... are you mandated to solve the problem in a single method?
â Vogel612â¦
Mar 3 at 18:39
I think it is shorter to write a method that ignores which was the last move and just loops the entire board to find any winning combination, and if so, by which player.
â JanErikGunnar
Mar 3 at 20:00
This doesn't look like it returns the correct result. Have you checked it? In particular, what happens if the newest piece is in the middle of a horizontal sequence?
â mdfst13
Mar 3 at 23:28
add a comment |Â
1
for the record... are you mandated to solve the problem in a single method?
â Vogel612â¦
Mar 3 at 18:39
I think it is shorter to write a method that ignores which was the last move and just loops the entire board to find any winning combination, and if so, by which player.
â JanErikGunnar
Mar 3 at 20:00
This doesn't look like it returns the correct result. Have you checked it? In particular, what happens if the newest piece is in the middle of a horizontal sequence?
â mdfst13
Mar 3 at 23:28
1
1
for the record... are you mandated to solve the problem in a single method?
â Vogel612â¦
Mar 3 at 18:39
for the record... are you mandated to solve the problem in a single method?
â Vogel612â¦
Mar 3 at 18:39
I think it is shorter to write a method that ignores which was the last move and just loops the entire board to find any winning combination, and if so, by which player.
â JanErikGunnar
Mar 3 at 20:00
I think it is shorter to write a method that ignores which was the last move and just loops the entire board to find any winning combination, and if so, by which player.
â JanErikGunnar
Mar 3 at 20:00
This doesn't look like it returns the correct result. Have you checked it? In particular, what happens if the newest piece is in the middle of a horizontal sequence?
â mdfst13
Mar 3 at 23:28
This doesn't look like it returns the correct result. Have you checked it? In particular, what happens if the newest piece is in the middle of a horizontal sequence?
â mdfst13
Mar 3 at 23:28
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
2
down vote
Thanks for sharing your code.
Your code is a procedural approach to the problem.
There is nothing wrong with procedural approaches in general, but Java is an object oriented (OO) programming language and if you want to become a good Java programmer then you should start solving problems in an OO way.
But OOP doesn't mean to "split up" code into random classes.
The ultimate goal of OOP is to reduce code duplication, improve readability and support reuse as well as extending the code.
Doing OOP means that you follow certain principles which are (among others):
- information hiding / encapsulation
- single responsibility
- separation of concerns
- KISS (Keep it simple (and) stupid.)
- DRY (Don't repeat yourself.)
- "Tell! Don't ask."
- Law of demeter ("Don't talk to strangers!")
How might that help to improve your code?
From an OO point of view you have the current position and you have to check if that position is part of a line of at least 5 other (excluding itself) equal elements.
The first implication is that you only have to look at the current positions neighbors and that there is no need to scan the whole board.
The easieast way is to go in each direction and count the consecutive neighbors belonging to the current player. Afterwards you add the opposit directions and check the sum.
I use a trick to safely calculate an index in "wrap around" arrays:
(arrayLength + currentIndex + differece) % arrayLength
where % is the modulo operator.
Here is how I would implement that:
class FiledPosition
final int r, c;
FiledPosition(int r, int c)
this.r=r;
this.c=c;
interface NeighborCalculator
FiledPosition getFor(FiledPosition current);
}
enum Direction NORTH,NORTH_EAST,EAST,SOUTH_EAST,SOUTH,SOUTH_WEST,WEST,NORTH_WEST
the code above may live in separate classes. What follows must be in your solution class
private final Direction opposits = new Direction
NORTH,SOUTH,
NORTH_EAST,SOUTH_WEST,
NORTH_WEST,SOUTH_EAST,
EAST,WEST
private final int WIN_COUNT_EXCLUDUNG_CURRENT = 5;
Map<Direction, NeighborCalculator> neigborSelector = new HashMap<>();
public boolean checkTorusWinner(int r, int c)
neigborSelector.put(NORTH, new NeighborCalculator() // pre java8 anonymous inner class
public FiledPosition getFor(FiledPosition currentPoint )
return new Point((vSize+currentPoint.r-1)%vSize, currentPoint.c));
);
neigborSelector.put(NORTH_EAST,currentPoint -> new Point((vSize+currentPoint.r-1)%vSize, (hSize+currentPoint.c+1)%hSize)); // java8 lambda
neigborSelector.put(EAST,currentPoint -> new Point(currentPoint.r, (hSize+currentPoint.c+1)%hSize));
neigborSelector.put(SOUTH_EAST,currentPoint -> new Point((vSize+currentPoint.r+1)%vSize, (hSize+currentPoint.c+1)%hSize));
// similar for all directions, should be in the classes constructor.
Map<Direction, Counter> lineSectionCounts = new HashMap<>();
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
// count consecutive same in each direction without current
for(Direction direction : Direction.values())
int consecutiveSame = 0;
FiledPosition neigborPosition = neigborSelector.get(direction).getFor(new FiledPosition(r,c));
while(currentPlayer.equals(board[neigborPosition.r][neigborPosition.c]))
consecutiveSame++;
neigborPosition = neigborSelector.get(direction).getFor(neigborPosition);
lineSectionCounts.put(consecutiveSame); // auto boxed
// sum up opposit directions
for(Direction opposit : opposits)
if(WIN_COUNT_EXCLUDUNG_CURRENT < lineSectionCounts.get(oposit[0]) + lineSectionCounts.get(oposit[1])) // auto unbox
return true; // current Player won.
return false; // no winner yet
This complete code has 57 lines (24 without the configuration). There are 4 lines missing to completly configure neigborSelector map (if you use jav8 lambdas).
This code uses basic Java concepts like classes, interfaces and enums you should already have heared of.
This solution has 8 repetitions of code where the only difference is the -1, 0, +1. Additionally, since SOUTH is basically "NEGATIVE NORTH", defining SOUTH is effectively duplication of NORTH. I think it would be more DRY to have the four "real" directions (horizontal, vertical, diagonal forward, diagonal backward) as small objects only containing the "x-delta" and "y-delta" (1,0, 0,1, 1,1, 1,-1). Then the code (or a method on the direction class) can just negate both values to get the opposite direction where needed.
â JanErikGunnar
Mar 5 at 12:46
Additionally, WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable.
â JanErikGunnar
Mar 5 at 12:46
@JanErikGunnar "WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable"WIN_COUNT_EXCLUDUNG_CURRENTis an implementation detail but in OOP we reuse behavior, not code.
â Timothy Truckle
Mar 5 at 12:56
1
Fair enough, although I disagree :)
â JanErikGunnar
Mar 5 at 13:10
1
It's a big world with room for more than one way to look at it... ;o)
â Timothy Truckle
Mar 5 at 13:11
 |Â
show 6 more comments
up vote
0
down vote
Some tips:
obviously, break into smaller methods if allowed
There are many magic numbers and strings. 17? 6? "none"? Put them in variables or constants to make the code more readable and easier to adjust.
you are changing hSize value within a loop where hSize is the bound of the loop. This is very error prone!
hasWinner = true; break; can be replaced by return true;
modulo operator is fantastic for "looping" arrays. Example:
length = 18;
position = 17;
array[(position) % length] == array[(position+1) % length]
This will compare position 17 with position 0.code can probably be simplified and more generic by taking less regard to the position of the last move.
the method sets board type to "none". I assume this resets the board. This makes the name of the method (checkTorusWinner) missleading
pseudo code for very easy approach
For each x:
For each y:
Set xwin = ywin = diagFwdWin = diagBackwdWin = true.
For each n = 1... winLength-1:
If board [x] [y] != board [(x+n) % boardwidth] [y] then
Xwin =false
End if
// Same if, but instead, y+n % boardheight, Ywin
// same if, but both x+n AND y+n, diagbackwdWin
// same if, but both x+n and y MINUS n, diagfwdWin
End for
If Xwin or ywin or diagFwdWin or diagBackwdWin == true then
Return true
End if
End for
End for
Return false
For better performance, x and y in outer loop can be limited to position of last added +/- winLength
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
Thanks for sharing your code.
Your code is a procedural approach to the problem.
There is nothing wrong with procedural approaches in general, but Java is an object oriented (OO) programming language and if you want to become a good Java programmer then you should start solving problems in an OO way.
But OOP doesn't mean to "split up" code into random classes.
The ultimate goal of OOP is to reduce code duplication, improve readability and support reuse as well as extending the code.
Doing OOP means that you follow certain principles which are (among others):
- information hiding / encapsulation
- single responsibility
- separation of concerns
- KISS (Keep it simple (and) stupid.)
- DRY (Don't repeat yourself.)
- "Tell! Don't ask."
- Law of demeter ("Don't talk to strangers!")
How might that help to improve your code?
From an OO point of view you have the current position and you have to check if that position is part of a line of at least 5 other (excluding itself) equal elements.
The first implication is that you only have to look at the current positions neighbors and that there is no need to scan the whole board.
The easieast way is to go in each direction and count the consecutive neighbors belonging to the current player. Afterwards you add the opposit directions and check the sum.
I use a trick to safely calculate an index in "wrap around" arrays:
(arrayLength + currentIndex + differece) % arrayLength
where % is the modulo operator.
Here is how I would implement that:
class FiledPosition
final int r, c;
FiledPosition(int r, int c)
this.r=r;
this.c=c;
interface NeighborCalculator
FiledPosition getFor(FiledPosition current);
}
enum Direction NORTH,NORTH_EAST,EAST,SOUTH_EAST,SOUTH,SOUTH_WEST,WEST,NORTH_WEST
the code above may live in separate classes. What follows must be in your solution class
private final Direction opposits = new Direction
NORTH,SOUTH,
NORTH_EAST,SOUTH_WEST,
NORTH_WEST,SOUTH_EAST,
EAST,WEST
private final int WIN_COUNT_EXCLUDUNG_CURRENT = 5;
Map<Direction, NeighborCalculator> neigborSelector = new HashMap<>();
public boolean checkTorusWinner(int r, int c)
neigborSelector.put(NORTH, new NeighborCalculator() // pre java8 anonymous inner class
public FiledPosition getFor(FiledPosition currentPoint )
return new Point((vSize+currentPoint.r-1)%vSize, currentPoint.c));
);
neigborSelector.put(NORTH_EAST,currentPoint -> new Point((vSize+currentPoint.r-1)%vSize, (hSize+currentPoint.c+1)%hSize)); // java8 lambda
neigborSelector.put(EAST,currentPoint -> new Point(currentPoint.r, (hSize+currentPoint.c+1)%hSize));
neigborSelector.put(SOUTH_EAST,currentPoint -> new Point((vSize+currentPoint.r+1)%vSize, (hSize+currentPoint.c+1)%hSize));
// similar for all directions, should be in the classes constructor.
Map<Direction, Counter> lineSectionCounts = new HashMap<>();
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
// count consecutive same in each direction without current
for(Direction direction : Direction.values())
int consecutiveSame = 0;
FiledPosition neigborPosition = neigborSelector.get(direction).getFor(new FiledPosition(r,c));
while(currentPlayer.equals(board[neigborPosition.r][neigborPosition.c]))
consecutiveSame++;
neigborPosition = neigborSelector.get(direction).getFor(neigborPosition);
lineSectionCounts.put(consecutiveSame); // auto boxed
// sum up opposit directions
for(Direction opposit : opposits)
if(WIN_COUNT_EXCLUDUNG_CURRENT < lineSectionCounts.get(oposit[0]) + lineSectionCounts.get(oposit[1])) // auto unbox
return true; // current Player won.
return false; // no winner yet
This complete code has 57 lines (24 without the configuration). There are 4 lines missing to completly configure neigborSelector map (if you use jav8 lambdas).
This code uses basic Java concepts like classes, interfaces and enums you should already have heared of.
This solution has 8 repetitions of code where the only difference is the -1, 0, +1. Additionally, since SOUTH is basically "NEGATIVE NORTH", defining SOUTH is effectively duplication of NORTH. I think it would be more DRY to have the four "real" directions (horizontal, vertical, diagonal forward, diagonal backward) as small objects only containing the "x-delta" and "y-delta" (1,0, 0,1, 1,1, 1,-1). Then the code (or a method on the direction class) can just negate both values to get the opposite direction where needed.
â JanErikGunnar
Mar 5 at 12:46
Additionally, WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable.
â JanErikGunnar
Mar 5 at 12:46
@JanErikGunnar "WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable"WIN_COUNT_EXCLUDUNG_CURRENTis an implementation detail but in OOP we reuse behavior, not code.
â Timothy Truckle
Mar 5 at 12:56
1
Fair enough, although I disagree :)
â JanErikGunnar
Mar 5 at 13:10
1
It's a big world with room for more than one way to look at it... ;o)
â Timothy Truckle
Mar 5 at 13:11
 |Â
show 6 more comments
up vote
2
down vote
Thanks for sharing your code.
Your code is a procedural approach to the problem.
There is nothing wrong with procedural approaches in general, but Java is an object oriented (OO) programming language and if you want to become a good Java programmer then you should start solving problems in an OO way.
But OOP doesn't mean to "split up" code into random classes.
The ultimate goal of OOP is to reduce code duplication, improve readability and support reuse as well as extending the code.
Doing OOP means that you follow certain principles which are (among others):
- information hiding / encapsulation
- single responsibility
- separation of concerns
- KISS (Keep it simple (and) stupid.)
- DRY (Don't repeat yourself.)
- "Tell! Don't ask."
- Law of demeter ("Don't talk to strangers!")
How might that help to improve your code?
From an OO point of view you have the current position and you have to check if that position is part of a line of at least 5 other (excluding itself) equal elements.
The first implication is that you only have to look at the current positions neighbors and that there is no need to scan the whole board.
The easieast way is to go in each direction and count the consecutive neighbors belonging to the current player. Afterwards you add the opposit directions and check the sum.
I use a trick to safely calculate an index in "wrap around" arrays:
(arrayLength + currentIndex + differece) % arrayLength
where % is the modulo operator.
Here is how I would implement that:
class FiledPosition
final int r, c;
FiledPosition(int r, int c)
this.r=r;
this.c=c;
interface NeighborCalculator
FiledPosition getFor(FiledPosition current);
}
enum Direction NORTH,NORTH_EAST,EAST,SOUTH_EAST,SOUTH,SOUTH_WEST,WEST,NORTH_WEST
the code above may live in separate classes. What follows must be in your solution class
private final Direction opposits = new Direction
NORTH,SOUTH,
NORTH_EAST,SOUTH_WEST,
NORTH_WEST,SOUTH_EAST,
EAST,WEST
private final int WIN_COUNT_EXCLUDUNG_CURRENT = 5;
Map<Direction, NeighborCalculator> neigborSelector = new HashMap<>();
public boolean checkTorusWinner(int r, int c)
neigborSelector.put(NORTH, new NeighborCalculator() // pre java8 anonymous inner class
public FiledPosition getFor(FiledPosition currentPoint )
return new Point((vSize+currentPoint.r-1)%vSize, currentPoint.c));
);
neigborSelector.put(NORTH_EAST,currentPoint -> new Point((vSize+currentPoint.r-1)%vSize, (hSize+currentPoint.c+1)%hSize)); // java8 lambda
neigborSelector.put(EAST,currentPoint -> new Point(currentPoint.r, (hSize+currentPoint.c+1)%hSize));
neigborSelector.put(SOUTH_EAST,currentPoint -> new Point((vSize+currentPoint.r+1)%vSize, (hSize+currentPoint.c+1)%hSize));
// similar for all directions, should be in the classes constructor.
Map<Direction, Counter> lineSectionCounts = new HashMap<>();
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
// count consecutive same in each direction without current
for(Direction direction : Direction.values())
int consecutiveSame = 0;
FiledPosition neigborPosition = neigborSelector.get(direction).getFor(new FiledPosition(r,c));
while(currentPlayer.equals(board[neigborPosition.r][neigborPosition.c]))
consecutiveSame++;
neigborPosition = neigborSelector.get(direction).getFor(neigborPosition);
lineSectionCounts.put(consecutiveSame); // auto boxed
// sum up opposit directions
for(Direction opposit : opposits)
if(WIN_COUNT_EXCLUDUNG_CURRENT < lineSectionCounts.get(oposit[0]) + lineSectionCounts.get(oposit[1])) // auto unbox
return true; // current Player won.
return false; // no winner yet
This complete code has 57 lines (24 without the configuration). There are 4 lines missing to completly configure neigborSelector map (if you use jav8 lambdas).
This code uses basic Java concepts like classes, interfaces and enums you should already have heared of.
This solution has 8 repetitions of code where the only difference is the -1, 0, +1. Additionally, since SOUTH is basically "NEGATIVE NORTH", defining SOUTH is effectively duplication of NORTH. I think it would be more DRY to have the four "real" directions (horizontal, vertical, diagonal forward, diagonal backward) as small objects only containing the "x-delta" and "y-delta" (1,0, 0,1, 1,1, 1,-1). Then the code (or a method on the direction class) can just negate both values to get the opposite direction where needed.
â JanErikGunnar
Mar 5 at 12:46
Additionally, WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable.
â JanErikGunnar
Mar 5 at 12:46
@JanErikGunnar "WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable"WIN_COUNT_EXCLUDUNG_CURRENTis an implementation detail but in OOP we reuse behavior, not code.
â Timothy Truckle
Mar 5 at 12:56
1
Fair enough, although I disagree :)
â JanErikGunnar
Mar 5 at 13:10
1
It's a big world with room for more than one way to look at it... ;o)
â Timothy Truckle
Mar 5 at 13:11
 |Â
show 6 more comments
up vote
2
down vote
up vote
2
down vote
Thanks for sharing your code.
Your code is a procedural approach to the problem.
There is nothing wrong with procedural approaches in general, but Java is an object oriented (OO) programming language and if you want to become a good Java programmer then you should start solving problems in an OO way.
But OOP doesn't mean to "split up" code into random classes.
The ultimate goal of OOP is to reduce code duplication, improve readability and support reuse as well as extending the code.
Doing OOP means that you follow certain principles which are (among others):
- information hiding / encapsulation
- single responsibility
- separation of concerns
- KISS (Keep it simple (and) stupid.)
- DRY (Don't repeat yourself.)
- "Tell! Don't ask."
- Law of demeter ("Don't talk to strangers!")
How might that help to improve your code?
From an OO point of view you have the current position and you have to check if that position is part of a line of at least 5 other (excluding itself) equal elements.
The first implication is that you only have to look at the current positions neighbors and that there is no need to scan the whole board.
The easieast way is to go in each direction and count the consecutive neighbors belonging to the current player. Afterwards you add the opposit directions and check the sum.
I use a trick to safely calculate an index in "wrap around" arrays:
(arrayLength + currentIndex + differece) % arrayLength
where % is the modulo operator.
Here is how I would implement that:
class FiledPosition
final int r, c;
FiledPosition(int r, int c)
this.r=r;
this.c=c;
interface NeighborCalculator
FiledPosition getFor(FiledPosition current);
}
enum Direction NORTH,NORTH_EAST,EAST,SOUTH_EAST,SOUTH,SOUTH_WEST,WEST,NORTH_WEST
the code above may live in separate classes. What follows must be in your solution class
private final Direction opposits = new Direction
NORTH,SOUTH,
NORTH_EAST,SOUTH_WEST,
NORTH_WEST,SOUTH_EAST,
EAST,WEST
private final int WIN_COUNT_EXCLUDUNG_CURRENT = 5;
Map<Direction, NeighborCalculator> neigborSelector = new HashMap<>();
public boolean checkTorusWinner(int r, int c)
neigborSelector.put(NORTH, new NeighborCalculator() // pre java8 anonymous inner class
public FiledPosition getFor(FiledPosition currentPoint )
return new Point((vSize+currentPoint.r-1)%vSize, currentPoint.c));
);
neigborSelector.put(NORTH_EAST,currentPoint -> new Point((vSize+currentPoint.r-1)%vSize, (hSize+currentPoint.c+1)%hSize)); // java8 lambda
neigborSelector.put(EAST,currentPoint -> new Point(currentPoint.r, (hSize+currentPoint.c+1)%hSize));
neigborSelector.put(SOUTH_EAST,currentPoint -> new Point((vSize+currentPoint.r+1)%vSize, (hSize+currentPoint.c+1)%hSize));
// similar for all directions, should be in the classes constructor.
Map<Direction, Counter> lineSectionCounts = new HashMap<>();
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
// count consecutive same in each direction without current
for(Direction direction : Direction.values())
int consecutiveSame = 0;
FiledPosition neigborPosition = neigborSelector.get(direction).getFor(new FiledPosition(r,c));
while(currentPlayer.equals(board[neigborPosition.r][neigborPosition.c]))
consecutiveSame++;
neigborPosition = neigborSelector.get(direction).getFor(neigborPosition);
lineSectionCounts.put(consecutiveSame); // auto boxed
// sum up opposit directions
for(Direction opposit : opposits)
if(WIN_COUNT_EXCLUDUNG_CURRENT < lineSectionCounts.get(oposit[0]) + lineSectionCounts.get(oposit[1])) // auto unbox
return true; // current Player won.
return false; // no winner yet
This complete code has 57 lines (24 without the configuration). There are 4 lines missing to completly configure neigborSelector map (if you use jav8 lambdas).
This code uses basic Java concepts like classes, interfaces and enums you should already have heared of.
Thanks for sharing your code.
Your code is a procedural approach to the problem.
There is nothing wrong with procedural approaches in general, but Java is an object oriented (OO) programming language and if you want to become a good Java programmer then you should start solving problems in an OO way.
But OOP doesn't mean to "split up" code into random classes.
The ultimate goal of OOP is to reduce code duplication, improve readability and support reuse as well as extending the code.
Doing OOP means that you follow certain principles which are (among others):
- information hiding / encapsulation
- single responsibility
- separation of concerns
- KISS (Keep it simple (and) stupid.)
- DRY (Don't repeat yourself.)
- "Tell! Don't ask."
- Law of demeter ("Don't talk to strangers!")
How might that help to improve your code?
From an OO point of view you have the current position and you have to check if that position is part of a line of at least 5 other (excluding itself) equal elements.
The first implication is that you only have to look at the current positions neighbors and that there is no need to scan the whole board.
The easieast way is to go in each direction and count the consecutive neighbors belonging to the current player. Afterwards you add the opposit directions and check the sum.
I use a trick to safely calculate an index in "wrap around" arrays:
(arrayLength + currentIndex + differece) % arrayLength
where % is the modulo operator.
Here is how I would implement that:
class FiledPosition
final int r, c;
FiledPosition(int r, int c)
this.r=r;
this.c=c;
interface NeighborCalculator
FiledPosition getFor(FiledPosition current);
}
enum Direction NORTH,NORTH_EAST,EAST,SOUTH_EAST,SOUTH,SOUTH_WEST,WEST,NORTH_WEST
the code above may live in separate classes. What follows must be in your solution class
private final Direction opposits = new Direction
NORTH,SOUTH,
NORTH_EAST,SOUTH_WEST,
NORTH_WEST,SOUTH_EAST,
EAST,WEST
private final int WIN_COUNT_EXCLUDUNG_CURRENT = 5;
Map<Direction, NeighborCalculator> neigborSelector = new HashMap<>();
public boolean checkTorusWinner(int r, int c)
neigborSelector.put(NORTH, new NeighborCalculator() // pre java8 anonymous inner class
public FiledPosition getFor(FiledPosition currentPoint )
return new Point((vSize+currentPoint.r-1)%vSize, currentPoint.c));
);
neigborSelector.put(NORTH_EAST,currentPoint -> new Point((vSize+currentPoint.r-1)%vSize, (hSize+currentPoint.c+1)%hSize)); // java8 lambda
neigborSelector.put(EAST,currentPoint -> new Point(currentPoint.r, (hSize+currentPoint.c+1)%hSize));
neigborSelector.put(SOUTH_EAST,currentPoint -> new Point((vSize+currentPoint.r+1)%vSize, (hSize+currentPoint.c+1)%hSize));
// similar for all directions, should be in the classes constructor.
Map<Direction, Counter> lineSectionCounts = new HashMap<>();
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
// count consecutive same in each direction without current
for(Direction direction : Direction.values())
int consecutiveSame = 0;
FiledPosition neigborPosition = neigborSelector.get(direction).getFor(new FiledPosition(r,c));
while(currentPlayer.equals(board[neigborPosition.r][neigborPosition.c]))
consecutiveSame++;
neigborPosition = neigborSelector.get(direction).getFor(neigborPosition);
lineSectionCounts.put(consecutiveSame); // auto boxed
// sum up opposit directions
for(Direction opposit : opposits)
if(WIN_COUNT_EXCLUDUNG_CURRENT < lineSectionCounts.get(oposit[0]) + lineSectionCounts.get(oposit[1])) // auto unbox
return true; // current Player won.
return false; // no winner yet
This complete code has 57 lines (24 without the configuration). There are 4 lines missing to completly configure neigborSelector map (if you use jav8 lambdas).
This code uses basic Java concepts like classes, interfaces and enums you should already have heared of.
edited Mar 5 at 8:44
answered Mar 5 at 8:01
Timothy Truckle
4,673316
4,673316
This solution has 8 repetitions of code where the only difference is the -1, 0, +1. Additionally, since SOUTH is basically "NEGATIVE NORTH", defining SOUTH is effectively duplication of NORTH. I think it would be more DRY to have the four "real" directions (horizontal, vertical, diagonal forward, diagonal backward) as small objects only containing the "x-delta" and "y-delta" (1,0, 0,1, 1,1, 1,-1). Then the code (or a method on the direction class) can just negate both values to get the opposite direction where needed.
â JanErikGunnar
Mar 5 at 12:46
Additionally, WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable.
â JanErikGunnar
Mar 5 at 12:46
@JanErikGunnar "WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable"WIN_COUNT_EXCLUDUNG_CURRENTis an implementation detail but in OOP we reuse behavior, not code.
â Timothy Truckle
Mar 5 at 12:56
1
Fair enough, although I disagree :)
â JanErikGunnar
Mar 5 at 13:10
1
It's a big world with room for more than one way to look at it... ;o)
â Timothy Truckle
Mar 5 at 13:11
 |Â
show 6 more comments
This solution has 8 repetitions of code where the only difference is the -1, 0, +1. Additionally, since SOUTH is basically "NEGATIVE NORTH", defining SOUTH is effectively duplication of NORTH. I think it would be more DRY to have the four "real" directions (horizontal, vertical, diagonal forward, diagonal backward) as small objects only containing the "x-delta" and "y-delta" (1,0, 0,1, 1,1, 1,-1). Then the code (or a method on the direction class) can just negate both values to get the opposite direction where needed.
â JanErikGunnar
Mar 5 at 12:46
Additionally, WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable.
â JanErikGunnar
Mar 5 at 12:46
@JanErikGunnar "WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable"WIN_COUNT_EXCLUDUNG_CURRENTis an implementation detail but in OOP we reuse behavior, not code.
â Timothy Truckle
Mar 5 at 12:56
1
Fair enough, although I disagree :)
â JanErikGunnar
Mar 5 at 13:10
1
It's a big world with room for more than one way to look at it... ;o)
â Timothy Truckle
Mar 5 at 13:11
This solution has 8 repetitions of code where the only difference is the -1, 0, +1. Additionally, since SOUTH is basically "NEGATIVE NORTH", defining SOUTH is effectively duplication of NORTH. I think it would be more DRY to have the four "real" directions (horizontal, vertical, diagonal forward, diagonal backward) as small objects only containing the "x-delta" and "y-delta" (1,0, 0,1, 1,1, 1,-1). Then the code (or a method on the direction class) can just negate both values to get the opposite direction where needed.
â JanErikGunnar
Mar 5 at 12:46
This solution has 8 repetitions of code where the only difference is the -1, 0, +1. Additionally, since SOUTH is basically "NEGATIVE NORTH", defining SOUTH is effectively duplication of NORTH. I think it would be more DRY to have the four "real" directions (horizontal, vertical, diagonal forward, diagonal backward) as small objects only containing the "x-delta" and "y-delta" (1,0, 0,1, 1,1, 1,-1). Then the code (or a method on the direction class) can just negate both values to get the opposite direction where needed.
â JanErikGunnar
Mar 5 at 12:46
Additionally, WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable.
â JanErikGunnar
Mar 5 at 12:46
Additionally, WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable.
â JanErikGunnar
Mar 5 at 12:46
@JanErikGunnar "WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable"
WIN_COUNT_EXCLUDUNG_CURRENT is an implementation detail but in OOP we reuse behavior, not code.â Timothy Truckle
Mar 5 at 12:56
@JanErikGunnar "WIN_COUNT_EXCLUDUNG_CURRENT is very specific, a WIN_COUNT (and taking -1 if "current" needs to be excluded) would be far more reusable and readable"
WIN_COUNT_EXCLUDUNG_CURRENT is an implementation detail but in OOP we reuse behavior, not code.â Timothy Truckle
Mar 5 at 12:56
1
1
Fair enough, although I disagree :)
â JanErikGunnar
Mar 5 at 13:10
Fair enough, although I disagree :)
â JanErikGunnar
Mar 5 at 13:10
1
1
It's a big world with room for more than one way to look at it... ;o)
â Timothy Truckle
Mar 5 at 13:11
It's a big world with room for more than one way to look at it... ;o)
â Timothy Truckle
Mar 5 at 13:11
 |Â
show 6 more comments
up vote
0
down vote
Some tips:
obviously, break into smaller methods if allowed
There are many magic numbers and strings. 17? 6? "none"? Put them in variables or constants to make the code more readable and easier to adjust.
you are changing hSize value within a loop where hSize is the bound of the loop. This is very error prone!
hasWinner = true; break; can be replaced by return true;
modulo operator is fantastic for "looping" arrays. Example:
length = 18;
position = 17;
array[(position) % length] == array[(position+1) % length]
This will compare position 17 with position 0.code can probably be simplified and more generic by taking less regard to the position of the last move.
the method sets board type to "none". I assume this resets the board. This makes the name of the method (checkTorusWinner) missleading
pseudo code for very easy approach
For each x:
For each y:
Set xwin = ywin = diagFwdWin = diagBackwdWin = true.
For each n = 1... winLength-1:
If board [x] [y] != board [(x+n) % boardwidth] [y] then
Xwin =false
End if
// Same if, but instead, y+n % boardheight, Ywin
// same if, but both x+n AND y+n, diagbackwdWin
// same if, but both x+n and y MINUS n, diagfwdWin
End for
If Xwin or ywin or diagFwdWin or diagBackwdWin == true then
Return true
End if
End for
End for
Return false
For better performance, x and y in outer loop can be limited to position of last added +/- winLength
add a comment |Â
up vote
0
down vote
Some tips:
obviously, break into smaller methods if allowed
There are many magic numbers and strings. 17? 6? "none"? Put them in variables or constants to make the code more readable and easier to adjust.
you are changing hSize value within a loop where hSize is the bound of the loop. This is very error prone!
hasWinner = true; break; can be replaced by return true;
modulo operator is fantastic for "looping" arrays. Example:
length = 18;
position = 17;
array[(position) % length] == array[(position+1) % length]
This will compare position 17 with position 0.code can probably be simplified and more generic by taking less regard to the position of the last move.
the method sets board type to "none". I assume this resets the board. This makes the name of the method (checkTorusWinner) missleading
pseudo code for very easy approach
For each x:
For each y:
Set xwin = ywin = diagFwdWin = diagBackwdWin = true.
For each n = 1... winLength-1:
If board [x] [y] != board [(x+n) % boardwidth] [y] then
Xwin =false
End if
// Same if, but instead, y+n % boardheight, Ywin
// same if, but both x+n AND y+n, diagbackwdWin
// same if, but both x+n and y MINUS n, diagfwdWin
End for
If Xwin or ywin or diagFwdWin or diagBackwdWin == true then
Return true
End if
End for
End for
Return false
For better performance, x and y in outer loop can be limited to position of last added +/- winLength
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Some tips:
obviously, break into smaller methods if allowed
There are many magic numbers and strings. 17? 6? "none"? Put them in variables or constants to make the code more readable and easier to adjust.
you are changing hSize value within a loop where hSize is the bound of the loop. This is very error prone!
hasWinner = true; break; can be replaced by return true;
modulo operator is fantastic for "looping" arrays. Example:
length = 18;
position = 17;
array[(position) % length] == array[(position+1) % length]
This will compare position 17 with position 0.code can probably be simplified and more generic by taking less regard to the position of the last move.
the method sets board type to "none". I assume this resets the board. This makes the name of the method (checkTorusWinner) missleading
pseudo code for very easy approach
For each x:
For each y:
Set xwin = ywin = diagFwdWin = diagBackwdWin = true.
For each n = 1... winLength-1:
If board [x] [y] != board [(x+n) % boardwidth] [y] then
Xwin =false
End if
// Same if, but instead, y+n % boardheight, Ywin
// same if, but both x+n AND y+n, diagbackwdWin
// same if, but both x+n and y MINUS n, diagfwdWin
End for
If Xwin or ywin or diagFwdWin or diagBackwdWin == true then
Return true
End if
End for
End for
Return false
For better performance, x and y in outer loop can be limited to position of last added +/- winLength
Some tips:
obviously, break into smaller methods if allowed
There are many magic numbers and strings. 17? 6? "none"? Put them in variables or constants to make the code more readable and easier to adjust.
you are changing hSize value within a loop where hSize is the bound of the loop. This is very error prone!
hasWinner = true; break; can be replaced by return true;
modulo operator is fantastic for "looping" arrays. Example:
length = 18;
position = 17;
array[(position) % length] == array[(position+1) % length]
This will compare position 17 with position 0.code can probably be simplified and more generic by taking less regard to the position of the last move.
the method sets board type to "none". I assume this resets the board. This makes the name of the method (checkTorusWinner) missleading
pseudo code for very easy approach
For each x:
For each y:
Set xwin = ywin = diagFwdWin = diagBackwdWin = true.
For each n = 1... winLength-1:
If board [x] [y] != board [(x+n) % boardwidth] [y] then
Xwin =false
End if
// Same if, but instead, y+n % boardheight, Ywin
// same if, but both x+n AND y+n, diagbackwdWin
// same if, but both x+n and y MINUS n, diagfwdWin
End for
If Xwin or ywin or diagFwdWin or diagBackwdWin == true then
Return true
End if
End for
End for
Return false
For better performance, x and y in outer loop can be limited to position of last added +/- winLength
edited Mar 4 at 10:12
answered Mar 4 at 3:10
JanErikGunnar
23616
23616
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188729%2fchecking-for-win-on-a-wrap-around-connect-6-board%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
for the record... are you mandated to solve the problem in a single method?
â Vogel612â¦
Mar 3 at 18:39
I think it is shorter to write a method that ignores which was the last move and just loops the entire board to find any winning combination, and if so, by which player.
â JanErikGunnar
Mar 3 at 20:00
This doesn't look like it returns the correct result. Have you checked it? In particular, what happens if the newest piece is in the middle of a horizontal sequence?
â mdfst13
Mar 3 at 23:28