//---------------------------------------------------------------------------
void __fastcall TFormSolvePuzzle::ButtonSolveClick(TObject *Sender)
{
  const std::vector<PuzzlePiece> piecesOriginal = GetPieces();
  std::vector<PuzzlePiece> pieces1d = piecesOriginal;
  std::sort(pieces1d.begin(),pieces1d.end());

  ProgressBar->Max = IntPower(4,9);
  ProgressBar->Hint = ProgressBar->Max;

  const int maxI = IntPower(4,9);
  for (int i = 1; i!=maxI; ++i)
  {
    const std::vector<PuzzlePiece> solution = SolvePuzzle(std::vector<PuzzlePiece>(),pieces1d);
    if (solution.empty() == false)
    {
      ShowSolution(solution);
      ShowMessage("Solved!");
      return;
    }

    Application->ProcessMessages();
    if (mQuit == true) return;
    ProgressBar->Position = i;

    //Rotate a piece or more pieces
    for (int index = 0; index != 9; ++index)
    {
      pieces1d[index].Rotate();
      if (pieces1d[index].mNrotations != 0) break;
    }
  }

  ShowMessage("Not solved...");
}
Exemple #2
0
int main(){
    FILE *fileToPrint;
    fileToPrint = fopen("Solutions.out","w");

    /** Create Interface of Program */
    while(!Start){
        GameOver = false;
        system("CLS");
        Intro();

        Ask();

        int puzzle[SizeOfPuzzle][SizeOfPuzzle];
        int copy[SizeOfPuzzle][SizeOfPuzzle];
        int i, j;
        /** Here is generated the puzzle full with 0 */
        for(i = 0; i < SizeOfPuzzle; i++){
            for(j = 0; j < SizeOfPuzzle; j++){
                puzzle[i][j] = 0;
            }
        }
        while(!GameOver){
            system("CLS");

            Intro();
            AskSize(SizeOfPuzzle, puzzle);
            ChoseOptions();

            scanf("%d",&choice);

            switch(choice){
                case 1:
                    main();
                    break;
                case 2:
                    InsertNumberInPozitionChoice(puzzle, copy, SizeOfPuzzle);
                    break;
                case 3:
                    GenerateRandomPuzzle(puzzle, copy, fileToPrint, SizeOfPuzzle);
                    break;
                case 4:
                    SolvePuzzle(puzzle, fileToPrint, SizeOfPuzzle);
                    break;
                case 5:
                    Back(puzzle, copy, SizeOfPuzzle);
                    break;
                case 6:
                    GameOver = true;
                    Start = true;
                    break;
                default:
                    printf("\t\t Wrong choice try again :");
                    scanf("%d",&choice);
                    break;
            }
        }
    }

	return 0;
}
// Tetris (Oriented)
void PuzzleTetrisOriented1() {
  Puzzle p(3, 3);
  p.SetName("PuzzleTetrisOriented1");
  p.AddHead(Vector2(2, 0));
  p.AddTail(Vector2(0, 2));
  p.AddSpecialBlock(Vector2(1, 0), L2x2_0);
  p.Regenerate();

  SolvePuzzle(p);
}
void PuzzleTetrisOriented3() {
  Puzzle p(4, 4);
  p.SetName("PuzzleTetrisOriented3");
  p.AddHead(Vector2(3, 0));
  p.AddTail(Vector2(0, 3));
  p.AddSpecialBlock(Vector2(0, 0), Line1x2);
  p.AddSpecialBlock(Vector2(2, 2), Square2x2);
  p.Regenerate();

  SolvePuzzle(p);
}
// Black & white separation
void PuzzleBW1() {
  Puzzle p(3, 3);
  p.SetName("PuzzleBW1");
  p.AddHead(Vector2(2, 0));
  p.AddTail(Vector2(0, 2));
  p.AddSpecialBlock(Vector2(0, 0), Black);
  p.AddSpecialBlock(Vector2(0, 1), Black);
  p.AddSpecialBlock(Vector2(1, 0), Black);
  p.AddSpecialBlock(Vector2(1, 1), White);
  p.Regenerate();

  SolvePuzzle(p);
}
void PuzzleTetrisOriented5() {
  Puzzle p(5, 5);
  p.SetName("PuzzleTetrisOriented5");
  p.AddHead(Vector2(4, 0));
  p.AddTail(Vector2(0, 4));
  p.AddObstacleSide(Vector2(1, 3), Vector2(2, 3));
  p.AddSpecialBlock(Vector2(1, 0), Line1x4);
  p.AddSpecialBlock(Vector2(3, 1), Line3x1);
  p.AddSpecialBlock(Vector2(3, 2), Line3x1);
  p.Regenerate();

  SolvePuzzle(p);
}
void PuzzleTetrisOriented2() {
  Puzzle p(4, 4);
  p.SetName("PuzzleTetrisOriented2");
  p.AddHead(Vector2(3, 0));
  p.AddTail(Vector2(0, 3));
  p.AddObstacleSide(Vector2(1, 2), Vector2(1, 3));
  p.AddObstacleSide(Vector2(2, 1), Vector2(2, 2));
  p.AddObstacleSide(Vector2(3, 2), Vector2(3, 3));
  p.AddSpecialBlock(Vector2(1, 1), Square2x2);
  p.Regenerate();

  SolvePuzzle(p);
}
void PuzzleEssential2() {
  Puzzle p(5, 5);
  p.SetName("PuzzleEssential2");
  p.AddHead(Vector2(2, 2));
  p.AddTail(Vector2(0, 4));
  for (int r = 0; r < 5; r++) {
    for (int c = 0; c < 5; c++) {
      p.AddEssentialNode(Vector2(r, c));
    }
  }
  p.Regenerate();

  SolvePuzzle(p);
}
void PuzzleTetrisOriented4() {
  Puzzle p(6, 6);
  p.SetName("PuzzleTetrisOriented4");
  p.AddHead(Vector2(5, 0));
  p.AddTail(Vector2(0, 5));
  p.AddObstacleSide(Vector2(0, 2), Vector2(1, 2));
  p.AddObstacleSide(Vector2(0, 4), Vector2(1, 4));
  p.AddObstacleSide(Vector2(0, 5), Vector2(1, 5));
  p.AddObstacleSide(Vector2(2, 0), Vector2(3, 0));
  p.AddObstacleSide(Vector2(4, 1), Vector2(4, 2));
  p.AddObstacleSide(Vector2(5, 4), Vector2(5, 5));
  p.AddSpecialBlock(Vector2(2, 2), L2x3_270);
  p.Regenerate();

  SolvePuzzle(p);
}
// Simple maze
void PuzzleSimpleMaze1() {
  Puzzle p(5, 4);
  p.SetName("PuzzleSimpleMaze1");
  p.AddHead(Vector2(4, 0));
  p.AddTail(Vector2(0, 3));
  p.AddObstacleSide(Vector2(3, 0), Vector2(4, 0));
  p.AddObstacleSide(Vector2(3, 1), Vector2(4, 1));
  p.AddObstacleSide(Vector2(1, 1), Vector2(2, 1));
  p.AddObstacleSide(Vector2(1, 2), Vector2(2, 2));
  p.AddObstacleSide(Vector2(1, 3), Vector2(2, 3));
  p.AddObstacleSide(Vector2(0, 2), Vector2(1, 2));
  p.AddObstacleSide(Vector2(0, 2), Vector2(0, 3));
  p.AddObstacleSide(Vector2(0, 0), Vector2(0, 1));
  p.Regenerate();

  SolvePuzzle(p);
}
void PuzzleBW2() {
  Puzzle p(4, 4);
  p.SetName("puzzleBW2");
  p.AddHead(Vector2(3, 0));
  p.AddTail(Vector2(2, 0));
  p.AddSpecialBlock(Vector2(0, 0), Black);
  p.AddSpecialBlock(Vector2(0, 1), Black);
  p.AddSpecialBlock(Vector2(0, 2), Black);
  p.AddSpecialBlock(Vector2(1, 0), Black);
  p.AddSpecialBlock(Vector2(1, 2), Black);
  p.AddSpecialBlock(Vector2(1, 1), White);
  p.AddSpecialBlock(Vector2(2, 0), White);
  p.AddSpecialBlock(Vector2(2, 1), White);
  p.AddSpecialBlock(Vector2(2, 2), White);
  p.Regenerate();

  SolvePuzzle(p);
}
// Maze with essential nodes
void PuzzleEssential1() {
  Puzzle p(4, 4);
  p.SetName("PuzzleEssential1");
  p.AddHead(Vector2(1, 1));
  p.AddHead(Vector2(2, 2));
  p.AddTail(Vector2(1, 0));
  p.AddObstacleSide(Vector2(0, 0), Vector2(0, 1));
  p.AddObstacleSide(Vector2(0, 0), Vector2(1, 0));
  p.AddObstacleSide(Vector2(1, 2), Vector2(1, 3));
  p.AddObstacleSide(Vector2(2, 2), Vector2(3, 2));
  p.AddEssentialNode(Vector2(2, 0));
  p.AddEssentialNode(Vector2(2, 1));
  p.AddEssentialNode(Vector2(0, 1));
  p.AddEssentialNode(Vector2(1, 2));
  p.AddEssentialNode(Vector2(1, 3));
  p.AddEssentialNode(Vector2(3, 3));
  p.Regenerate();

  SolvePuzzle(p);
}
//---------------------------------------------------------------------------
const std::vector<PuzzlePiece> TFormSolvePuzzle::SolvePuzzle(
  const std::vector<PuzzlePiece>& piecesUsed,
  const std::vector<PuzzlePiece>& piecesLeft)
{
  if (CheckBoxDisplay->Checked == true)
  {
    ShowSolution(piecesUsed);
    Application->ProcessMessages();
    this->Refresh();
    Sleep(100);
  }
  if (piecesLeft.empty() == true) return piecesUsed;
  assert(piecesUsed.size() + piecesLeft.size() == 9);
  const int nUsed = static_cast<int>(piecesUsed.size());
  const int nLeft = static_cast<int>(piecesLeft.size());
  const int newIndex = nUsed;
  for (int i=0; i!=nLeft; ++i)
  {
    //Check if the newcomer will fit
    if (newIndex > 2
      && DoesFit(piecesUsed[newIndex-3].mBottom,piecesLeft[i].mTop)==false)
    {
      continue;
    }
    if (newIndex % 3 != 0
      && DoesFit(piecesUsed[newIndex-1].mRight,piecesLeft[i].mLeft)==false)
    {
      continue;
    }
    //Newcomer fits!
    std::vector<PuzzlePiece> newPiecesUsed = piecesUsed;
    std::vector<PuzzlePiece> newPiecesLeft = piecesLeft;
    newPiecesUsed.push_back(newPiecesLeft[i]);
    std::swap(newPiecesLeft[i],newPiecesLeft.back());
    newPiecesLeft.pop_back();
    const std::vector<PuzzlePiece> solution = SolvePuzzle(newPiecesUsed,newPiecesLeft);
    if (solution.empty() == false) return solution;
  }
  return std::vector<PuzzlePiece>();
}
// Black & white separation + essential nodes
void PuzzleEssentialBW1() {
  Puzzle p(8, 8);
  p.SetName("puzzleEssentialBW1");
  p.AddHead(Vector2(7, 0));
  p.AddHead(Vector2(2, 4));
  p.AddHead(Vector2(5, 2));
  p.AddHead(Vector2(4, 6));
  p.AddTail(Vector2(0, 0));
  p.AddTail(Vector2(0, 7));
  p.AddTail(Vector2(7, 7));
  p.AddSpecialBlock(Vector2(0, 0), Black);
  p.AddSpecialBlock(Vector2(0, 5), Black);
  p.AddSpecialBlock(Vector2(1, 3), Black);
  p.AddSpecialBlock(Vector2(1, 4), Black);
  p.AddSpecialBlock(Vector2(4, 2), Black);
  p.AddSpecialBlock(Vector2(5, 6), Black);
  p.AddSpecialBlock(Vector2(6, 6), Black);
  p.AddSpecialBlock(Vector2(0, 1), White);
  p.AddSpecialBlock(Vector2(1, 0), White);
  p.AddSpecialBlock(Vector2(0, 6), White);
  p.AddSpecialBlock(Vector2(2, 3), White);
  p.AddSpecialBlock(Vector2(2, 4), White);
  p.AddSpecialBlock(Vector2(5, 2), White);
  p.AddSpecialBlock(Vector2(6, 5), White);
  p.AddEssentialSide(Vector2(0, 6), Vector2(0, 7));
  p.AddEssentialSide(Vector2(1, 7), Vector2(0, 7));
  p.AddEssentialSide(Vector2(3, 7), Vector2(4, 7));
  p.AddEssentialSide(Vector2(4, 6), Vector2(4, 7));
  p.AddEssentialSide(Vector2(5, 1), Vector2(5, 2));
  p.AddEssentialSide(Vector2(6, 0), Vector2(7, 0));
  p.AddEssentialSide(Vector2(7, 0), Vector2(7, 1));
  p.AddEssentialSide(Vector2(7, 5), Vector2(7, 6));
  p.Regenerate();

  SolvePuzzle(p);
}
void PuzzleBW3() {
  Puzzle p(5, 5);
  p.SetName("PuzzleBW3");
  p.AddHead(Vector2(4, 0));
  p.AddTail(Vector2(0, 1));
  p.AddSpecialBlock(Vector2(0, 0), Black);
  p.AddSpecialBlock(Vector2(0, 3), Black);
  p.AddSpecialBlock(Vector2(1, 0), Black);
  p.AddSpecialBlock(Vector2(1, 1), Black);
  p.AddSpecialBlock(Vector2(1, 2), Black);
  p.AddSpecialBlock(Vector2(1, 3), Black);
  p.AddSpecialBlock(Vector2(2, 0), Black);
  p.AddSpecialBlock(Vector2(2, 2), Black);
  p.AddSpecialBlock(Vector2(2, 3), Black);
  p.AddSpecialBlock(Vector2(3, 3), Black);
  p.AddSpecialBlock(Vector2(0, 2), White);
  p.AddSpecialBlock(Vector2(2, 1), White);
  p.AddSpecialBlock(Vector2(3, 0), White);
  p.AddSpecialBlock(Vector2(3, 1), White);
  p.AddSpecialBlock(Vector2(3, 2), White);
  p.Regenerate();

  SolvePuzzle(p);
}