ARTICLE AD BOX
First, let's see how to “mark” the attacked positions, to do this, we will use a method called addQueen() that receives the position of the new queen, marks it with a “1,” and then calls “8” times to setCellUnderAtack() (passing it as a parameter, the position of the queen, and an array that determines on which row/column/diagonal and in which direction it will move board), for the rest of the work.
void addQueen( int x, int y ) { board[ x ][ y ] = 1; for( int[] modifiers : jumps ) { setCellUnderAtack( x + modifiers[ 0 ], y + modifiers[ 1 ], modifiers ); } } jumps = new int[][] { // explore -> { 0, 1 }, // row right { 0, -1 }, // left { 1, 0 }, // column upwards { -1, 0 }, // below { 1, 1 }, // diagonal-rigth upwards { 1, -1 }, // below { -1, 1 }, // diagonal-left upwards { -1, -1 }, // below }; void setCellUnderAtack( int x, int y, int modifiers[] ) { for( ; isInRange( x, y ); x += modifiers[ 0 ], y += modifiers[ 1 ] ) { if( board[ x ][ y ] == 0 ) board[ x ][ y ] = 2; String key = "" + x + y; modifyEntry( key, true ); } } boolean isInRange( int x, int y ) { return x > -1 && x < 8 && y > -1 && y < 8; }Now the problems begin. What happens if I eliminate a queen? It's not as simple as marking the square as unattacked, because it may be under attack by another queen, or even several. To solve this problem, I use a Map in which the keys are the coordinates of the squares and the value is the number of attacks it receives (to simplify, the queen that is on a square does not count as an attacker). To start, we instantiate our map.
Map<String, Integer> cellsStates = new HashMap<>(); void setInicialStates() { for( int i = 0; i < 8; i ++ ) { for( int k = 0; k < 8; k++ ) { cellsStates.put( "" + i + k, 0 ); } } }If we look at the code for setCellUnderAtack(), we will see a call to modifyEntry(). This method is responsible for updating the value of the key passed as a parameter.
void modifyEntry( String key, boolean increase ) { int cellValue = cellsStates.get( key ); int newValue = cellValue; if( increase ) newValue = cellValue + 1; else if( cellValue > 0 ) newValue = cellValue - 1; cellsStates.replace( key, newValue ); }Now everything is simpler; we just have to check how many queens attack a certain position and act accordingly.
void removeQueen( int x, int y ) { int cellState = cellsStates.get( "" + x + y ); if( cellState == 0 ) board[ x ][ y ] = 0; else board[ x ][ y ] = 2; for( int[] modifiers : jumps ) { setCellReduceAtack( x + modifiers[ 0 ], y + modifiers[ 1 ], modifiers ); } } void setCellReduceAtack( int x, int y, int modifiers[] ) { for( ; isInRange( x, y ); x += modifiers[ 0 ], y += modifiers[ 1 ] ) { String key = "" + x + y; if( cellsStates.get( key ) == 1 ) board[ x ][ y ] = 0; modifyEntry( key, false ); } }We put everything together...
public class QueenProblem { Map<String, Integer> cellsStates; int board[][]; int jumps[][]; int boardSize = 8; public QueenProblem() { board = new int[ boardSize ][ boardSize ]; jumps = new int[][] { // explore -> { 0, 1 }, // row right { 0, -1 }, // left { 1, 0 }, // column upwards { -1, 0 }, // below { 1, 1 }, // diagonal-rigth upwards { 1, -1 }, // below { -1, 1 }, // diagonal-left upwards { -1, -1 }, // below }; cellsStates = new HashMap<>(); } void addQueen( int x, int y ) { board[ x ][ y ] = 1; for( int[] modifiers : jumps ) { setCellUnderAtack( x + modifiers[ 0 ], y + modifiers[ 1 ], modifiers ); } } void setCellUnderAtack( int x, int y, int modifiers[] ) { for( ; isInRange( x, y ); x += modifiers[ 0 ], y += modifiers[ 1 ] ) { if( board[ x ][ y ] == 0 ) { board[ x ][ y ] = 2; } String key = "" + x + y; modifyEntry( key, true ); } } void removeQueen( int x, int y ) { int cellState = cellsStates.get( "" + x + y ); if( cellState == 0 ) { board[ x ][ y ] = 0; } else { board[ x ][ y ] = 2; } for( int[] modifiers : jumps ) { setCellReduceAtack( x + modifiers[ 0 ], y + modifiers[ 1 ], modifiers ); } } void setCellReduceAtack( int x, int y, int modifiers[] ) { for( ; isInRange( x, y ); x += modifiers[ 0 ], y += modifiers[ 1 ] ) { String key = "" + x + y; if( cellsStates.get( key ) == 1 ) { board[ x ][ y ] = 0; } modifyEntry( key, false ); } } void modifyEntry( String key, boolean increase ) { int cellValue = cellsStates.get( key ); int newValue = cellValue; if( increase ) { newValue = cellValue + 1; } else if( cellValue > 0 ) { newValue = cellValue - 1; } cellsStates.replace( key, newValue ); } void init() { setInicialStates(); addQueen( 0, 0 ); addQueen( 7, 7 ); showBoard(); seeKeyAndValues(); removeQueen( 0, 0 ); showBoard(); } boolean isInRange( int x, int y ) { return x > -1 && x < boardSize && y > -1 && y < boardSize; } void setInicialStates() { for( int i = 0; i < boardSize; i ++ ) { for( int k = 0; k < boardSize; k ++ ) { cellsStates.put( "" + i + k, 0 ); } } } void showBoard() { for( int[] arr : board ) { for( int item : arr ) { System.out.print( item + " " ); } System.out.println(); } System.out.println(); } public static void main( String[] args ) { new QueenProblem().init(); } }