Beispiel #1
0
void Table::solve()
{
	if (!isSolvable())
		return;
	clock_t t1 = clock();
	unsigned long long masks[9] =
	{
		0x0000000000000000ll,
		0x1000000000000000ll,
		0x1200000000000000ll,
		0x1230000000000000ll,
		0x1230000400000000ll,
		0x1234000000000000ll,
		0x1234500000000000ll,
		0x1234560000000000ll,
		0x123456789ABCDEF0ll
	};
	Field field = m_startField;
	for (int i = 1; i < 9; i++)
	{
		field = searchForMask(field, masks[(i == 5 ? i - 3 : i - 1)], masks[i]);
	}

	while (field != m_startField)
	{
		m_solution.push_back(field);
		field = m_parent.at(field);
	}
	m_solution.push_back(m_startField);
	std::reverse(m_solution.begin(), m_solution.end());
	m_isSolved = true;
	clock_t t2 = clock();
	printf("%.3lf seconds\n", double(t2 - t1) / 1000);
}
Beispiel #2
0
//This function sets the new dimentions of the puzzle and re-shuffles it.
void Puzzle::setDimensions( int newWidth, int newHeight) {
    width = newWidth ;
    height = newHeight ;  //It's not a square, so each dimention must be named
    turns = 0 ;
    do { //initialize it and shuffle it again until you come across a solvable one
        initPuzzle() ;
        shufflePuzzle() ;
        
        //cout << "Shuffled puzzle: \n";
        //output(cout);                             }this was used in debugging, but is no longer needed
        //system("PAUSE");
        
    } while ( !isSolvable() ) ;  //do it until it's solved
}
Beispiel #3
0
void sudokuBoard::newBoard() {

  // Robust generator
  populateBoard();
  obfuscateBoard();
  if ( isSolvable() ) {
    isCreated = true;
    isSolved = false;
  } 
  else 
    newBoard();

  
  
}
Beispiel #4
0
void Tile::Shuffle()
{
    Reset();
    for (int i = 1; i < 16; i++) {
        //get random number 1..15
        int id = randInt(1,15);
        //swap it
        QPushButton *button_1 = idtoButton(i);
        QPushButton *button_2 = idtoButton(id);
        QString str = button_1->text();
        button_1->setText(button_2->text());
        button_2->setText(str);
    }
    if (!isSolvable()) {
        Shuffle();
    } else {
        isRunning = 1;
    }
}
Beispiel #5
0
std::vector <bool> 
GaussianEliminator::getSolution()
{
  std::vector <bool> sol(vars, false) ;  

  if (!isSolvable())
    throw;
			 

  for (int k = vars-1; k >= 0; k --){
    unsigned int size = rows[k].eq.size();
    bool parity = false;    
    
    for (int j = size - 1; j > 0; j --)
      parity ^= sol[rows[k].eq[j]];          
		 
    sol[k] = parity ^ constTerms[k];
  }
  
  return sol;
}
Beispiel #6
0
// This sets the first empty cell to the least possible value and returns a Square with row 
// and col of  cell it edits. This function is used inside the recursiveSolver() function to 
// make guesses systematically.
// If the first empty cell has no possible values the Square that is returned will have -1 for
// row and col.
Square Sudoku::makeGuess()
{
	Square saved;
	saved.row = -1;
	saved.col = -1;

	// Only make a guess on valid unsolved boards.
	if( isSolvable() && !isSolved() )
	{
		// Find the first empty cell and save it.
		for( int r = 0; r < 9; r++ )
		{
			for( int c = 0; c < 9; c++ )
			{
				if( 0 == cell[r][c] )
				{
					saved.row = r;
					saved.col = c;
					break;
				}
			}
			if( -1 != saved.row )
				break;
		}

		// Loop through values 1-9
		for( int v = 1; v <= 9; v++ )
		{
			// Try to assign the value to the saved empty cell
			// Exit once it's set.
			// This assigns the lowest possible value.
			if( set( saved.row, saved.col, v ) )
			{
				break;
			}
		}
	}

	return saved;
}
Beispiel #7
0
bool
GaussianEliminator::addEquation(Equation eq, bool term)
{
  Row nrow; 

  while(eq.size()) {
    unsigned short int fp = eq[0];
    if (rows[fp].set){
      eq += rows[fp].eq;
      term ^= constTerms[fp];      
    } else {
      rows[fp].set = true;
      rows[fp].eq = eq;
      constTerms[fp] = term;
      rowsUnset --;
      break;
    }        
  }

  if (isSolvable())
    return true;

  return false;
}
Beispiel #8
0
// The recursive solver will solve any valid board. 
// Returns TRUE If the board is solved.
// Returns FALSE if the board is not solved and all appropriate guesses have been exhausted.
bool Sudoku::recursiveSolver( /*int depth*/ )
{
	Sudoku original = *this;
	Sudoku child;
	Square saved;
	int guess = 0;
	bool validGuess;

	// Solve the board as much as possible deterministically.
	deterministic();

	// Save a copy of the board so that changes made from invalid
	// guesses can be reverted to the original parent.
	Sudoku parent = *this;

//	// Display the depth and current board state.
//	cout << "depth: " << depth << endl;
//	print();

	// If the board is invalid return false.
	if( !isSolvable() )
	{
		return false;
	}

	// If the board is solved return true.
	if( isSolved() )
	{
		return true;
	}

	// If the board is still valid but not solved we need to make guesses.
	else
	{
		int iter = 0;
		do
		{
			// Make a guess of the lowest possible value in the first empty cell
			// Save the cell where the guess is.
			saved = makeGuess();

			// If we have exhausted the guesses in the first empty cell then
			// exit since this is no longer a valid board. 
			if( saved.row == -1 )
			{
				break;
			}

			// Save the value of the guess made in the "Square saved" cell.
			guess = cell[saved.row][saved.col];

			// The recursiveSolver() will return whether the board is solved after making that guess.
			validGuess = recursiveSolver( /*depth + 1*/ );

			// If it solved it return true.
			if( validGuess )
			{
				return true;
			}

			// If the board was not solved then the guess was not valid.
			// Revert the board to the parent.
			// Remove guess from the possible values in the saved cell.
			// Update parent so it remembers the guesses we have already tried.
			else
			{
				*this = parent;
				possible[saved.row][saved.col][guess] = false;
				parent = *this;
			}
		}while( !validGuess && saved.row != -1 && iter++ < 9 );
		// Some redundancies in the while loop exit criteria
		// Do this while the last guess was bad and there are still
		// more guesses to make.
		// Also never loop more than 9 guesses. ( redundant, should never catch )
	}

	// If we pass all of that then the board had all the guesses exhausted in a particular cell.
	// This means we have a cell with no possible values. 
	// Revert to the parent board.
	// Exit and pass back up to the calling function.
	// If this was called recursively then the next level down will make the next appropriate guess in 
	// the last cell where a guess was made.
	*this = original;
	return false;
}