程序截图
简单说明
随机生成数独的算法见力扣上对应题目的题解,我用的是递归回溯法
先随机放入 11 个数就能生成一个数独然后求数独的解最后选择要显示的数字再显示出来。这里还用到了洗牌算法选择要随机显示的数字。
代码实现
TCW_GUI.h
// 程序:数独
// 编译环境:Visual Studio 2019,EasyX_20211109
#pragma once
#include<graphics.h>
#include<string>
#include<list>
#include<functional>
#include<stdio.h>
#pragma comment( lib, "MSIMG32.LIB")
#define TCW_GUI_BUTTON_MYSELF 0
#ifdef UNICODE
#define STRING std::wstring
#define SPRINTF swprintf_s
#define SSCANF swscanf_s
#else
#define STRING std::string
#define SPRINTF sprintf
#define SSCANF sscanf
#endif // UNICODE
namespace TCW_GUI
{
enum class State
{
general = 0,
touch = 1,
press = 2,
release = 3,
forbidden = 4
};
enum class DrawDecision
{
text = 0,
graph = 1
};
class Vec2
{
public:
double x, y;
Vec2() :x(0), y(0) {}
Vec2(double xx, double yy) :x(xx), y(yy) {};
Vec2 operator+(Vec2 num)
{
return Vec2(x + num.x, y + num.y);
}
Vec2 operator-(Vec2 num)
{
return Vec2(x - num.x, y - num.y);
}
Vec2 operator/(double num)
{
return Vec2(x / num, y / num);
}
Vec2 operator*(double num)
{
return Vec2(x * num, y * num);
}
};
class Rect
{
public:
Rect() :size(), position() {}
Rect(Vec2 position, Vec2 size) :size(size), position(position) {}
Vec2 size;
Vec2 position;
bool isInRect(Vec2 point)
{
Vec2 left_top = position - size / 2.0;
Vec2 right_buttom = position + size / 2.0;
if (point.x >= left_top.x && point.y >= left_top.y &&
point.x <= right_buttom.x && point.y <= right_buttom.y)return true;
return false;
}
};
class Button
{
private:
double textsize = 20;
double textareasize = 0.9;
Vec2 defaultsize;
Vec2 defaulttext;
State nowstate = State::general;
DrawDecision drawdecision = DrawDecision::text;
void DrawButton_General();
void DrawButton_Touch();
void DrawButton_Press();
void DrawButton_Forbidden();
bool isPress = false;
public:
Button() :boundingbox(), buttontext()
{
settextstyle(textsize, 0, TEXT("微软雅黑"));
Vec2 defaultsize = Vec2(textwidth(TEXT("...")) / textareasize, textheight(TEXT("...")) / textareasize);
Vec2 defaulttext = Vec2(textwidth(TEXT("...")), textheight(TEXT("...")));
}
Button(Rect boundingbox, STRING buttontext, std::function<int(void*)> releaseFunc, void* releaseParam) :
boundingbox(boundingbox), buttontext(buttontext), releaseFunc(releaseFunc), releaseParam(releaseParam)
{
drawdecision = DrawDecision::text;
settextstyle(textsize, 0, TEXT("微软雅黑"));
Vec2 defaultsize = Vec2(textwidth(TEXT("...")) / textareasize, textheight(TEXT("...")) / textareasize);
Vec2 defaulttext = Vec2(textwidth(TEXT("...")), textheight(TEXT("...")));
}
Button(Rect boundingbox, STRING graphsrc_normal, STRING graphsrc_touch, STRING graphsrc_press,
std::function<int(void*)> releaseFunc, void* releaseParam) :
boundingbox(boundingbox), graphsrc_normal(graphsrc_normal), graphsrc_touch(graphsrc_touch), graphsrc_press(graphsrc_press),
releaseFunc(releaseFunc), releaseParam(releaseParam)
{
drawdecision = DrawDecision::graph;
}
STRING buttontext;
STRING graphsrc_normal;
STRING graphsrc_touch;
STRING graphsrc_press;
Rect boundingbox;
std::function<int(void*)> releaseFunc = nullptr;
void* releaseParam = nullptr;
void DrawButton();
void DrawButton_Text(State state);
void DrawButton_Graph(State state);
void receiver(ExMessage* msg);
void ForbidButton() { this->nowstate = State::forbidden; } // 禁用按钮
void RefreshButton() { this->nowstate = State::general; } // 恢复按钮
void SetTextSize(double size)
{
textsize = size;
defaultsize = Vec2(textsize * 1.5 / textareasize, textsize / textareasize);
defaulttext = Vec2(textsize * 1.5, textsize);
}
void SetTextAreaSize(double size)
{
textareasize = size;
defaultsize = Vec2(textsize * 1.5 / textareasize, textsize / textareasize);
defaulttext = Vec2(textsize * 1.5, textsize);
}
};
class ButtonManager
{
std::list<Button> buttonlist;
public:
Button* AddButton(Button button);
void ReceiveMessage(ExMessage* msg);
void DrawButton();
};
void Rectangle_TCW(Vec2 left_top, Vec2 right_buttom)
{
rectangle(left_top.x, left_top.y, right_buttom.x, right_buttom.y);
}
void Fillrectangle_TCW(Vec2 left_top, Vec2 right_buttom)
{
fillrectangle(left_top.x, left_top.y, right_buttom.x, right_buttom.y);
}
void Outtextxy_TCW(Vec2 position, const TCHAR* str)
{
outtextxy(position.x, position.y, str);
}
void Button::DrawButton_Text(State state)
{
LOGFONT log;
COLORREF textcol;
COLORREF linecol;
COLORREF fillcol;
int bkmode;
gettextstyle(&log);
bkmode = getbkmode();
textcol = gettextcolor();
linecol = getlinecolor();
fillcol = getfillcolor();
// 默认数值
settextstyle(textsize, 0, TEXT("微软雅黑"));
settextcolor(BLACK);
setbkmode(TRANSPARENT);
setlinecolor(BLACK);
setfillcolor(WHITE);
switch (state)
{
case TCW_GUI::State::general:
break;
case TCW_GUI::State::touch:
setfillcolor(RGB(240, 240, 240));
break;
case TCW_GUI::State::press:
setfillcolor(RGB(240, 240, 240));
break;
case TCW_GUI::State::release:
break;
case TCW_GUI::State::forbidden:
settextcolor(RGB(128, 128, 128));
break;
default:
break;
}
Vec2 size_button = Vec2(this->boundingbox.size * textar