This site requires JavaScript, please enable it in your browser!
Greenfoot back
RUMMAKER
RUMMAKER wrote ...

2013/9/6

Need help with 2D array bug?

RUMMAKER RUMMAKER

2013/9/6

#
Right, so this is a school project and we are suppose to make a grid game. I chose to make "Gomoku" which is like connect five. So this is the only problem i have with the game that i can't figure out (its a big one); There is 8 directions the stones/pieces can connect; up, down, left, right, and the four diagonals. if i place a stone from left to right, top to bottom, left-down diagonal,or right-down diagonal, it only takes 3 stones to register as a "connect 5" instead of the 5 it's suppose to be. The other four directions work fine with no bugs. the way i set up the world is using a int array i have 3 states for a point BLANK_ BLACK_ WHITE_ the way i check the stones is using this code here (I triple checked the code for all of the directions before i posted the problem here so it's probably not a +/- mistake i made) EDIT: finally figured out how to post the code in a readable manner xD the important stuff starts from line 68
public class Board extends World
{
    private final int BLANK_;
    private final int BLACK_;
    private final int WHITE_;
    public int[][] board_;
    public int x_;
    public int y_;
    public int player_;
    public Board()
    {    
        super(19, 19, 30);
        BLANK_ = 0;// no pieces on point
        BLACK_ = 1;// black piece
        WHITE_ = 2;// white piece
        board_ = new int[19][19];// a 19 by 19 Go/Gomoku board
        x_ = 0;
        y_ = 0;
        player_ = BLACK_;//black starts first
        while(x_ < 19)
        {
            board_[x_][y_] = 0;
            if(x_ == 18 && y_ < 19)//resets the loop so it runs again till all points covered
            {
                x_ = 0;
                y_ ++;
            }
            else
            {
                return;
            }
            x_++;
        }
    }
    public void act()
    {
        if(Greenfoot.getMouseInfo() != null)
        {
            if(Greenfoot.mouseClicked(this))
            {
                x_ = Greenfoot.getMouseInfo().getX();
                y_ = Greenfoot.getMouseInfo().getY();
                if(player_ == BLACK_)
                {
                    addBlack();
                }
                else
                {
                    addWhite();
                }
            }
            if(scanAll())
            {
                Message m = new Message();
                if(player_ == BLACK_)
                {
                    m.setImage("whiteWin.png");
                }
                else
                {
                    m.setImage("blackWin.png");
                }
                addObject(m, getWidth()/2, getHeight()/2);
                Greenfoot.stop();
            }
        }
    }
    public void addBlack()
    {
        if(board_[x_][y_] == BLANK_)
        {
            board_[x_][y_] = BLACK_;
            Black b = new Black();
            addObject(b, x_, y_);
            player_ = WHITE_;// switch turns
        }
    }
    public void addWhite()
    {
        if(board_[x_][y_] == BLANK_)
        {
            board_[x_][y_] = WHITE_;
            White w = new White();
            addObject(w, x_, y_);
            player_ = BLACK_;// switch turns
        }
    }
    
    public int scanUp()
    {
        if(Greenfoot.getMouseInfo() != null && Greenfoot.mouseClicked(null))//only scan when clicked
        {
            int stoneCount = 0;
            if(y_ > 0)//wether u are at edge (not at edge)
            {
                while(y_ > 0 && board_[x_][y_-1] != player_ && board_[x_][y_-1] != BLANK_)// != because the player switches when a stone is placed
                {
                    y_--;
                    stoneCount++;
                }
                return stoneCount;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    public int scanDown()
    {
        if(Greenfoot.getMouseInfo() != null && Greenfoot.mouseClicked(null))//only scan when clicked
        {
            int stoneCount = 0;
            if(y_ < getHeight()-1)// -1 because getHeight() returns amount of pixels starting from 1 not 0
            {
                while(y_ < getHeight()-1 && board_[x_][y_+1] != player_ && board_[x_][y_+1] != BLANK_)// != because the player switches when a stone is placed
                {
                    y_++;
                    stoneCount++;
                }
                return stoneCount;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    public int scanLeft()
    {
        if(Greenfoot.getMouseInfo() != null && Greenfoot.mouseClicked(null))//only scan when clicked
        {
            int stoneCount = 0;
            if(x_ > 0)
            {
                while(x_ > 0 && board_[x_-1][y_] != player_ && board_[x_-1][y_] != BLANK_)// != because the player switches when a stone is placed
                {
                    x_--;
                    stoneCount++;
                }
                return stoneCount;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    public int scanRight()
    {
        if(Greenfoot.getMouseInfo() != null && Greenfoot.mouseClicked(null))//only scan when clicked
        {
            int stoneCount = 0;
            if(x_ < getWidth()-1)
            {
                while(x_ < getWidth()-1 && board_[x_+1][y_] != player_ && board_[x_+1][y_] != BLANK_)// != because the player switches when a stone is placed
                {
                    x_++;
                    stoneCount++;
                }
                return stoneCount;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    public int scanDRU()//diagonal right up
    {
        if(Greenfoot.getMouseInfo() != null && Greenfoot.mouseClicked(null))//only scan when clicked
        {
            int stoneCount = 0;
            if(x_ < getWidth()-1 && y_ > 0)
            {
                while(x_ < getWidth()-1 && y_ > 0 && board_[x_+1][y_-1] != player_ && board_[x_+1][y_-1] != BLANK_)// != because the player switches when a stone is placed
                {
                    x_++;
                    y_--;
                    stoneCount++;
                }
                return stoneCount;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    public int scanDLU()//diagonal left up
    {
        if(Greenfoot.getMouseInfo() != null && Greenfoot.mouseClicked(null))//only scan when clicked
        {
            int stoneCount = 0;
            if(x_ > 0 && y_ > 0)
            {
                while(x_ > 0 && y_ > 0 && board_[x_-1][y_-1] != player_ && board_[x_-1][y_-1] != BLANK_)// != because the player switches when a stone is placed
                {
                    x_--;
                    y_--;
                    stoneCount++;
                }
                return stoneCount;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    public int scanDRD()//diagonal right down
    {
        if(Greenfoot.getMouseInfo() != null && Greenfoot.mouseClicked(null))//only scan when clicked
        {
            int stoneCount = 0;
            if(x_ < getWidth()-1 && y_ < getHeight()-1)
            {
                while(x_ < getWidth()-1 && y_ < getHeight()-1 && board_[x_+1][y_+1] != player_ && board_[x_+1][y_+1] != BLANK_)// != because the player switches when a stone is placed
                {
                    x_++;
                    y_++;
                    stoneCount++;
                }
                return stoneCount;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    public int scanDLD()//diagonal left down
    {
        if(Greenfoot.getMouseInfo() != null && Greenfoot.mouseClicked(null))//only scan when clicked
        {
            int stoneCount = 0;
            if(x_ > 0 && y_ < getHeight()-1)
            {
                while(x_ > 0 && y_ < getHeight()-1 && board_[x_-1][y_+1] != player_ && board_[x_-1][y_+1] != BLANK_)// != because the player switches when a stone is placed
                {
                    x_--;
                    y_++;
                    stoneCount++;
                }
                return stoneCount;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    public boolean scanAll()
    {
        if((scanUp() + scanDown() + 1) >= 5)// +1 to include center stone
        {
            return true;
        }
        else if((scanLeft() + scanRight() + 1) >= 5)// +1 to include center stone
        {
            return true;
        }
        else if((scanDLU() + scanDRD() + 1) >= 5)// +1 to include center stone
        {
            return true;
        }
        else if((scanDRU() + scanDLD() + 1) >= 5)// +1 to include center stone
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
danpost danpost

2013/9/6

#
Instead of having separate methods for 'up' and 'down', 'left' and 'right', etc., if might be easier to check the pairs together (since the sum of the same color pieces found in each set of directions need to be added with the piece just placed to check for a total of 5). Also using the 'while' loop may be very helpful here. Example:
public boolean winsVertically()
{
    int count = 1
    int y = getY();
    while (--y >= 0 && board[getX()][y] == player_) count++;
    y = getY();
    while (++y < 19 && board[getX()][y] == player_)count++;
    return count >= 5;
}
After the other three methods ('winsHorizontally', 'winsDiagonallyD' and 'winsDiagonallyU') are included, then you can check by ORing all four conditions in one 'if' statement to check if won:
if (winsHorizontally() || winsVertically() || winsDiagonallyD() || winsDiagonallyU()) gameOver();
RUMMAKER RUMMAKER

2013/9/6

#
thanks danpost, i realized i had a lot of redundant code in there and after doing what you suggested the errors are gone. But I'm still not sure why my original code had that weird bug :/, the problem is solved now but I'm still curious to know what mistakes I made in my old code so if anyone finds out go ahead and tell me.
danpost danpost

2013/9/6

#
Still trying to figure out why it was not working properly for you.
danpost danpost

2013/9/6

#
OK, I have re-created your 'weird bug'. Working on determining cause.
danpost danpost

2013/9/6

#
The reason for your 'weird bug': in your scan methods you were changing the values of x_ and y_; so secondary scan calls did not start at the last placed piece.
RUMMAKER RUMMAKER

2013/9/6

#
that makes sense
RUMMAKER RUMMAKER

2013/9/6

#
so i guess i need to keep a initial x and y and re declare my x_ and y_ to be the initial x and y everytime i scan?
danpost danpost

2013/9/6

#
Or just declare new fields each time set to x_ and y_ and use them instead of x_ and y_ (or use them as offsets from x_ and y_). Example:
private boolean winsHorizontally()
{
    int count = 1;
    int dx = 0;
    while (x_+(--dx) >= 0 && board[x_+dx][y_] == player_) count++;
    dx = 0;
    while (x_+(++dx) < 19 && board[x_+dx][y_] == player_) count++;
    return count >= 5;
}
You need to login to post a reply.