#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>
#define PixelEnabled // 支持像素操作前先在编译选项加上 -lgdi32
using namespace std;
struct RandomGenerator {
int StartSeed;
int CurSeed;
int CurCount;
RandomGenerator() {
CurCount = 0;
CurSeed = time(0);
StartSeed = CurSeed;
srand(CurSeed);
}
RandomGenerator(int Seed) {
CurCount = 0;
CurSeed = Seed;
StartSeed = CurSeed;
srand(CurSeed);
}
void Srand(int Seed) {
CurCount = 0;
CurSeed = Seed;
StartSeed = CurSeed;
srand(CurSeed);
}
int Rand() {
++CurCount;
if (CurCount==0x8000) {
CurCount = 0;
CurSeed += (StartSeed^0x66CCFF)+1;
srand(CurSeed);
}
return rand();
}
int Rand32() {
return ((Rand()>>1)<<16)|Rand()|((Rand()&1)<<15);
}
int Rand(int Mod) {
return Rand32()%Mod;
}
} Rnd;
struct CuSO4 {
HDC Hdc;
HANDLE Hout;
int FQ[7] = {523,578,659,698,784,880,990};
double DeltaX, DeltaY;
double Rat;
CuSO4(bool k) {
if (!k) return;
Hdc = GetDC(GetConsoleWindow());
Hout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD dwMode = 0;
DeltaX = DeltaY = 0.0;
Rat = 1.0;
GetConsoleMode(Hout, &dwMode);
SetConsoleMode(Hout, dwMode|4);
#ifdef PixelEnabled
for (int i=0; i<100; ++i) {
for (int j=0; j<100; ++j) {
SetPixel(Hdc, i, j, 0);
}
}
#endif
}
void Beep(int X, int Ud, double Tm) { // 发出 X^{+Ud} 音调 Tm 秒
int T = int(round(Tm*500.0));
if ((X<1)||(X>7)) {
Sleep(T); return;
}
int F = FQ[X-1];
if (Ud>=0) F=(F<<Ud);
else F=(F>>(-Ud));
::Beep(F, T);
}
void Curpos(int x, int y) { // 光标移到 (x, y)
SetConsoleCursorPosition(Hout, {y,x});
}
int CursorX() {
POINT cp;
GetCursorPos(&cp);
return int(round(double(cp.y)*Rat+DeltaX));
}
int CursorY() {
POINT cp;
GetCursorPos(&cp);
return int(round(double(cp.x)*Rat+DeltaY));
}
void SystemColor(int x) { // 使用系统默认文本颜色
SetConsoleTextAttribute(Hout, x);
}
void Color(int R, int G, int B) { // 使用自定义文本颜色 (RGB)
wprintf(L"\x1b[38;2;%d;%d;%dm", R, G, B);
}
void Color(int x) { // 使用自定义文本颜色 (十六进制代码)
int R = (x>>16);
int G = ((x>>8)&((1<<8)-1));
int B = (x&((1<<8)-1));
Color(R, G, B);
}
void ResetCursor() { // 校准鼠标位置
system("cls");
SystemColor(7); Curpos(0,0);
printf("校准即将开始,请把窗口调整到合适大小、位置,然后按任意键继续...");
getch();
system("cls"); Curpos(0,0);
printf("请把鼠标移到红色标记中央,然后按下 [A] 键校准");
for (int i=195; i<=205; ++i) {
for (int j=195; j<=205; ++j) Plot(i,j,0xEE0000);
}
char ch = getch();
while ((ch!='A')&&(ch!='a')) ch=getch();
POINT cp;
GetCursorPos(&cp);
int A=cp.y, B=cp.x;
system("cls"); Curpos(0,0);
printf("请把鼠标移到红色标记中央,然后按下 [B] 键校准");
for (int i=395; i<=405; ++i) {
for (int j=395; j<=405; ++j) Plot(i,j,0xEE0000);
}
ch = getch();
while ((ch!='B')&&(ch!='b')) ch=getch();
GetCursorPos(&cp);
int C=cp.y, D=cp.x;
Rat = 200.0/double(D-B);
DeltaX = 200.0-Rat*double(A);
DeltaY = 200.0-Rat*double(B);
system("cls");
printf("校准完毕,请勿再移动窗口。按任意键继续...");
getch();
system("cls");
}
#ifdef PixelEnabled
void Plot(int x, int y, int R, int G, int B) { // 在 (x,y) 像素绘制颜色 (RGB)
SetPixel(Hdc, y+30, x+30, R+(G<<8)+(B<<16));
}
int Get(int x, int y) { // 查询 (x,y) 像素处的颜色 (十六进制代码)
int tmp = GetPixel(Hdc, y+30, x+30);
int R = (tmp&((1<<8)-1));
int G = ((tmp>>8)&((1<<8)-1));
int B = (tmp>>16);
return (R<<16)+(G<<8)+B;
}
void Plot(int x, int y, int clr) { // 在 (x,y) 像素绘制颜色 (十六进制代码)
Plot(x, y, (clr>>16), ((clr>>8)&((1<<8)-1)), (clr&((1<<8)-1)));
}
#endif
int Mix(int ca, int cb, double rt) { // 颜色 ca 和 cb 按 rat 比例混合 (十六进制代码)
int Ar = (ca>>16);
int Ag = ((ca>>8)&((1<<8)-1));
int Ab = (ca&((1<<8)-1));
int Br = (cb>>16);
int Bg = ((cb>>8)&((1<<8)-1));
int Bb = (cb&((1<<8)-1));
int R = int(floor(rt*double(Ar)+(1.0-rt)*double(Br)));
int G = int(floor(rt*double(Ag)+(1.0-rt)*double(Bg)));
int B = int(floor(rt*double(Ab)+(1.0-rt)*double(Bb)));
return (max(0,min(255,R))<<16)+(max(0,min(255,G))<<8)+max(0,min(255,B));
}
} Sc(1);
double a[2010][2010];
vector<pair<int,int> > v;
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
int n;
int bel(double x) {
return int(floor(x*5.0));
}
int bel2(double x) {
return int(floor(x*15.0));
}
double lower_lim = 0.05;
double upper_lim = 0.5;
bool lower(double x) {
return x<lower_lim;
}
bool fff = true;
void ep(int i, int j) {
if (!fff) return;
int clr;
if (a[i][j]<=upper_lim) clr=Sc.Mix(0xAAFF80,0x35601D,a[i][j]/upper_lim);
else clr=Sc.Mix(0xFFFFFF,0xAAFF80,(a[i][j]-upper_lim)/(2.1-upper_lim));
Sc.Plot(i, j, clr);
}
void smooth(int cnt) {
int sz=n*n, m=cnt*sz;
int cc = 0;
while (m--) {
int x=cc/n+1, y=cc%n+1;
++cc; if (cc>=sz) cc-=sz;
int d=Rnd.Rand(4), nx=x+dx[d], ny=y+dy[d];
if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
double p=a[x][y], q=a[nx][ny];
a[x][y]=(p+p+q)/3.0; a[nx][ny]=(p+q+q)/3.0;
ep(x,y); ep(nx,ny);
}
}
void asmooth(int cnt) {
int sz=n*n, m=cnt*sz;
int cc = 0;
while (m--) {
int x=cc/n+1, y=cc%n+1;
++cc; if (cc>=sz) cc-=sz;
int d=Rnd.Rand(4), nx=x+dx[d], ny=y+dy[d];
if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
double p=a[x][y], q=a[nx][ny];
a[x][y]=q; a[nx][ny]=p;
ep(x,y); ep(nx,ny);
}
}
int main() {
fff = false;
if (fff) getch();
Rnd.Srand(1);
n = 1300;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=n; ++j) {
v.push_back(make_pair(i,j)); a[i][j]=-1;
}
}
int sz = n*n;
for (int i=0; i<sz; ++i) swap(v[i],v[Rnd.Rand(sz)]);
for (int i=0; i<sz; ++i) {
int x=v[i].first, y=v[i].second;
if (a[x][y]>=-0.5) continue;
int bbc = 100000;
double val = Rnd.Rand(1025)/1024.0;
int num = Rnd.Rand(bbc);
while (num--) {
int d=Rnd.Rand(4), nx=x+dx[d], ny=y+dy[d];
if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
a[x][y]=val; x=nx; y=ny;
}
}
for (int i=1; i<=n; ++i) {
for (int j=1; j<=n; ++j) ep(i,j);
}
asmooth(20000000/sz);
for (int i=1; i<=n; ++i) {
for (int j=1; j<=n; ++j) {
int dis = int(sqrt(i*i+j*j));
double rat = 1.0-double(dis)/sqrt(n*n)*1.1;
rat = 2.0*max(0.0275,rat);
a[i][j] = a[i][j]*rat+rat*0.1;
ep(i, j);
}
}
for (int i=0; i<sz; ++i) swap(v[i],v[Rnd.Rand(sz)]);
for (int i=0; i<sz/15000; ++i) {
int x=v[i].first, y=v[i].second;
int bbc = 10000;
double val=Rnd.Rand(1025)/1024.0; val*=val;
val *= min(2.0,a[x][y]+0.3);
int num = Rnd.Rand(bbc);
while (num--) {
int d=Rnd.Rand(4), nx=x+dx[d], ny=y+dy[d];
if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
a[x][y]=val; x=nx; y=ny;
ep(x, y);
}
}
smooth(10000000/sz);
getch();
for (;;) {
for (int s=0; s<sz; ++s) {
int i=v[s].first, j=v[s].second;
bool flag=false, flag2=false, bord=false;
for (int d=0; d<4; ++d) {
int nx=i+dx[d], ny=j+dy[d];
if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
if (bel(a[i][j])>bel(a[nx][ny])) flag=true;
if (bel2(a[i][j])>bel2(a[nx][ny])) flag2=true;
if (lower(a[i][j])<lower(a[nx][ny])) bord=true;
}
if (bord) Sc.Plot(i,j,0x0775BF);
else if (lower(a[i][j])) {
Sc.Plot(i, j, Sc.Mix(0x49B6FF,0x0775BF,a[i][j]/lower_lim));
}
else {
int clr;
if (a[i][j]<=upper_lim) clr=Sc.Mix(0xAAFF80,0x35601D,a[i][j]/upper_lim);
else clr=Sc.Mix(0xFFFFFF,0xAAFF80,(a[i][j]-upper_lim)/(2.1-upper_lim));
if (flag) clr=Sc.Mix(0x000000,clr,0.5);
else if (flag2) clr=Sc.Mix(0x000000,clr,0.2);
Sc.Plot(i, j, clr);
}
}
}
return 0;
}