数独源码

因为下载了一个数独游戏,想着写个计算器。

原理很简单,就是暴力破解

但感觉代码还是非常复杂,在网上看了新加坡总理李显龙的c代码,仅有几十行,用位运算比较多,比较晦涩难懂。但写的真好

想着用c++尽量面向对象的思想实现一下,代码如下:

平台ubuntu + Qt,控制台程序,在windows下运行应该也没问题。

main.cpp

/* write by huoqs
 * 2016-12-25
 */
#include <QCoreApplication>
#include <iostream>
#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 <QVector>

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<int> findPossibleNumbers(SudokuBox* pBox);
    bool isValid();
    void attemptSetBox(SudokuBox* pBox);
    QVector<SudokuBoxes* > m_oRows;
    QVector<SudokuBoxes* > m_oColumns;
    QVector<SudokuBoxes* > m_oBlocks;
    QVector<SudokuBox* > m_oBoxes;
};

//has nine box
class SudokuBoxes
{
public:
    void addBox(SudokuBox* pBox);
    SudokuBox* box(int nIndex);
    bool isValid();
private:
    QVector<SudokuBox*> 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 <sudoku.h>
#include <iostream>

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<int> oVec = findPossibleNumbers(pBox);
    for (auto it = oVec.begin(); it != oVec.end(); it++)
    {
        pBox->setData(*it);
        SudokuBox * pNextBox = findNextUncertainBox();
        attemptSetBox(pNextBox);
        pBox->setData(0);
    }
}

QVector<int> SudokuCalcultor::findPossibleNumbers(SudokuBox* pBox)
{
    QVector<int> 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<int> 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;
}
时间: 2024-10-13 10:15:39

数独源码的相关文章

android源码大放送(实战开发必备),免费安卓demo源码,例子大全文件详细列表

免费安卓demo源码,例子大全文件详细列表 本列表源码永久免费下载地址:http://www.jiandaima.com/blog/android-demo 卷 yunpan 的文件夹 PATH 列表 卷序列号为 0000-73EC E:. │ jiandaima.com文件列表生成.bat │ 例子大全说明.txt │ 本例子永久更新地址~.url │ 目录列表2016.03.10更新.txt │ ├─前台界面 │ ├─3D标签云卡片热门 │ │ Android TagCloudView云标签

C#源码大汇总

C#高仿QQ2013可在广域网部署聊天系统GG叽叽 动态显示硬盘分区容量饼图 自定义ProgressBar控件高仿Win8进度条 多皮肤精美在线QQ悬浮客服插件 jQuery仿天猫首页多格焦点图片轮播 jQuery时间轴特效 自动完成菜单.代码提示.输入纠错控件 仿Google浏览器进度条 仿苹果Safari浏览器选项卡自定义TabControl控件 蜂窝大战游戏 C#开源内容管理系统DTcms v3.0正式版源码 ScreenToGif录制屏幕到gif动画 CSS3仿Google Play的垂

android 近百个源码项目【转】

http://www.cnblogs.com/helloandroid/articles/2385358.html Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用.其中也有许许多多的开发者提供了应用开源项目,贡献出他们的智慧和创造力.学习开源代码是掌握技术的一个最佳方式.下面推荐几个应用开源项目,这些项目不仅提供了优秀的创意,也可以直接掌握 Android内核的接口使用: 1.Android团队提供的示例项目 如果不是从学习Android S

多个Android项目源码-覆盖方方面面值得学习

Android PDF 阅读器 http://sourceforge.net/projects/andpdf/files/个人记账工具 OnMyMeans http://sourceforge.net/projects/onmymeans/developAndroid电池监控 Android Battery Dog http://sourceforge.net/projects/andbatdog/RSS阅读软件 Android RSS http://code.google.com/p/andr

Android 上千实例源码分析以及开源分析

Android 上千实例源码分析以及开源分析(百度云分享) 要下载的直接翻到最后吧,项目实例有点多. 首先 介绍几本书籍(下载包中)吧. 01_Android系统概述 02_Android系统的开发综述 03_Android的Linux内核与驱动程序 04_Android的底层库和程序 05_Android的JAVA虚拟机和JAVA环境 06_Android的GUI系统 07_Android的Audio系统 08_Android的Video 输入输出系统 09_Android的多媒体系统 10_

【周末福利】源码分享

这是我在刚刚学习Android时自己做的一个小游戏,彩色双重数独.现在看看,布局弱到爆,性能不忍直视,注释都不全...咳咳 但是当时还是很用心做的但是第一个小游戏在应用宝上有超过10万的下载 还是很开心的当时.  今天就来给大家看看 大神请无视,笑话的默默的笑话下就好话不多说 ,上图先 ?源码地址: http://techfoxbbs.com/thread-596-1-1.html 更多java,java学习,安卓学习  在 TechFox IT技术论坛

小说分销系统,微信小说分销,类掌中云小说系统,类818tu系统源码

[演示站参数][][][][][][][][][][][] [后 台 地 址]     http://xiaoshuo.qqsiot.cn/manager          [] [管理员账号]     admin                                                     [] [渠道商账号]     channel                                                  [] [代理商账号]     age

cocos Creator js 房卡麻将/血战/H5四川麻将源码下载搭建

房卡麻将/血战/H5四川麻将 源码 支持iOS/Android/H5 完整源码 1.基于NODEJS+MYSQL的服务器,成熟的技术方案,高效稳定,且方便Windows开发,Linux平台布署,节约服务器运转成本. 2.采用最新版本的cocos引擎,cocos creator开发,可快速的进行界面调整.且能够快速地发布iOS,Android版本. 3.如需H5版本,只需针对H5平台进行资源优化即可. 4.成熟可靠的房卡式设计,能满足大部分用户使用体验. 5.产品经过大量测试,可以运转稳定. 测试

下载-深入浅出Netty源码剖析、Netty实战高性能分布式RPC、NIO+Netty5各种RPC架构实战演练三部曲视频教程

下载-深入浅出Netty源码剖析.Netty实战高性能分布式RPC.NIO+Netty5各种RPC架构实战演练三部曲视频教程 第一部分:入浅出Netty源码剖析 第二部分:Netty实战高性能分布式RPC 第三部分:NIO+Netty5各种RPC架构实战演练