基本的十字绣线性生成中提供了判断下一步可以画的位置并且逐步生成的函数。以这些基本函数为基础,可以进行更多变化的图案设计。

为了方便的扩展,可以把线性生成写成一个类,以后的修改继承这个类。

头文件BasicBoard.h

//基本的生成函数,有run和mutiRun两种运行方式。
//run会按照朝着四个方向延伸且不和其他已有图案碰撞的方式生成图像。生成到没有可以画的点就停止
//mutiRun则是在run的基础上,在可以找到新的起点的时候继续画图,直到没有起点 #include <iostream>
#include <set>
#include <list>
#include <ctime>
#include <cstdlib>
#include <string>
#include <windows.h> #define ROW 51 //行数
#define COL 51 //列数
#define seedX ROW/2 //初始行号
#define seedY COL/2 //初始列号
#define random(x) (rand()%x) //随机数 using namespace std; struct point
{
int x;
int y;
};
struct compare //set的排序函数
{
bool operator()(const point &p1,const point &p2)const
{
//return p1.x * COL + p1.y < p2.x * COL + p2.y;
return p1.x==p2.x ? p1.y<p2.y: p1.x<p2.x;
}
}; class BasicBoard
{
public:
void run();//运行并画图
void run(int x, int y); //带种子参数的run
void mutiRun();//运行一次之后找新的起点继续运行,直到没有起点
void init();
void print();
void print(set<point,compare> pl);
bool isNext(int x, int y, char dir);
void findAndErase(point p, set<point,compare> &nextSet);
virtual void setNextSet(point seed, set<point,compare> &nextSet);
set<point,compare>::iterator getNextIter(set<point,compare> &nextSet);
virtual void drawNext(set<point,compare> &nextSet); virtual void generate(point &seed);
virtual bool getSeed(point &seed); //获取可以开始的位置,该位置周围8个格子均为空
void printAs();//输出
protected:
int b[ROW][COL];
};

实现文件BasicBoard.cpp

#include "BasicBoard.h"
void BasicBoard::run()
{
init();
point seed;
seed.x = seedX;
seed.y = seedY;
generate(seed);
printAs();
}
void BasicBoard::run(int x, int y)
{
init();
point seed;
seed.x = x;
seed.y = y;
generate(seed);
printAs();
}
void BasicBoard::mutiRun()
{
init();
point seed;
while(getSeed(seed))
{
generate(seed);
}
printAs();
}
void BasicBoard::init() //初始化,全部置0
{
for(int i=0;i<ROW;i++)
{
for(int j=0;j<COL;j++)
{
b[i][j]=0;
}
}
} void BasicBoard::print() //打印画布01序列
{
for(int i=0;i<ROW;i++)
{
for(int j=0;j<COL;j++)
{
cout<<b[i][j];
}
cout<<endl;
}
}
void BasicBoard::printAs() //以方块形式打印图案
{
string b2[ROW][COL];
int count = 0;
for(int i=0; i<ROW; i++)
{
for(int j=0; j<COL; j++)
{
if(b[i][j])
{
b2[i][j]="■";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0xF1);
/*输出颜色说明。导入windows.h,使用SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x71)。参数中的16进制数字第一位表示背景颜色,第二位表示文字颜色,代码含义为
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 A = 淡绿色
3 = 湖蓝色 B = 淡浅绿
4 = 红色 C = 淡红色
5 = 紫色 D = 淡紫色
6 = 黄色 E = 淡黄色
7 = 白色 F = 亮白色
如果背景为“白色”,会显示cmd默认的颜色
*/ count++;
}
else
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0xF9);
b2[i][j]="□";
}
cout<<b2[i][j];
} cout<<count<<endl;
} }
void BasicBoard::print(set<point,compare> pl) //测试函数,打印set中的值
{
set<point,compare>::iterator iter = pl.begin();
for(; iter!=pl.end(); iter++)
{
cout<<iter->x<<","<<iter->y<<" - ";
}
cout<<endl;
} bool BasicBoard::isNext(int x, int y, char dir) //判断某个位置是不是可以画下一笔 {
if(0<x && ROW-1>x && 0<y && COL-1>y)
{
int temp = 0;
switch(dir)
{
case 'U':
{ temp = b[x-1][y-1]+b[x-1][y]+b[x-1][y+1]+b[x][y-1]+b[x][y]+b[x][y+1]; break;
}
case 'D':
{
temp = b[x][y-1]+b[x][y]+b[x][y+1]+b[x+1][y-1]+b[x+1][y]+b[x+1][y+1];
break;
}
case 'L':
{
temp = b[x-1][y-1]+b[x-1][y]+b[x][y-1]+b[x][y]+b[x+1][y-1]+b[x+1][y];
break;
}
case 'R':
{
temp = b[x-1][y]+b[x-1][y+1]+b[x][y]+b[x][y+1]+b[x+1][y]+b[x+1][y+1];
break;
}
}
if(temp==0)
return true;
}
return false;
}
void BasicBoard::findAndErase(point p, set<point,compare> &nextSet) //新添加点之后,删除候选列表中不能继续画的点
{
set<point,compare>::iterator iterErase;
iterErase = nextSet.find(p);
if(iterErase != nextSet.end())
{
nextSet.erase(iterErase);
}
}
void BasicBoard::setNextSet(point seed, set<point,compare> &nextSet) //设置候选列表
{
int x = seed.x;//x为行,y为列
int y = seed.y; point p;
p.x = x-1;
p.y = y;
if(isNext(x-1,y,'U'))
{
nextSet.insert(p);
}
else
{
findAndErase(p,nextSet);
}
p.x = x+1;
p.y = y;
if(isNext(x+1,y,'D'))
{ nextSet.insert(p);
}
else
{
findAndErase(p,nextSet);
}
p.x = x;
p.y = y-1;
if(isNext(x,y-1,'L'))
{
nextSet.insert(p);
}
else
{
findAndErase(p,nextSet);
}
p.x = x;
p.y = y+1;
if(isNext(x,y+1,'R'))
{
nextSet.insert(p);
}
else
{
findAndErase(p,nextSet);
}
p.x = x-1;
p.y = y-1;
findAndErase(p,nextSet); //角上相邻的
p.x = x+1;
p.y = y-1;
findAndErase(p,nextSet);
p.x = x-1;
p.y = y+1;
findAndErase(p,nextSet);
p.x = x+1;
p.y = y+1;
findAndErase(p,nextSet); } //通过随机数获取下一步的位置。种子在main中生成
set<point,compare>::iterator BasicBoard::getNextIter(set<point,compare> &nextSet)
{
int count = nextSet.size();
set<point,compare>::iterator iterNext = nextSet.begin();
int pos = int(random(count)); for(int i = 0; i<pos; i++)
{
iterNext++;
}
return iterNext;
}
//画下一格:从候选里面选出一个;更改b的值;判断它四个正方向的候选,如果是候选加入,不是候选尝试查找删除;判断它四个斜方向,从候选列表删除。
void BasicBoard::drawNext(set<point,compare> &nextSet)
{ set<point,compare>::iterator iterNext;
iterNext = getNextIter(nextSet);
point next;
next.x = iterNext->x;
next.y = iterNext->y;
b[next.x][next.y]=1;
nextSet.erase(iterNext);
setNextSet(next, nextSet);
} void BasicBoard::generate(point &seed)
{
b[seed.x][seed.y]=1;
set<point,compare> nextSet; setNextSet(seed,nextSet);
while(!nextSet.empty())
{
drawNext(nextSet);
}
} //生成新的种子。方法是找到所有可以做种子的点然后随机选一个。
bool BasicBoard::getSeed(point &seed)
{ list<point> seedList;
int count = 0;
for(int x = 1; x<ROW-1; x++)
{
for(int y = 1; y<COL-1; y++)
{
if(b[x-1][y-1]+b[x-1][y]+b[x-1][y+1]+b[x][y-1]+b[x][y]+b[x][y+1]+b[x+1][y-1]+b[x+1][y]+b[x+1][y+1]==0)
{
seed.x = x;
seed.y = y;
seedList.push_back(seed);
count++;
}
}
}
if(count==0)
{ return false;}
list<point>::iterator iter = seedList.begin();
int pos = int(random(count)); for(int i = 0; i<pos; i++)
{
iter++;
}
seed.x = iter->x;
seed.y = iter->y;
return true;
}

main函数

#include "BasicBoard.h"

void main()
{
srand(unsigned(time(0)));
BasicBoard b;
b.run();
}

C++生成十字绣图案(二) 面向对象的更多相关文章

  1. 2018-2019-2 20175306实验二面向对象程序设计《Java开发环境的熟悉》实验报告

    2018-2019-2 20175306实验二面向对象程序设计<Java开发环境的熟悉>实验报告 面向对象程序设计-1 实验要求: 参考:> http://www.cnblogs.c ...

  2. 2018-2019-20175205实验二面向对象程序设计《Java开发环境的熟悉》实验报告

    2018-2019-20175205实验二面向对象程序设计<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>< ...

  3. 20175212童皓桢 Java实验二-面向对象程序设计实验报告

    20175212童皓桢 Java实验二-面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设 ...

  4. #2019-2020-4 实验二面向对象程序设计《Java开发环境的熟悉》实验报告

    2019-2020-4 实验二面向对象程序设计<Java开发环境的熟悉>实验报告 一.面向对象程序设计-1 ①实验要求: 1.参考 http://www.cnblogs.com/roced ...

  5. 20165317JAVA实验二-面向对象程序设计

    JAVA实验二-面向对象程序设计 提交点一 参考Intellj IDEA 简易教程-单元测试完成单元测试的学习 在IDEA中建立名为MyUtil5317的project,并在其src文件夹中创建名为M ...

  6. Java生成与解析二维码

    1.下载支持二维码的jar包qrcode.jar和qrcode_swetake.jar, 其中qrcode_swetake.jar用于生成二维码,rcode.jar用于解析二维码,jar包下载地址(免 ...

  7. asp.net.web如何简单生成和保存二维码图片的例子

    首先,要有生成二维码图片,需要二维码生成的类库,到官网下载thoughtWorks.QRCode.dll 例子的步骤: 1.创建项目QRCodeTest1,选择asp.net.web窗体应用程序

  8. python实现树莓派生成并识别二维码

    python实现树莓派生成并识别二维码 参考来源:http://blog.csdn.net/Burgess_Liu/article/details/40397803 设备及环境 树莓派2代 官方系统R ...

  9. ZXing 生成、解析二维码图片的小示例

    概述 ZXing 是一个开源 Java 类库用于解析多种格式的 1D/2D 条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME ...

随机推荐

  1. DataTable初次使用笔记

    概述:DataTable是一个jQuery插件,用于生成HTML表格,功能很强大. 使用: 使用DataTable需要引入jQuery,因为他是基于jQuery的插件,然后引入DataTable的js ...

  2. Tomcat启动异常 java.net.BindException: Cannot assign requested address: JVM_Bind

    从Apache官网下载的tomcat7,在MyEclipse中启动时抛出如下异常: 严重: StandardServer.await: create[localhost:8005]: java.net ...

  3. Zookeeper Monitor集群监控开发

    随着线上越来越多的系统依赖Zookeeper集群.以至于Zookeeper集群的执行状况越来越重要.可是眼下还没有什么好用的Zookeeper集群监控系统(淘宝开源了一个Zookeeper监控系统,可 ...

  4. QT 开发资料

    http://pan.baidu.com/s/1bntYkpx 密码: fgsa

  5. jQuery 二级菜单,一次显示一个小类 鼠标点击显示小类

    jQuery 二级菜单,一次显示一个小类 鼠标点击显示小类 本例有另外2个关联案例,演示地址分别为2.php,3.php 演示 XML/HTML Code <div class="ar ...

  6. MVC批量更新,使用jQuery Template

    在"MVC批量更新,可验证并解决集合元素不连续控制器接收不完全的问题"中,当点击"添加"按钮的时候,通过部分视图,在界面上添加新行.本篇体验使用jQuery T ...

  7. org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundaryRAYPKeHKTYSNdzc1;charset=UTF-8' not supported

    原文:https://www.cnblogs.com/yueli/p/7552888.html 最近同事在做一个图片上传功能.在入参 body 中同时传入文件和其它基本信息结果出现如题异常.在此记录下 ...

  8. linux升级mysql到5.7

    原文:http://blog.csdn.net/qing_gee/article/details/41774265 Linux升级MySQL版本到5.7. 1.下载Linux的5.7版本,主要需要两个 ...

  9. DAO,Service接口与实现类设计

    DAO接口 为每个DAO声明接口的好处在于 1. 可以在尚未实现具体DAO的时候编写上层代码,如Service里对DAO的调用 2. 可以为DAO进行多实现,例如有JDBCDAO实现,MyBatisD ...

  10. 数据库实例: STOREBOOK > 表空间 > 编辑 表空间: TEMP

    ylbtech-Oracle:数据库实例: STOREBOOK  >  表空间  >  编辑 表空间: TEMP 表空间  >  编辑 表空间: TEMP 1. 一般信息返回顶部 1 ...