数独个人项目

1) GitHub地址

https://github.com/ChengHaoShi/Project

2) PSP表格


PSP2.1


Personal Software Process Stages


预估耗时(小时)


实际耗时(小时)


Planning


计划


1.5


1


·Estimate

  • ·估计这个任务需要多少时间

1.5


1

  • ·Development

·开发


44.5


41.5

  • ·Analysis
  • ·需求分析 (包括学习新技术)
 
12


16


·Design Spec

  • ·生成设计文档

8


5

  • ·Design Review
  • ·设计复审 (和同事审核设计文档)
 
3


4

  • ·Coding Standard
  • ·代码规范 (为目前的开发制定合适的规范)
 
1


2

  • ·Design
  • ·具体设计
 
5


4

  • ·Coding
  • ·具体编码
 
5.5


4

  • ·Code Review
  • ·代码复审
 
3.5


4

  • ·Test
  • ·测试(自我测试,修改代码,提交修改)
 
4.5


2.5


Reporting


报告


5


6

  • ·Test Report
  • ·测试报告
 
1.5


1

  • ·Size Measurement
  • ·计算工作量
 
1


2.5

  • ·Postmortem & Process Improvement Plan
  • ·事后总结, 并提出过程改进计划
 
2.5


2.5


合计


51


48.5

3) 解题思路

  • ·数独游戏规则:

数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。                   ———引用自《数独_百度百科

·题目要求:

1.程序能生成不重复的数独终局至文件;

2.程序能读取文件内的数独问题,求一个可行解并将结果输出到文件;

·采用算法:

回溯法生成数独终局,并检验是否符合数独可行解。

4) 设计实现过程

将部分函数和变量封装成Sudoku类。6个Sudoku类函数:

构造函数void Sudoku(int n)

公有函数int SudokuGenerate(int pos, long& count), void SudokuSolve(char* path)

私有函数bool IsVaild(int pot)、void PrintSudoku()

控制台输出函数void   PrintUsage()

单元测试设计:

对IsValid() 函数进行测试;

对命令行进行测试,检测异常输入并提供解决办法;

对队中生成数独的个数进行测试;

5) 程序使用方法

1.序每次向sudoku.txt文件中输入一个数独终局。

2.使用release进行程序生成。

性能分析图

int SudokuGenerate(int pos, long& count, bool solve);//程序中消耗最大的函数

6) 核心代码

#include "sudoku.h"
#include "stdafx.h"

using namespace std;
string const NOSUCHFILE = "No such file: ";
string const OUTFILE = "sudoku.txt";
int const SQRTSIZE = int(sqrt(GRIDSIZE));

Sudoku::Sudoku(int n)
{
    for (int i = 0; i < GRIDSIZE; i++)
    {
        for (int j = 0; j < GRIDSIZE; j++)
        {
            grid[i][j] = UNKNOWN;
        }
    }
    grid[0][0] = FLAGNUM;
    this->n = n;
    output.open(OUTFILE);
    for (int i = 0; i < GRIDSIZE * GRIDSIZE; i++)
    {
        if ((i + 1) % 9 == 0)
        {
            buff[2 * i + 1] = ‘\n‘;
            continue;
        }
        buff[2 * i + 1] = ‘ ‘;
    }
    buff[162] = ‘\n‘;
}

int Sudoku::SudokuGenerate(int pos, long& count, bool solve)
{
    if (pos == GRIDSIZE * GRIDSIZE)
    {
        PrintSudoku();
        count++;
        if (count == n)
        {
            return 1;
        }
    }
    else
    {
        int x = pos / GRIDSIZE;
        int y = pos % GRIDSIZE;
        if (grid[x][y] == UNKNOWN)
        {
            int base = x / 3 * 3;
            for (int i = 0; i < GRIDSIZE; i++)         // try to fill the pos from 1-9
            {
                grid[x][y] = (i + base) % GRIDSIZE + 1 + ‘0‘;
                if (IsValid(pos, solve))               // if the number is valid
                {
                    if (SudokuGenerate(pos + 1, count, solve) == 1)       // try to fill next pos
                    {
                        return 1;
                    }
                }
                grid[x][y] = UNKNOWN;
            }
        }
        else
        {
            if (SudokuGenerate(pos + 1, count, solve) == 1)
            {
                return 1;
            }
        }
    }
    return 0;
}

int Sudoku::SudokuSolve(char* path)
{
    ifstream input;
    input.open(path);
    if (input)
    {
        int total = 0;
        string temp[GRIDSIZE];
        string str;
        int line = 0;
        bool exc = false;     // wrong input such as ‘a‘,‘.‘,etc. in the input file
        while (total < 1000000 && getline(input, str))
        {
            temp[line] = str;
            line++;
            if (line == GRIDSIZE)
            {
                for (int i = 0; i < GRIDSIZE; i++)
                {
                    for (int j = 0; j < GRIDSIZE; j++)
                    {
                        grid[i][j] = temp[i][2 * j];
                        if(grid[i][j] < ‘0‘ || grid[i][j] > ‘9‘)
                        {
                            exc = true;
                            break;
                        }
                    }
                }
                getline(input, str);
                line = 0;
                if (exc)
                {
                    exc = false;
                    continue;
                }
                total++;
                // solve sudoku
                long count = 0;
                SudokuGenerate(0, count, true);
            }
        }
        //cout << total << endl;
    }
    else
    {
        cout << NOSUCHFILE << string(path) << endl;
        return 0;
    }
    return 1;
}

bool Sudoku::IsValid(int pos, bool solve)
{
    int x = pos / GRIDSIZE;
    int y = pos % GRIDSIZE;
    int z = x / SQRTSIZE * SQRTSIZE + y / SQRTSIZE;
    int leftTop = z / SQRTSIZE * GRIDSIZE * SQRTSIZE + (z % SQRTSIZE) * SQRTSIZE;
    int rightDown = leftTop + (2 * GRIDSIZE + SQRTSIZE - 1);
    int bound = solve ? GRIDSIZE : y;
    // check row
    for (int i = 0; i < bound; i++)
    {
        if (i == y)
        {
            continue;
        }
        if (grid[x][i] == grid[x][y])
        {
            return false;
        }
    }
    // check column
    bound = solve ? GRIDSIZE : x;
    for (int i = 0; i < bound; i++)
    {
        if (i == x)
        {
            continue;
        }
        if (grid[i][y] == grid[x][y])
        {
            return false;
        }
    }
    // check box
    int bound_x = leftTop / GRIDSIZE;
    int bound_y = leftTop % GRIDSIZE;
    if (bound_x % 3 != 0 || bound_y % 3 != 0 || bound_x > GRIDSIZE -3 || bound_y > GRIDSIZE - 3)
    {
        cout << "error" << endl;
        exit(0);
    }
    for (int i = bound_x; i < (bound_x + 3); i++)
    {
        for (int j = bound_y; j < (bound_y + 3); j++)
        {
            if (i == x && j == y)
            {
                if (solve)
                {
                    continue;
                }
                else
                {
                    return true;
                }
            }
            if (grid[i][j] == grid[x][y])
            {
                return false;
            }
        }
    }
    return true;
}

void Sudoku::PrintSudoku()
{
    for (int i = 0; i < GRIDSIZE; i++)
    {
        for (int j = 0; j < GRIDSIZE; j++)
        {
            buff[18 * i + 2 * j] = grid[i][j];
        }
    }
    output << buff;
}

原文地址:https://www.cnblogs.com/AmandaYoung/p/8726878.html

时间: 2024-10-07 08:53:39

数独个人项目的相关文章

干货来了!python学习之重难点整理合辑1

关于装饰器.lambda.鸭子类型.魔法函数的理解仍存有困惑之处,趁周末有时间温故,赶紧去自学了解下相关知识. 1.装饰器是什么: 很多初学者在接触装饰器的时候只做到了肤浅的了解它的概念.组成形态.实际上装饰器是python学习中很难啃的大骨头,一旦涉及到具体用途以及原理,经常会把人绕晕. 在这里,我们需要明确的一点是:装饰器并不是加速器.装饰器的作用仅仅是为了封装一个函数,使其增加原有的函数功能,却不改变其调用方式. 而装饰器往往需要具有三大要素:1把想加入的函数C作为参数传入函数A  2.在

数独GUI程序项目实现

数独GUI程序项目实现 导语:最近玩上了数独这个游戏,但是找到的几个PC端数独游戏都有点老了...我就想自己做一个数独小游戏,也是一个不错的选择. 前期我在网上简单地查看了一些数独游戏的界面,代码.好好地了解了一下现在数独游戏的大概的框架.当然,我自己写的小游戏,也许没那么好.但是我一定会一点点升级这个小游戏的. 目前,我做的游戏是V1.0版本的,只能说实现了这个游戏的基本功能:可以进行数独游戏.可以更换背景色以及一些其他的基本功能.接下来,在空余时间,我会进行对其中一Studying功能的实现

数独_个人项目

个人项目-数独 Github地址 https://github.com/ZhaoYi1031/Sudoku 花费时间 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划     ·Estimate ·估计这个任务需要多少时间 10 10 Development 开发     ·Analysis ·需求分析(包括学习新技术) 60 120 ·Design spec ·生成设计文档 0 0 ·Design Rev

2017BUAA软工个人项目之数独

1.项目GitHub地址:https://github.com/ZiJiaW/Soduko (由于一开始把sudoku看成了soduko,于是名字建错了,读起来可能有点奇怪-) 2.项目PSP表格如下: PSP2.1 Personal Software Process Stages 预估耗时 实际耗时 Planning 计划 0.5h 0.5h .Estimate .估计这个任务需要多少时间 0.5h 0.5h Development 开发 20.5h 21.5 .Analysis .需求分析(

#2018BIT软件工程基础#个人项目:数独

一.开发时间 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划     · Estimate · 估计这个任务需要多少时间 5 6 Development 开发     · Analysis · 需求分析 (包括学习新技术) 420 840 · Design Spec · 生成设计文档 120 180 · Design Review · 设计复审 (和同事审核设计文档) 10 20 · Coding Sta

软件工程基础-个人项目-数独

任务:实现一个能够生成数独局并且能求解数独问题的控制台程序. 1.GitHub:https://github.com/MiaoZhou48/SoftwareEngineeringProject 2.时间耗费 PSD2.1 Personnal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning  计划  40  40 .Estimate .估计这个任务需要多长时间     Development 开发  150  120 .Analysis .需求

BIT软工个人项目-数独

GitHub项目地址: https://github.com/FounDerSquare/SE-sudoku 一.任务 实现一个能够生成数独终局并且能求解数独问题的控制台程序. 提交的代码要求经过代码质量分析工具的分析并消除所有的警告. 对项目的首个版本使用性能分析工具找出性能瓶颈并改进. 及时维护仓库与博客. 二.PSP表格 PSP2.1 Personal Software Process Stages 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划 30 l  Estimat

第二次作业——个人项目实战:数独

1.阅读 刚开始泛看<构建之法>的时候,还是觉得非常难理解里面的内容,特别是代码部分.后来第二次拿起这本书,从第一章开始看起,慢慢了解了"软件企业=软件+商业模式"和对软件工程的定义,但是更多地还是记忆了一遍,没有明白这里面的深意:看第二章的时候,跟着单元测试.回归测试的.效能分析的内容自己照着书上的代码敲了一敲,偶尔会出现bug,但是能得到书上所说的效果还是很开心的,效能分析,感觉就是代码的效率问题,追求高效,然后接触到了软件工程师的一套模型-个人开发流程PSP,我也尝试

[2017BUAA软工]第一次个人项目 数独的生成与求解

零.Github链接 https://github.com/xxr5566833/sudo 一.PSP表格 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划     · Estimate · 估计这个任务需要多少时间 10   Development 开发     · Analysis · 需求分析 (包括学习新技术)  120   · Design Spec · 生成设计文档  60   · Design