数独ソース

6670 ワード

数独ゲームをダウンロードしたので、電卓を書こうと思っています.
原理は簡単です.暴力的な解読です.
しかし、コードは非常に複雑な感じがして、ネット上でシンガポールの李顕龍首相のcコードを見て、数十行しかなくて、ビット演算が多くて、比較的に難解です.でもよく書けた
c++でできるだけオブジェクト向けのアイデアを実現したいと考えています.コードは以下の通りです.
プラットフォームubuntu+Qt、コンソールプログラム、windowsで実行しても問題ないはずです.
main.cpp
/* write by huoqs
 * 2016-12-25
 */
#include 
#include 
#include "sudoku.h"

using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    SudokuCalcultor oCalc;
    //input unknown number please input 0 (no space)
    char nData;
    for (int i = 0; i < 9; i++)
    {
        cout << "Row " << i+1 << ":";
        for (int j = 0; j < 9; j++)
        {
            cin >> nData;
            oCalc.setData(i, j, nData - '0');
        }
    }
    oCalc.outPut();
    oCalc.calculateAndOutput();
    cout << "Hello World!" << endl;

    return a.exec();
}

 sudoku.h
#ifndef SUDOKU_H
#define SUDOKU_H
#include 

class SudokuBoxes;
class SudokuBox;

class SudokuCalcultor
{
public:
    SudokuCalcultor();
    ~SudokuCalcultor();
    void setData(int nRow, int nColumn, int nData);
    void calculateAndOutput();
    void outPut();

private:
    void initialData();
    SudokuBox* findNextUncertainBox();
    QVector findPossibleNumbers(SudokuBox* pBox);
    bool isValid();
    void attemptSetBox(SudokuBox* pBox);
    QVector m_oRows;
    QVector m_oColumns;
    QVector m_oBlocks;
    QVector m_oBoxes;
};

//has nine box
class SudokuBoxes
{
public:
    void addBox(SudokuBox* pBox);
    SudokuBox* box(int nIndex);
    bool isValid();
private:
    QVector m_oSudokuBoxes;
};

class SudokuBox
{
public:
    SudokuBox(int nRow, int nColumn);
    int column();
    int row();
    int block();
    int data();
    void setData(int nData);
private:
    int m_nColumn;
    int m_nRow;
    int m_nData;
};

#endif // SUDOKU_H

 sudoku.cpp
#include 
#include 

SudokuCalcultor::SudokuCalcultor()
{
    initialData();
}

SudokuCalcultor::~SudokuCalcultor()
{
    qDeleteAll(m_oBoxes);
    m_oBoxes.clear();
    qDeleteAll(m_oRows);
    m_oRows.clear();
    qDeleteAll(m_oColumns);
    m_oColumns.clear();
    qDeleteAll(m_oBlocks);
    m_oBlocks.clear();
}

void SudokuCalcultor::initialData()
{
    for (int i = 0; i < 9; i++)
    {
        SudokuBoxes* pBoxes = new SudokuBoxes();
        m_oRows.append(pBoxes);
        pBoxes = new SudokuBoxes();
        m_oColumns.append(pBoxes);
        pBoxes = new SudokuBoxes();
        m_oBlocks.append(pBoxes);
    }
    for (int i = 0; i < 9; i++)
    {

        for (int j = 0; j < 9; j++)
        {
            SudokuBox * pBox = new SudokuBox(i, j);
            m_oBoxes.append(pBox);
            m_oRows.at(i)->addBox(pBox);
            m_oColumns.at(j)->addBox(pBox);
            m_oBlocks.at(i / 3 * 3 + j / 3)->addBox(pBox);
        }
    }
}

void SudokuCalcultor::outPut()
{
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
        {
            std::cout << m_oRows.at(i)->box(j)->data() << " ";
        }
        std::cout << std::endl;
    }

    std::cout << std::endl;

}
bool SudokuCalcultor::isValid()
{
    for (int i = 0; i < 9; i++)
    {
        if (!m_oRows.at(i)->isValid())
        {
            return false;
        }
    }
    for (int i = 0; i < 9; i++)
    {
        if (!m_oColumns.at(i)->isValid())
        {
            return false;
        }
    }
    for (int i = 0; i < 9; i++)
    {
        if (!m_oBlocks.at(i)->isValid())
        {
            return false;
        }
    }
    return true;
}

void SudokuCalcultor::setData(int nRow, int nColumn, int nData)
{
    m_oRows.at(nRow)->box(nColumn)->setData(nData);
}

void SudokuCalcultor::calculateAndOutput()
{
    if (!isValid())
    {
        std::cout << "The Initial is not Valid." << std::endl;
        return;
    }
    SudokuBox* pFirst = findNextUncertainBox();
    if (pFirst)
    {
        attemptSetBox(pFirst);
    }
}

void SudokuCalcultor::attemptSetBox(SudokuBox* pBox)
{
    if (!pBox)
    {
        outPut();
        return;
    }
    QVector oVec = findPossibleNumbers(pBox);
    for (auto it = oVec.begin(); it != oVec.end(); it++)
    {
        pBox->setData(*it);
        SudokuBox * pNextBox = findNextUncertainBox();
        attemptSetBox(pNextBox);
        pBox->setData(0);
    }
}

QVector SudokuCalcultor::findPossibleNumbers(SudokuBox* pBox)
{
    QVector oVec{1,2,3,4,5,6,7,8,9};
    SudokuBoxes* pBoxes = m_oRows.at(pBox->row());
    for (int i = 0; i < 9; i++)
    {
        oVec.removeOne(pBoxes->box(i)->data());
    }
    pBoxes = m_oColumns.at(pBox->column());
    for (int i = 0; i < 9; i++)
    {
        oVec.removeOne(pBoxes->box(i)->data());
    }
    pBoxes = m_oBlocks.at(pBox->block());
    for (int i = 0; i < 9; i++)
    {
        oVec.removeOne(pBoxes->box(i)->data());
    }
    return oVec;
}

SudokuBox* SudokuCalcultor::findNextInvalid()
{
    for (auto it = m_oBoxes.begin(); it != m_oBoxes.end(); it++)
    {
        if ((*it)->data() < 1)
        {
            return *it;
        }
    }
    return nullptr;
}

void SudokuBoxes::addBox(SudokuBox* pBox)
{
    m_oSudokuBoxes.append(pBox);
}

SudokuBox* SudokuBoxes::box(int nIndex)
{
    return m_oSudokuBoxes.at(nIndex);
}

bool SudokuBoxes::isValid()
{
    QVector oVec{1,2,3,4,5,6,7,8,9};
    for (auto it = m_oSudokuBoxes.begin(); it != m_oSudokuBoxes.end(); it ++)
    {
        int nData = (*it)->data();
        if (nData != 0)
        {
            if (oVec.contains(nData))
            {
                oVec.removeOne(nData);
            }
            else
            {
                return false;
            }
        }
    }
    return true;
}

SudokuBox::SudokuBox(int nRow, int nColumn):
    m_nRow(nRow), m_nColumn(nColumn), m_nData(0)
{

}

int SudokuBox::column()
{
    return m_nColumn;
}

int SudokuBox::row()
{
    return m_nRow;
}

int SudokuBox::data()
{
    return m_nData;
}

void SudokuBox::setData(int nData)
{
    m_nData = nData;
}

int SudokuBox::block()
{
    return m_nRow / 3 * 3 + m_nColumn / 3;
}

 
転載先:https://www.cnblogs.com/huoqs/p/6218979.html