用C++可视化生成9x9有效数独完整代码
时间: 2024-05-07 07:19:09 浏览: 6
以下是一个基于C++和Qt的可视化生成9x9有效数独的完整代码:
```c++
#include <QtWidgets>
class SudokuWidget : public QWidget {
public:
SudokuWidget(QWidget *parent = nullptr)
: QWidget(parent), m_layout(new QGridLayout(this))
{
m_layout->setSpacing(0);
m_layout->setMargin(0);
m_layout->setContentsMargins(0, 0, 0, 0);
for (int i = 0; i < 81; i++) {
int row = i / 9, column = i % 9;
m_cells[i] = new QLineEdit(this);
m_cells[i]->setAlignment(Qt::AlignCenter);
m_cells[i]->setMaxLength(1);
m_cells[i]->setFixedSize(QSize(40, 40));
m_cells[i]->setValidator(new QIntValidator(1, 9, this));
m_cells[i]->installEventFilter(this);
m_layout->addWidget(m_cells[i], row, column);
}
QPushButton *generateButton = new QPushButton(tr("Generate"), this);
connect(generateButton, SIGNAL(clicked()), this, SLOT(generate()));
m_layout->addWidget(generateButton, 9, 0, 1, 9);
}
private slots:
void generate()
{
int board[81];
memset(board, 0, sizeof(board));
generateSudoku(board);
for (int i = 0; i < 81; i++) {
m_cells[i]->setText(board[i] ? QString::number(board[i]) : "");
m_cells[i]->setReadOnly(board[i] != 0);
}
}
private:
QLineEdit *m_cells[81];
QGridLayout *m_layout;
bool eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Delete || keyEvent->key() == Qt::Key_Backspace) {
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(watched);
if (lineEdit && lineEdit->isReadOnly()) {
lineEdit->setText("");
return true;
}
}
}
return QWidget::eventFilter(watched, event);
}
bool check(int board[], int row, int column, int value)
{
for (int i = 0; i < 9; i++) {
if (board[row * 9 + i] == value || board[i * 9 + column] == value) {
return false;
}
}
int blockRow = row / 3 * 3, blockColumn = column / 3 * 3;
for (int i = blockRow; i < blockRow + 3; i++) {
for (int j = blockColumn; j < blockColumn + 3; j++) {
if (board[i * 9 + j] == value) {
return false;
}
}
}
return true;
}
bool solveSudoku(int board[], int index)
{
if (index == 81) {
return true;
}
if (board[index] != 0) {
return solveSudoku(board, index + 1);
}
for (int i = 1; i <= 9; i++) {
if (check(board, index / 9, index % 9, i)) {
board[index] = i;
if (solveSudoku(board, index + 1)) {
return true;
}
board[index] = 0;
}
}
return false;
}
void generateSudoku(int board[])
{
srand(time(nullptr));
board[rand() % 81] = rand() % 9 + 1;
solveSudoku(board, 0);
int removeCount = 50;
while (removeCount > 0) {
int index = rand() % 81;
int temp = board[index];
board[index] = 0;
int tempBoard[81];
memcpy(tempBoard, board, sizeof(tempBoard));
int count = 0;
solveSudoku(tempBoard, 0);
for (int i = 0; i < 81; i++) {
if (board[i] == 0 && tempBoard[i] != 0) {
count++;
}
}
if (count > 1) {
board[index] = temp;
} else {
removeCount--;
}
}
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
SudokuWidget widget;
widget.show();
return app.exec();
}
```
这个程序使用了Qt的QLineEdit组件来展示数独,同时使用了QIntValidator来限制输入的内容必须为数字1-9。在生成数独时,我们使用了一个简单的算法:将一个随机位置的值设为1-9中的一个,然后使用递归回溯算法来填充剩下的空格。最后,我们随机选取一些空格并将它们清空,再使用回溯算法来检查这个数独是否有唯一解,如果有,则保留这些空格,否则重新填充这个空格。