I am having issues with trying to find a way to check all diagonal lines in the BoundedGrid for a string of 4 "discs", and the attempt at the solution I have now doesn't work at all. My attempt is in the getWinner() method. Anyone have a solution? Sorry in advance about the spacing.
import java.awt.Color;
import info.gridworld.grid.Grid;
import info.gridworld.world.World;
import info.gridworld.grid.Location;
import info.gridworld.grid.BoundedGrid;
import java.util.ArrayList;
public class ConnectFourWorld extends World<Piece>
{
private String whosTurn;
private boolean gameOver;
public ConnectFourWorld()
{
super(new BoundedGrid<Piece>(6,7));
whosTurn="Player 1";
gameOver=false;
setMessage("Welcome to CONNECT 4! - - Click a spot - "+whosTurn+" turn.");
}
public boolean locationClicked(Location loc)
{
Grid<Piece> grid = getGrid();
if(grid==null)
return false;
//if the game is over, clear the board and get ready to play a new game
if(!getWinner().equals("no winner")){
gameOver=true;
}
if(gameOver==true)
{
//clear the board
resetWorld();
gameOver=false;
setMessage("It's "+whosTurn+" click step button");
}
//this section will draw an X or an O
Piece piece = grid.get(loc);
if(whosTurn.equals("Player 1")&&piece==null)
{
add(loc,new Piece("Player 1",Color.BLACK,Color.RED));
whosTurn="Player 2";
}
else if(whosTurn.equals("Player 2")&&piece==null)
{
add(loc,new Piece("Player 2",Color.BLACK,Color.GREEN));
whosTurn="Player 1";
}
setMessage("It is " + whosTurn +"'s turn.");
if(isWorldFull()){
setMessage(getWinner() + "Click on the grid to start a new game");
}
if(!getWinner().equals("no winner")&&!getWinner().equals("cat's game - no winner!")){
setMessage(getWinner() + "Click on the grid to start a new game");
}
return true;
}
//this method will be called each time the step button is pressed
public void step()
{
if (whosTurn=="Player 1"){
whosTurn="Player 2";
}
if (whosTurn=="Player 2"){
whosTurn="Player 1";
}
}
//this method will determine if someone has won the game
public String getWinner()
{
Grid<Piece> grid = getGrid();
if(grid==null){
return "no winner";
}
//check horizontal winner
String winner="";
for (int r = 0; r<grid.getNumRows()-1; r++)
{
for(int col=0; col<grid.getNumCols()-3; col++){
Piece x =grid.get(new Location(r,col));
Piece x2 =grid.get(new Location(r,col+1));
Piece x3 =grid.get(new Location(r,col+2));
Piece x4 =grid.get(new Location(r,col+3));
if(x==null||x2==null||x3==null||x4==null)
continue;
if(x.getName().equals(x2.getName())&&x.getName().equals(x3.getName())&&x.getName().equals(x4.getName()))
winner=x.getName()+" wins horizontally!";
break;
}
}
//check for vertical winner
for (int r = 0; r<grid.getNumRows()-1; r++)
{
for(int col=0; col<grid.getNumCols()-3; col++){
Piece y =grid.get(new Location(r,col));
Piece y2 =grid.get(new Location(r+1,col));
Piece y3 =grid.get(new Location(r+2,col));
Piece y4 =grid.get(new Location(r+3,col));
if(y==null||y2==null||y3==null||y4==null)
continue;
if(y.getName().equals(y2.getName())&&y.getName().equals(y3.getName())&&y.getName().equals(y4.getName()))
winner=y.getName()+" wins vertically!";
break;
}
}
//check for low left to up right diagonal winner
for (int r = 0; r<grid.getNumRows()-3; r++)
{
for(int col=0; col<grid.getNumCols()-3; col++){
Piece z =grid.get(new Location(r,col));
Piece z2 =grid.get(new Location(r-1,col+1));
Piece z3 =grid.get(new Location(r-2,col+2));
Piece z4 =grid.get(new Location(r-3,col+3));
if(z.getName().equals(z2.getName())&&z.getName().equals(z3.getName())&&z.getName().equals(z4.getName()))
winner=z.getName()+" wins diagonally!";
}
}
//check for up left to low right winner
for (int r = grid.getNumRows()-1; r>=3; r--)
{
for(int col=0; col<grid.getNumCols()-3; col++){
Piece zz =grid.get(new Location(r,col));
Piece zz2 =grid.get(new Location(r-1,col+1));
Piece zz3 =grid.get(new Location(r-2,col+2));
Piece zz4 =grid.get(new Location(r-3,col+3));
if(zz.getName().equals(zz2.getName())&&zz.getName().equals(zz3.getName())&&zz.getName().equals(zz4.getName()))
winner=zz.getName()+" wins diagonally!";
}
}
if(isWorldFull() && winner.length()==0){
winner = "cat's game - no winner!\n\n";
}
else if(!isWorldFull() && winner.length()==0){
winner="no winner";
}
return winner;
}
//this method will determine if the board if full of Xs and Os
public boolean isWorldFull(){
//getOccupiedLocations might prove handy
ArrayList<Location> locarray = getGrid().getOccupiedLocations();
if (locarray.size()==42){
return true;
}
else{
return false;
}
}
//this method will clear the board of all Xs and Os
public void resetWorld()
{
ArrayList<Location> locarray = getGrid().getOccupiedLocations();
for(Location loc : locarray){
getGrid().remove(loc);
}
}
}
You have initialized your board as a six element array (where each element is itself an array of seven elements):
new BoundedGrid<Piece>(6,7)
(Internally, this is a two-dimensional array.)
The indexes in a six-element array are 0 through 5. Yet you are trying to access it with
grid.get(new Location(r+2,col))
Where r
ranges from 0
through 4
, as specified in your for loop:
for (int r = 0; r<grid.getNumRows()-1; r++) {
Because grid.getNumRows()-1
is 5
.
So when you attempt these lines, here are the resulting values of r
. As you can see, it goes out of bounds in many cases.
// When r is
// 0 1 2 3 4
// ---------------
Piece y =grid.get(new Location(r,col)); // 0 1 2 3 4
Piece y2 =grid.get(new Location(r+1,col)); // 1 2 3 4 5
Piece y3 =grid.get(new Location(r+2,col)); // 2 3 4 5 6
Piece y4 =grid.get(new Location(r+3,col)); // 3 4 5 6 7
There is a similar problem with these:
Piece z =grid.get(new Location(r,col));
Piece z2 =grid.get(new Location(r-1,col+1));
Piece z3 =grid.get(new Location(r-2,col+2));
Piece z4 =grid.get(new Location(r-3,col+3));
(You may also want to double check the col
indexes.)
This all assumes that Location
is accessing the elements in the BoundedGrid
object. Without knowing gridworld
, this is the best I can guess.
(I'd recommend putting comments like the above permanently in your code. Confusing code is always made a little clearer with detailed comments.)