简体   繁体   中英

Java 2D Array Placing Value if Adjacent value is the same

There are some similar threads and I have tried some solutions but none are working to how my result is intended to be. I have a 2d array (Which is a game board). If i want to move a playerID to a position in the board I want to check if that position has an adjacent cell that is equal to the player ID. Otherwise it wont place it.

For example if i have a board:

[0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 2, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

If i try 1 in position [0][0] it should reject it but if i try put it in either: [0][7], [0][9], [1][6], [1][7],[1][8] (this includes diagonals).

My current code was a starting attempt I guess? But im not sure how I could do the clientID check:

public void move(int client, int x, int y) {
        int startPosX = (x - 1 < MIN_X) ? x : x-1;
        int startPosY = (y - 1 < MIN_Y) ? y : y-1;
        int endPosX =   (x + 1 > MAX_X) ? x : x+1;
        int endPosY =   (y + 1 > MAX_Y) ? y : y+1;

        for (int rowNum=startPosX; rowNum<=endPosX; rowNum++) {
            for (int colNum=startPosY; colNum<=endPosY; colNum++) {
                if (storeArray[x][y] == EMPTY && client <= 5 && client >= 1) {
                    storeArray[x][y] = client;
                    int count = totals.containsKey(client) ? totals.get(client) : 1;
                    totals.put(client, count + 1);
                }
            }
        }

So it goes through the rows and columns and if it's in any of the surrounding cells, it should place it. But I can still place it anywhere. Is my code even close to doing what it's supposed to do?

What sort of things am i missing to match my criteria and can this code be modified to make it work?

If you can't store the coordinates of clients you can modify your if statement to the following. If you can store the coordinates I would definitely use Leo Leontev's answer.

/*I removed check for client to be between 1-5, can be re-added.

I would add the checks for the desired spot being empty and the client 
being within 1-5 to the top of the method.

For loop iterates over the possible spaces where the client would be in range
check if client is in a space*/

if (storeArray[rowNum][colNum]==client) {
    //storeArray[rowNum][colNum]=0;
    storeArray[x][y] = client;
    //unchanged
    int count = totals.containsKey(client) ? totals.get(client) : 1;
    totals.put(client, count + 1);
}

You can also simplify your startX,Y, endX,Y by using Math.min and Math.max to avoid any indexOutOfBounds errors that may be caused by trying to move the client outside of the board.

int startPosX = Math.max(x-1,0);
int startPosY = Math.max(y-1,0;
int endPosX = Math.min(x+1,storeArray.length-1);
int endPosY = Math.min(y+1,storeArray[0].length-1);

If you're not doing anything after the totals.put(client,count+1); call you can add a return; statement to exit the method. If you still need to do more work you can add a label to the outer for loop and then break out of the label. Either way will stop your count from counting more than once per move.

outerloop:
for(int rowNum=startPosX;rowNum<=endPosX;rowNum++){
    for(int colNum=startPosY;colNum<=endPosY;colNum++){
        if(...){
          //code
          totals.put(client, count+1);
          break outerloop;
        }
    }
}

Here is the method as it is in my editor

public static move(int client, int x, int y){
    if(storeArray[x][y]==client)
        return;
    int startPosX = Math.max(x-1,0), startPosY=Math.max(y-1,0);
    int endPosX = Math.min(x+1,storeArray.length-1), endPosY = Math.min(y+1,storeArray[0].length-1);
    outerloop:
    for(int rowNum=startPosX;rowNum<=endPosX;rowNum++)
    {
        for(int colNum=startPosY;colNum<=endPosY;colNum++){
            if(storeArray[rowNum][colNum]==client)
            {
                storeArray[x][y]=client;
                System.out.println("Successful move");
                int count = totals.getOrDefault(client, 1);
                totals.put(client, count + 1);
                break outerloop;
                //could set colNum=endPosY+1 and rowNum=endPosX+1 if you don't want to use label/break
            }
        }
    }
}

You can use an array to store the coordinates of clients:

ArrayList<int[]> clientCoords = new ArrayList<>;

And so the move method will look like that:

public void move(int client, int x, int y) {
    int[] coords = clientCoords.get(client);
    int old_x = coords[0], old_y = coords[1];  // previous coordinates of the client
    // check that the new cell is adjacent
    if(Math.abs(x - old_x) <= 1 && Math.abs(y - old_y) <= 1){  
        clientCoords.set(client, new int[2]{x, y});
        // your code
        int count = totals.containsKey(client) ? totals.get(client) : 1;
        totals.put(client, count + 1);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM