Vaguely about writing a program to place some modified pieces like a crown on an 8 x 8 board

To this question:

Supercurin is a chess piece that can move like a queen, but also like a knight. What is the maximum number of superscrapers on a chessboard 8X8 so that no one can capture another?

I want to write brute force algorithm to find the maximum. Here is what I wrote:

public class Main { public static boolean chess[][]; public static void main(String[] args) throws java.lang.Exception { chess = new boolean[8][8]; chess[0][0] = true; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { /*Loop to check various possibilities*/ if (!checkrow(i) && !checkcolumn(j) && !checkdiagonals(i, j) && !checkknight(i, j)) { if (i != 0 || j != 0) { chess[i][j] = true; } } } }/*printing the array*/ for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { System.out.print(((chess[i][j]) ? "T" : "x") + "|"); } System.out.println(); } } /*All working fine here*/ public static boolean checkrow(int a) { for (int i = 0; i < 8; i++) { if (chess[a][i]) { return true; } } return false; } /*All working fine here*/ public static boolean checkcolumn(int a) { for (int i = 0; i < 8; i++) { if (chess[i][a]) { return true; } } return false; } /*All working fine here*/ public static boolean checkdiagonals(int pi, int pj) { int i = pi - Math.min(pi, pj); int j = pj - Math.min(pi, pj); for (int k = i, l = j; k < 8 && l < 8; k++, l++) { if (chess[k][l]) { return true; } } int i_2 = pi - Math.min(pi, pj); int j_2 = pj + Math.min(pi, pj); for (int k = i_2, l = j_2; k < 8 && l > 1; k++, l--) { if (chess[k][l]) { return true; } } return false; } /*Not All working fine here try commenting out this method above so that that it doesn't run during the check*/ public static boolean checkknight(int pi, int pj) { for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (0 <= pi + 2 * i && pi + 2 * i <= 8 && 0 <= pj + j && pj + j <= 8) { if (chess[pi + 2 * i][pj + j]) { return true; } } if (0 <= pi + i && pi + i <= 8 && 0 <= pj + 2 * j && pj + 2 * j <= 8) { if (chess[pi + i][pj + 2 * i]) { return true; } } } } return false; } } 

I have two questions:

  • My checkknight algorithm looks for all knight positions, right? or there is some coding error. Everything works fine when I comment on this and I get a good solution.
  • Secondly, this will lead to only one solution. For other solutions, I have to shift (or change position) the other parts by bits after each mega-cycle, I am confused about its implementation. My instincts tell me that I need to change all the code. Is there a modification or way to do this?

Additional thoughts: I think that we would add a counter every time we put a piece and add to a long array, and output a maximum and an array after storing the corresponding data.

Code Location: You can view / edit / use fork / upload it to http://ideone.com/gChD8a

+6
source share
3 answers

This is a crude brute force method starting in the opposite direction, i.e. from the allowed figure eight puzzle. This will allow us to find a bunch of viable solutions.

The brute force method for moving from one super-sine to a potentially 8 seems especially difficult due to the knight's bypass. Based on the runs, about 60% of the viable paths for normal queens are invalid with superqueens. Therefore, if we instead used the brute forces of ordinary queens and then worked in the opposite direction, this is a potential time to find a solution, and we can better determine the lead time. Because we know that normal ladies are easier.

We will start with 12 fundamental solutions, and we will use them as input. The solution to ordinary queens is beyond this, but there is a fantastic article on the wiki page describing everything.

In my case, I saved them as Lines representing the coordinate of the queen (rows are indices).

So: "17468253" = A1, B7, C4, D6, E8, F2, G5, H3

By pushing the opposite direction from the decided queen, we need to test a maximum of 12 x 8! possible solutions. Since order does not matter, further optimization is possible by eliminating duplicate boards and processing solutions.

First up, checkKnight, which seems to be a source of confusion. Using absolute values, you can intelligently determine if a unit is within the range of the knights by checking if the offset X is equal to 2 and the offset Y is 1 or vice versa. You made the sophisticated checkKnight function to check each individual location and regardless of whether the fragment is on the border. Working with a different path, showing each queen to each other queens, is logically simpler and less of a nightmare for debugging.

Queen class

 public class Queen { int i, j; public Queen(int i, int j) { this.i = i; this.j = j; } public boolean checkKnight(Queen queen) { // if any queen meets another // queen at 2 and 1 offset, we // eliminate it. return (Math.abs(i - queen.i) == 2 && Math.abs(j - queen.j) == 1) || (Math.abs(i - queen.i) == 1 && Math.abs(j - queen.j) == 2); } } 

This board has been modified since my publication. It takes a String input and converts it into a complete chessboard. This has little work on a potential board of any size, but right now it is working on creating a daughter board. When a daughterboard is created, queens are passed by reference, rather than creating an entirely new set of queens. A total of 96 queens are stored in memory, 1 for each of the 12-card solutions. Not perfectly optimized, but better 96 β†’ 672 β†’ 4032 β†’ ...

Board Class

 public class Board { static int boardSize = 8; ArrayList<Queen> queens = new ArrayList<Queen>(); public Board(String s) { for (int i = 0; i < s.length(); i++) { queens.add(new Queen(i, s.charAt(i) - 49)); // you could implement // base 16 here, for // example, for a 15x15 // board } } public Board(Board b) { // duplicates the board, but keeps references to // queens to conserve memory, only 96 total queens // in existence through search! for (Queen q : b.queens) { queens.add(q); } } public boolean checkForImpact() { for (int i = 0; i < queens.size(); i++) { for (int j = i + 1; j < queens.size(); j++) { if (queens.get(i).checkKnight(queens.get(j))) { // just check // for any // queens // intersecting, // one hit is // enough return true; } } } return false; } public ArrayList<Board> getChildBoards() { // create child boards with a // single queen removed ArrayList<Board> boards = new ArrayList<Board>(); for (int i = 0; i < queens.size(); i++) { boards.add(new Board(this)); } int i = 0; for (Board b : boards) { b.queens.remove(i); i++; } return boards; } public String drawBoard() { String s = ""; char[][] printableBoard = new char[boardSize][boardSize]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { printableBoard[i][j] = '_'; } } for (Queen q : queens) { printableBoard[qi][qj] = 'Q'; } s += " ABCDEFGH\n"; for (int i = 0; i < 8; i++) { s += (8 - i) + "|"; for (int j = 0; j < boardSize; j++) { s += printableBoard[i][j]; s += "|"; } s += "\n"; } return s; } } 

Testing class

 import java.util.ArrayList; public class Test { static String[] boards = { "24683175", "17468253", "17582463", "41582736", "51842736", "31758246", "51468273", "71386425", "51863724", "57142863", "63184275", "53172864" }; // all 12 solutions for the 8 // queens problem static ArrayList<Board> boardObjects = new ArrayList<Board>(); public static void main(String[] args) { for (String queens : boards) { // create starter boards boardObjects.add(new Board(queens)); } int i; ArrayList<Board> foundBoards = null; for (i = 8; i > 0; i--) { ArrayList<Board> newBoards = new ArrayList<Board>(); foundBoards = new ArrayList<Board>(); for (Board b : boardObjects) { if (b.checkForImpact()) { // if any queen intercepts we get // children ArrayList<Board> boardsToBeAdded = b.getChildBoards(); // pass // all // permutations // of // queens // once // removed for (Board bo : boardsToBeAdded) { newBoards.add(bo); // add it in to the next list } } else { foundBoards.add(b); // if we have no impact, we have a // solution } } if (!foundBoards.isEmpty()) break; boardObjects.clear(); boardObjects = newBoards; } System.out.println("The maximum number of super-queens is: " + i); ArrayList<String> winningCombinations = new ArrayList<String>(); for (Board board : foundBoards) { String createdBoard = board.drawBoard(); boolean found = false; for (String storedBoard : winningCombinations) { if (storedBoard.equals(createdBoard)) found = true; } if (!found) winningCombinations.add(createdBoard); } for (String board : winningCombinations) { System.out.println(board); } } } 

Final conclusion:

 The maximum number of super-queens is: 6 ABCDEFGH 8|Q|_|_|_|_|_|_|_| 7|_|_|_|_|_|_|Q|_| 6|_|_|_|Q|_|_|_|_| 5|_|_|_|_|_|_|_|_| 4|_|_|_|_|_|_|_|Q| 3|_|Q|_|_|_|_|_|_| 2|_|_|_|_|Q|_|_|_| 1|_|_|_|_|_|_|_|_| ABCDEFGH 8|Q|_|_|_|_|_|_|_| 7|_|_|_|_|_|_|_|_| 6|_|_|_|_|Q|_|_|_| 5|_|_|_|_|_|_|_|Q| 4|_|Q|_|_|_|_|_|_| 3|_|_|_|_|_|_|_|_| 2|_|_|_|_|_|Q|_|_| 1|_|_|Q|_|_|_|_|_| ABCDEFGH 8|_|_|_|_|Q|_|_|_| 7|Q|_|_|_|_|_|_|_| 6|_|_|_|_|_|_|_|Q| 5|_|_|_|Q|_|_|_|_| 4|_|_|_|_|_|_|_|_| 3|_|_|_|_|_|_|_|_| 2|_|_|Q|_|_|_|_|_| 1|_|_|_|_|_|Q|_|_| ABCDEFGH 8|_|_|_|_|Q|_|_|_| 7|Q|_|_|_|_|_|_|_| 6|_|_|_|_|_|_|_|Q| 5|_|_|_|Q|_|_|_|_| 4|_|_|_|_|_|_|_|_| 3|_|_|_|_|_|_|Q|_| 2|_|_|Q|_|_|_|_|_| 1|_|_|_|_|_|_|_|_| ABCDEFGH 8|_|_|_|_|Q|_|_|_| 7|Q|_|_|_|_|_|_|_| 6|_|_|_|_|_|_|_|Q| 5|_|_|_|_|_|_|_|_| 4|_|_|Q|_|_|_|_|_| 3|_|_|_|_|_|_|Q|_| 2|_|_|_|_|_|_|_|_| 1|_|_|_|Q|_|_|_|_| 

I removed duplicates and made a good way to print boards. I don’t remember the exact mathematics, but this indicates 40 possible places. There are others just by looking, but we have already found a fair chunk! From here we can gently move individual queens around. With a cursory glance, there is one piece on each board that can be transferred to 3 additional spaces, so now we know that there are probably about 160 solutions.

conclusions

In this application, the runtime on my machine was less than a second, which means that if we tie it to the standard applications for queens, additional knight-forcing will not affect this process and the execution time will be almost the same. In addition, since only 6-piece puzzles are possible, we know that your possible launch of the application will complete its detection in 6th place, because there will be no more solutions, since there are no viable solutions of 7 items and 8 items.

In other words, finding the maximum layout of a super queen is likely to be shorter than the maximum layout of a queen due to additional restrictions!

+6
source

Trying to sort out such a question is a good way to feel it. Therefore, I will not offer ready-made solutions first.

One small note: I see no reason for the if (i != 0 || j != 0) { condition that you have. You are working on Java arrays. Instead of 1-8, they go from 0 to 7, but 0 is the first column, you should not eliminate it, otherwise it is only a 7x7 board.


First, let me turn to your technical question: how to calculate the positions of knights.

Take a sheet of quadrangular paper, place the queen somewhere at least two squares from the edge. Then mark the end positions of the transition knight from it.

As a result, you get only 8 squares that you need to consider. It makes no sense to make a 3x3 loop to find them. The best idea would be to prepare a static array with the relative coordinates of the movements of the knights - an array of 8 pairs of numbers - and a loop on that. Thus, you only have an 8-step cycle. At each step of the cycle, check the boundaries (0 ≀ X + Xoffset <8, 0 ≀ Y + Yoffset <8), and you have the coordinates of the knight.


Secondly, there is no point checking the part of the board that is ahead of you. Since you have not covered the next line below, it makes no sense to look for queens there. The consequences of this:

  • You will never become another queen on the same line where you just marked the queen's position (because you are threatening her horizontally). This means that if you check the queen, you must use continue to exit the inner loop to the next line.
  • You do not need checkrow() . When you start a scandal, there is no queen in front of you. And if you followed the above brand, there is no queen on your back either.
  • When you use checkcolumn , you start at line 0, but you can end the line to where you are on ( i-1 ). There are no queens in the lines below. The same is true for diagonal checks.
  • Earlier, I said that you need to prepare and check the 8 positions of the knights. But now you know that there are no knights ahead of you in knightly positions. Therefore, you only need to prepare an array with four knight positions - those that are above your position.

But most importantly ... as soon as you finish, and you have the queens in the fields and print the board: you have a single grid. You have proven that this number of queens is possible. But is this the greatest number possible? You have not checked what happens if you do not put the queen on the first square of the first row, but on the second. Perhaps this will allow you to add an additional queen later. What about the queen in the second row? Maybe if you moved this, you could put the queen somewhere below, where you could not before?

So now you have to do the same thing again, changing one decision every time and working from there. In fact, you have many potential boards. What for? Because in each line where you place this queen of lines, there can be more than one real position. Therefore, you decided to put him in the first acting position. But what if you decide to put him in a second valid position? Or leave this line blank? Each such decision is followed by a different set of solutions on the next line.

Different boards created by different solutions form a decision tree. So the problem you have to consider is how to work with such a tree. How to write your solution path, and then come back, change, fill out another board and calculate the queens at each level. People here suggested recursion because it lends itself well to such problems. Or, if you want, you can take a decision package. You can eliminate some of the possible symmetry-based boards.

I suggest you first make sure that you understand your only board well, and then think about how to present your decision tree and how to get through it.

+2
source

There are a few questions here.

First: how many knights can be placed on an nxn chessboard? Since the solution of the k-piece can be trivially reduced to the solution of the k-1 part, it makes sense to start from the upper boundary. That is, look for an n-shaped solution if it fails to find an n-1 solution, etc.

Second question: how do I look for a k-piece solution? There are two classic strategies: first in depth and in width. In the first case, you count one vertex of the search tree at a time and use rollback on error. In the latter case, you take into account one full level of the search tree at a time.

Something that can greatly affect your search is symmetry (in this case, rotation and reflection).

Third (implicit) question: what is a good presentation here? If your chessboards are smaller than 8x8, then the 64-bit bit pattern will be very nice!

In practical terms, try to separate the three levels of your problem as much as possible. If you do not, you will find that choosing at one level will severely limit your options at another level.

+1
source

Source: https://habr.com/ru/post/975089/


All Articles