Example #1
0
 /**
  * Creates a step for a W-Wing. <code>cand1</code> is the candidate for which eliminations can be
  * made, <code>cand2</code> is the connecting candidate. <code>index1</code> and <code>index2
  * </code> are the bivalue cells, {@link #wIndex1} and {@link #wIndex2} are the strong link.
  * <code>elimSet</code> holds all cells where candidates can be eliminated.
  *
  * @param cand1
  * @param cand2
  * @param index1
  * @param index2
  * @param elimSet
  * @param onlyOne
  * @return
  */
 private SolutionStep createWWingStep(
     int cand1, int cand2, int index1, int index2, SudokuSet elimSet, boolean onlyOne) {
   globalStep.reset();
   globalStep.setType(SolutionType.W_WING);
   globalStep.addValue(cand1);
   globalStep.addValue(cand2);
   globalStep.addIndex(index1);
   globalStep.addIndex(index2);
   globalStep.addFin(index1, cand2);
   globalStep.addFin(index2, cand2);
   globalStep.addFin(wIndex1, cand2);
   globalStep.addFin(wIndex2, cand2);
   for (int i = 0; i < elimSet.size(); i++) {
     globalStep.addCandidateToDelete(elimSet.get(i), cand1);
   }
   SolutionStep step = (SolutionStep) globalStep.clone();
   if (onlyOne) {
     return step;
   } else {
     steps.add(step);
   }
   return null;
 }
Example #2
0
 /**
  * Try all combinations of three bivalue cells (for xyz: one trivalue and two bivalue cells). The
  * following restrictions are in place:
  *
  * <ul>
  *   <li>The three cells must have exactly three candidates together
  *   <li>The first cell (pivot) must see both other cells (pincers)
  *   <li>The pincers must have exactly one candidate that is the same (candidate z)
  *   <li>z can be excluded from all cells that see both pincers (for xyz they must see the pivot
  *       as well)
  * </ul>
  *
  * @param xyz
  * @param onlyOne
  * @return
  */
 private SolutionStep getWing(boolean xyz, boolean onlyOne) {
   // first get all bivalue/trivalue cells
   int biValueCount = 0;
   int triValueCount = 0;
   for (int i = 0; i < Sudoku2.LENGTH; i++) {
     if (sudoku.getAnzCandidates(i) == 2) {
       biCells[biValueCount++] = i;
     }
     if (xyz && sudoku.getAnzCandidates(i) == 3) {
       triCells[triValueCount++] = i;
     }
   }
   // now iterate them; use local variables to cover xy and xyz
   int endIndex = xyz ? triValueCount : biValueCount;
   int[] biTri = xyz ? triCells : biCells;
   // we check all combinations of bivalue cells (one tri + 2 bi for xyz)
   for (int i = 0; i < endIndex; i++) {
     for (int j = xyz ? 0 : i + 1; j < biValueCount; j++) {
       // any given combination of two cells must give exactly three
       // candidates; if that is not the case, skip it right away
       if (Sudoku2.ANZ_VALUES[sudoku.getCell(biTri[i]) | sudoku.getCell(biCells[j])] != 3) {
         // cant become a wing
         continue;
       }
       for (int k = j + 1; k < biValueCount; k++) {
         int index1 = biTri[i];
         int index2 = biCells[j];
         int index3 = biCells[k];
         int cell1 = sudoku.getCell(index1);
         int cell2 = sudoku.getCell(index2);
         int cell3 = sudoku.getCell(index3);
         // all three cells combined must have exactly three candidates
         if (Sudoku2.ANZ_VALUES[cell1 | cell2 | cell3] != 3) {
           // incorrect number of candidates
           continue;
         }
         // none of the cells may be equal
         if (cell1 == cell2 || cell2 == cell3 || cell3 == cell1) {
           // cant be a wing
           continue;
         }
         // three possibilities for XY-Wing: each cell could be the pincer
         // XYZ-Wing exits the loop after the first iteration
         int maxTries = xyz ? 1 : 3;
         for (int tries = 0; tries < maxTries; tries++) {
           // swap cells accordingly
           if (tries == 1) {
             index1 = biCells[j];
             index2 = biTri[i];
             cell1 = sudoku.getCell(index1);
             cell2 = sudoku.getCell(index2);
           } else if (tries == 2) {
             index1 = biCells[k];
             index2 = biCells[j];
             index3 = biTri[i];
             cell1 = sudoku.getCell(index1);
             cell2 = sudoku.getCell(index2);
             cell3 = sudoku.getCell(index3);
           }
           // the pivot must see the pincers
           if (!Sudoku2.buddies[index1].contains(index2)
               || !Sudoku2.buddies[index1].contains(index3)) {
             // doesnt see them -> try another
             continue;
           }
           // the pincers must have exactly one candidate that is the same in both cells
           short cell = (short) (cell2 & cell3);
           if (Sudoku2.ANZ_VALUES[cell] != 1) {
             // no wing, sorry
             continue;
           }
           int candZ = Sudoku2.CAND_FROM_MASK[cell];
           // are there candidates that can see the pincers?
           elimSet.setAnd(Sudoku2.buddies[index2], Sudoku2.buddies[index3]);
           elimSet.and(finder.getCandidates()[candZ]);
           if (xyz) {
             // the pivot as well
             elimSet.and(Sudoku2.buddies[index1]);
           }
           if (elimSet.isEmpty()) {
             // no candidates to delete
             continue;
           }
           // ok, wing found!
           globalStep.reset();
           if (xyz) {
             globalStep.setType(SolutionType.XYZ_WING);
           } else {
             globalStep.setType(SolutionType.XY_WING);
           }
           int[] cands = sudoku.getAllCandidates(index1);
           globalStep.addValue(cands[0]);
           globalStep.addValue(cands[1]);
           if (xyz) {
             globalStep.addValue(cands[2]);
           } else {
             globalStep.addValue(candZ);
           }
           globalStep.addIndex(index1);
           globalStep.addIndex(index2);
           globalStep.addIndex(index3);
           if (xyz) {
             globalStep.addFin(index1, candZ);
           }
           globalStep.addFin(index2, candZ);
           globalStep.addFin(index3, candZ);
           for (int l = 0; l < elimSet.size(); l++) {
             globalStep.addCandidateToDelete(elimSet.get(l), candZ);
           }
           SolutionStep step = (SolutionStep) globalStep.clone();
           if (onlyOne) {
             return step;
           } else {
             steps.add(step);
           }
         }
       }
     }
   }
   return null;
 }