#ifndef CDEx_H
#define CDEx_H
#include<bits/stdc++.h>
#include<windows.h>
#define KEYDOWN(name) (((GetAsyncKeyState(name)&0x8000)?1:0) && now_window==GetForegroundWindow())
using namespace std;
HWND now_window=GetForegroundWindow();//当前窗口
bool init_flag=0;
struct xy
{
int x,y;
bool operator == (const xy nxt)const
{
return x==nxt.x && y==nxt.y;
}
bool operator != (const xy nxt)const
{
return x!=nxt.x || y!=nxt.y;
}
xy operator + (const xy nxt)const
{
return {x+nxt.x,y+nxt.y};
}
xy operator - (const xy nxt)const
{
return {x-nxt.x,y-nxt.y};
}
int to_quadrant(xy p)
{
if(p.x<=x && p.y>y)return 1;
if(p.x<x && p.y<=y)return 2;
if(p.x>=x && p.y<y)return 3;
if(p.x>x && p.y>=y)return 4;
return 0;
}
char out(string s=",")
{
cout<<x<<s<<y;
return '\0';
}
};
struct picture
{
int l,h;
vector<string>g;
};
xy py_xy={0,0};
void tset(xy p)
{
py_xy=p;
}
xy tget()
{
return py_xy;
}
xy tcde(xy p)
{
return p+py_xy;
}
xy tdef(xy p)
{
return p-py_xy;
}
namespace Tool
{
void sleep(int ms)
{
Sleep(ms);
}
bool mouse_down(int left,int mid,int right)//是否按下鼠标
{
bool flag=1;
if(left)
flag=flag && KEYDOWN(VK_LBUTTON);
if(mid)
flag=flag && KEYDOWN(VK_MBUTTON);
if(right)
flag=flag && KEYDOWN(VK_RBUTTON);
return flag;
}
xy mousexy()//获取鼠标字符位置
{
HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
if(hOutput==INVALID_HANDLE_VALUE)
return {0,0};
CONSOLE_FONT_INFO ft_size;
if(!GetCurrentConsoleFont(hOutput,FALSE,&ft_size))
return {0,0};
POINT p;
GetCursorPos(&p);
ScreenToClient(GetForegroundWindow(),&p);
return {p.y/ft_size.dwFontSize.Y,p.x/ft_size.dwFontSize.X};
}
}
class Item
{
private:
void gotoxy(xy po)//移动字符位置
{
COORD pos={(short)po.y,(short)po.x};
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,pos);
}
void init()
{
if(!init_flag)
{
CONSOLE_CURSOR_INFO cciCursor;
HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
if(GetConsoleCursorInfo(hStdOut,&cciCursor))
{
cciCursor.bVisible=FALSE;
SetConsoleCursorInfo(hStdOut,&cciCursor);
}
HANDLE hStdin=GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin,&mode);
mode&=~ENABLE_QUICK_EDIT_MODE;
SetConsoleMode(hStdin,mode);
init_flag=1;
}
}
string turn(string str)
{
string s=str;
for(int i=0;i<(int)s.size();i++)
{
if(s[i]=='`')//空格
s[i]=' ';
}
return s;
}
void load(string file)
{
ifstream fin(file);
ng="";
fin>>len>>hei;
for(int i=1;i<=len;i++)
{
string str;fin>>str;
ng+=str;
str=turn(str);
g.push_back(str);
}
fin.close();
}
string strs(string s,int times)
{
string str="";
for(int i=1;i<=times;i++)
str+=s;
return str;
}
protected:
xy pxy;
int len,hei,hidemode,fac;
vector<string>g;
string ng;
//克隆组
vector<Item>clone;
vector<int>vis;
bool killmode;
//图片组
map<string,picture>group;
//动画组
map<string,vector<string> >anime;
map<string,int>anime_frame;
int clone_clear_v()
{
for(int i=vis.size()-1;i>=0;i--)
if(!vis[i])clone.pop_back(),vis.pop_back();
else break;
return vis.size();
}
Item jc_item()
{
Item p(pxy,1);
p.group_set(group);
p.code_load(len,hei,ng);
if(hidemode)p.hide();
else p.show();
p.fac=fac;
p.T_int=T_int;
p.T_double=T_double;
p.T_string=T_string;
p.Tmap_int=Tmap_int;
p.Tmap_double=Tmap_double;
p.Tmap_string=Tmap_string;
return p;
}
#define PI 3.14159265369
double sin_(double x)
{
return sin(x*PI/180);
}
double cos_(double x)
{
return cos(x*PI/180);
}
double tan_(double x)
{
return tan(x*PI/180);
}
double asin_(double x)
{
return asin(x)*180/PI;
}
double acos_(double x)
{
return acos(x)*180/PI;
}
double atan_(double x)
{
return atan(x)*180/PI;
}
#undef PI
public:
//本体变量组
vector<int>T_int;
vector<double>T_double;
vector<string>T_string;
map<string,int>Tmap_int;
map<string,double>Tmap_double;
map<string,string>Tmap_string;
//初始化组
Item(xy p,int hide=0)
{
pxy=p;
hidemode=hide;
killmode=0;
fac=0;
init();
}
Item()
{
pxy={0,0};
hidemode=0;
killmode=0;
fac=0;
init();
}
//获取组
xy get_xy()
{
return pxy;
}
int get_len()
{
return len;
}
int get_hei()
{
return hei;
}
int get_hidemode()
{
return hidemode;
}
int get_facing()
{
return fac;
}
vector<string> get_g()
{
return g;
}
string get_gline(int line)
{
return g[line-1];
}
xy get_mousexy()
{
return Tool::mousexy();
}
bool get_killmode()
{
return killmode;
}
map<string,picture> get_group()
{
return group;
}
picture get_groupline(string name)
{
return group[name];
}
vector<Item> get_clone()
{
vector<Item>v;
for(int i=0;i<(int)clone.size();i++)
if(vis[i])
v.push_back(clone[i]);
return v;
}
xy get_center()//获取图片的中心位置
{
xy acenter={len/2,hei/2};
return pxy+acenter;
}
double get_to_facing(xy p)
{
int F=pxy.to_quadrant(p);
int xs=abs(pxy.x-p.x);
int ys=abs(pxy.y-p.y);
if(F==1) return atan_(1.0*ys/xs);
if(F==4) return 90+atan_(1.0*xs/ys);
if(F==3) return 180+atan_(1.0*ys/xs);
if(F==2) return 270+atan_(1.0*xs/ys);
return 0;
}
xy get_len_xy(double len,double block_mode=2)
{
bool flag=0;
if(len<0)
flag=1,len=-len,left(180);
block_mode=abs(block_mode);
int nx=pxy.x,ny=pxy.y;
int nf=fac%90;
if(fac>=0 && fac<90)
nx-=round(cos_(nf)*len),ny+=round(block_mode*sin_(nf)*len);
if(fac>=90 && fac<180)
nx+=round(sin_(nf)*len),ny+=round(block_mode*cos_(nf)*len);
if(fac>=180 && fac<270)
nx+=round(cos_(nf)*len),ny-=round(block_mode*sin_(nf)*len);
if(fac>=270 && fac<360)
nx-=round(sin_(nf)*len),ny-=round(block_mode*cos_(nf)*len);
if(flag)
left(180);
return xy{nx,ny};
}
double get_to_facing(Item p,bool facing_center=1)
{
if(facing_center)
return get_to_facing(p.get_center());
return get_to_facing(p.get_xy());
}
//导入组
void file_load(string file,string s="")
{
clear();
file+=".cditem";
g.clear();
load(file);
draw();
if(s!="")
group_load(s);
}
void code_load(int l,int h,string str,string s="")
{
clear();
g.clear();
len=l,hei=h;
ng="";
for(int i=0;i<l*h;i+=h)
{
string s="";
for(int j=i;j<i+h;j++)
s+=str[j];
ng+=s;
g.push_back(turn(s));
}
draw();
if(s!="")
group_load(s);
}
void code_load(int l,string str,string s="")
{
clear();
g.clear();
int h=str.size()/l;
len=l,hei=h;
ng="";
for(int i=0;i<l*h;i+=h)
{
string s="";
for(int j=i;j<i+h;j++)
s+=str[j];
ng+=s;
g.push_back(turn(s));
}
draw();
if(s!="")
group_load(s);
}
//绘制组
void draw()
{
if(!hidemode && !crash_edge())
{
for(int i=0;i<(int)g.size();i++)
{
gotoxy({pxy.x+i,pxy.y});
cout<<g[i];
}
}
}
void clear()
{
if(!crash_edge())
{
for(int i=0;i<(int)g.size();i++)
{
gotoxy({pxy.x+i,pxy.y});
cout<<strs(" ",(int)g[i].size());
}
}
}
//动作组
bool goto_xy(xy p,xy py={0,0})
{
clear();
p=p+py;
if(crash_edge(p))
return 0;
pxy=p;
draw();
return 1;
}
bool goto_item(Item p,xy py={0,0})
{
return goto_xy(p.get_xy(),py);
}
bool move_xy(int x,int y)
{
clear();
if(crash_edge({pxy.x+x,pxy.y+y}))
return 0;
pxy={pxy.x+x,pxy.y+y};
draw();
return 1;
}
bool move_xy(xy p)
{
return move_xy(p.x,p.y);
}
void towards(int new_fac)
{
new_fac%=360;
if(new_fac<0)new_fac=360+new_fac;
fac=new_fac;
}
void towards(Item p,bool facing_center=1)
{
towards(round(get_to_facing(p,facing_center)));
}
void towards(xy p)
{
towards(round(get_to_facing(p)));
}
void left(int ang)
{
towards(fac-ang);
}
void right(int ang)
{
towards(fac+ang);
}
bool forward(double lens,double block_mode=2)
{
return goto_xy(get_len_xy(lens,block_mode));
}
bool forward_run(double lens,void *fun(xy),double block_mode=2)
{
xy p=pxy;
bool flag=1;
for(int i=0;i<=abs(lens);i++)
{
forward((lens<0?-i:i),block_mode),fun(pxy),flag=goto_xy(p);
if(!flag)return 0;
}
return 1;
}
bool backward(double lens,double block_mode=2)
{
return forward(-lens,block_mode);
}
bool backward_run(double lens,void *fun(xy),double block_mode=2)
{
return forward_run(-lens,fun,block_mode);
}
void hide()
{
hidemode=1;
clear();
}
void show()
{
hidemode=0;
draw();
}
void kill()
{
killmode=1;
clear();
}
//克隆组
void clone_this()//克隆自己
{
Item p=jc_item();
int u=-1;
for(int i=0;i<(int)vis.size();i++)
if(!vis[i])u=i;
if(u==-1)
clone.push_back(p),vis.push_back(1);
else
clone[u]=p,vis[u]=1;
clone_clear_v();
}
void clone_item(Item p)//克隆图片
{
int u=-1;
for(int i=0;i<(int)vis.size();i++)
if(!vis[i])u=i;
if(u==-1)
clone.push_back(p),vis.push_back(1);
else
clone[u]=p,vis[u]=1;
clone_clear_v();
}
void clone_run(Item (*fun)(Item))
{
for(int i=0;i<(int)clone.size();i++)
if(vis[i])
{
clone[i]=fun(clone[i]);
if(clone[i].get_killmode())
vis[i]=0;
}
clone_clear_v();
}
void clone_clear()
{
for(int i=0;i<(int)clone.size();i++)
if(vis[i])
clone[i].clear();
clone.clear();
vis.clear();
}
int clone_size()
{
int sum=0;
for(int i=0;i<(int)clone.size();i++)
if(vis[i])
sum++;
return sum;
}
//图片组
void group_load(string name)
{
group[name]=(picture){len,hei,g};
}
void group_item(string name,Item p)
{
group[name]=(picture){p.get_len(),p.get_hei(),p.get_g()};
}
void group_use(string name)
{
clear();
picture p=group[name];
len=p.l,hei=p.h;
g=p.g;
draw();
}
void group_erase(string name)
{
group.erase(name);
}
void group_set(map<string,picture>p)
{
group=p;
}
//动画组
void frame_add(string name,string pname)
{
anime[name].push_back(pname);
anime_frame[name]=0;
}
void frame_clear(string name)
{
anime[name].clear();
anime_frame[name]=0;
}
void frame_use(string name,int start)
{
start=(start-1)%anime[name].size();
anime_frame[name]=start;
group_use(anime[name][anime_frame[name]]);
}
void frame_next(string name)
{
anime_frame[name]=(anime_frame[name]+1)%anime[name].size();
group_use(anime[name][anime_frame[name]]);
}
/*暂不提供此函数
void frame_set(string name,int index,string pname)
{
index=(index-1)%anime[name].size();
anime[name][index]=pname;
if(index==anime_frame[name])
group_use(anime[name][anime_frame[name]]);
}
*/
vector<string> frame_get(string name)
{
return anime[name];
}
int frame_get_frame(string name)
{
return anime_frame[name];
}
//碰撞组
bool crash_mouse(bool must_show=1)//鼠标是否碰到图片矩形部分
{
xy mp=Tool::mousexy();
if(!hidemode || !must_show)
if(mp.x>=pxy.x && mp.y>=pxy.y && mp.x<pxy.x+len && mp.y<pxy.y+hei)
return 1;
return 0;
}
bool crash_mouse_block(bool must_show=1)//鼠标是否碰到图片非空格部分
{
if(!crash_mouse())return 0;
xy mp=Tool::mousexy();
mp=(xy){mp.x-pxy.x,mp.y-pxy.y};
if(!hidemode || !must_show)
if(g[mp.x][mp.y]!=' ')
return 1;
return 0;
}
bool crash_item(Item anitem,bool must_show=1)//某个其他图片是否碰到图片矩形部分
{
if(must_show && (hidemode || anitem.get_hidemode()))
return 0;
xy p=anitem.get_xy();
int l=anitem.get_len();
int h=anitem.get_hei();
for(int i=pxy.x;i<pxy.x+len;i++)
for(int j=pxy.y;j<pxy.y+hei;j++)
if(i>=p.x && j>=p.y && i<p.x+l && j<p.y+h)
return 1;
return 0;
}
bool crash_item_block(Item anitem,bool must_show=1)//某个其他图片是否碰到图片非空格部分
{
if(must_show && (hidemode || anitem.get_hidemode()))
return 0;
xy p=anitem.get_xy();
int l=anitem.get_len();
int h=anitem.get_hei();
for(int i=pxy.x;i<pxy.x+len;i++)
for(int j=pxy.y;j<pxy.y+hei;j++)
for(int k=p.x;k<p.x+l;k++)
for(int m=p.y;m<p.y+h;m++)
if(i==k && j==m && g[i-pxy.x][j-pxy.y]!=' ' && anitem.get_g()[k-p.x][m-p.y]!=' ')
return 1;
return 0;
}
bool crash_item_clone(Item anitem,bool must_show=1)
{
bool flag=0;
for(auto i:anitem.get_clone())
flag=flag || crash_item(i,must_show);
return flag;
}
bool crash_item_clone_block(Item anitem,bool must_show=1)
{
bool flag=0;
for(auto i:anitem.get_clone())
flag=flag || crash_item_block(i,must_show);
return flag;
}
bool crash_edge(xy np={-1,-1})
{
xy newp,p={31,121};
newp=(np==(xy){-1,-1}?pxy:np);
if(newp.x>=0 && newp.y>=0 && newp.x+len<p.x && newp.y+hei<p.y)
return 0;
return 1;
}
//工具组
bool move_key(bool w,bool s,bool a,bool d,int speed=1)
{
bool f=1;
if(w && KEYDOWN('W'))
f=min(1,(int)move_xy(-speed,0));
if(s && KEYDOWN('S'))
f=min(1,(int)move_xy(speed,0));
if(a && KEYDOWN('A'))
f=min(1,(int)move_xy(0,-speed));
if(d && KEYDOWN('D'))
f=min(1,(int)move_xy(0,speed));
return (bool)f;
}
bool move_key(int speed=1)
{
return move_key(1,1,1,1,speed);
}
bool move_key_def(bool i,bool b,int l,int r,char w,char s,char a,char d,int speed=1)
{
bool f=1;
if(i && KEYDOWN(w))
f=min(1,(int)move_xy(-speed,0));
if(b && KEYDOWN(s))
f=min(1,(int)move_xy(speed,0));
if(l && KEYDOWN(a))
f=min(1,(int)move_xy(0,-speed));
if(r && KEYDOWN(d))
f=min(1,(int)move_xy(0,speed));
return (bool)f;
}
bool move_key_def(char w,char s,char a,char d,int speed=1)
{
return move_key_def(1,1,1,1,w,s,a,d,speed);
}
void print(xy p)
{
xy fp=pxy;
pxy=p;
draw();
pxy=fp;
}
};
Item FEItem(xy pos,int len,string picture,int hidemode=0)
{
Item p(pos,hidemode);
p.code_load(len,picture);
return p;
}
template<typename T_item=Item>
class Main
{
private:
map<string,T_item>back;
map<string,T_item>front;
map<string,T_item>top;
public:
void add_back(string name,T_item p)
{
back[name]=p;
}
void add_front(string name,T_item p)
{
front[name]=p;
}
void add_top(string name,T_item p)
{
top[name]=p;
}
void run_back(vector<string>name,T_item (*fun)(Item))
{
for(auto i:name)
{
back[i]=fun(back[i]);
if(back[i].get_killmode())
back.erase(i);
}
}
void run_front(vector<string>name,T_item (*fun)(Item))
{
for(auto i:name)
{
front[i]=fun(front[i]);
if(front[i].get_killmode())
front.erase(i);
}
}
void run_top(vector<string>name,T_item (*fun)(Item))
{
for(auto i:name)
{
top[i]=fun(top[i]);
if(top[i].get_killmode())
top.erase(i);
}
}
void run_back_all(T_item (*fun)(T_item))
{
vector<string>name;
for(auto i:back)
name.push_back(i.first);
run_back(name,fun);
}
void run_front_all(T_item (*fun)(T_item))
{
vector<string>name;
for(auto i:front)
name.push_back(i.first);
run_front(name,fun);
}
void run_top_all(T_item (*fun)(T_item))
{
vector<string>name;
for(auto i:top)
name.push_back(i.first);
run_top(name,fun);
}
void draw()
{
for(auto i:back)
i.second.draw();
for(auto i:front)
i.second.draw();
for(auto i:top)
i.second.draw();
}
};
namespace Physics
{
double p_g=9.8;
class EP_Item:public Item//Easy_Physics_Item
{
protected:
int p_m;//质量g
int p_zq;//周期
int p_L;
public:
EP_Item(xy p,int m)
{
pxy=p,p_m=m,p_zq=0,p_L=p_g*100/p_m;
}
void p_down()
{
if(++p_zq<p_L)return;
p_zq=0;
if(!crash_edge(pxy+(xy){1,0}))
move_xy({1,0});
}
};
}
#endif