公歪摇号 1.0

· · 个人记录

使用说明:https://docs.qq.com/doc/DWGlUYklNeVhyTXpa

#include<iostream>
#include<fstream>
#include<sstream>
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<vector>
#include<conio.h>
#include<cstring>
#include<iomanip>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) 
using namespace std;
int seed=1,n,roun,trou,xuanz,page,count,chance,cheat,recho;
string docnam;
char cmmd;
vector<int> aq;
struct gwlist{
    int ext,per,intervene;
    string nam;
}v;
vector<gwlist> a;
vector<int> mus;
void console(){
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);  
    CONSOLE_SCREEN_BUFFER_INFO bInfo; 
    GetConsoleScreenBufferInfo(hOut, &bInfo );  
    SetConsoleTitle("公歪摇号 1.0"); // 设置窗口的标题
}
int rdm(int aaaaa,int bbbbb){
    int ret=-1;
    do
    {
        ret=rand()/(bbbbb-aaaaa);
    }while(!(aaaaa<=ret && ret<=bbbbb));
    ret=rand()%(bbbbb-aaaaa+1)+aaaaa;
    return ret;
}
bool kd(char ccc){
    if(!KEY_DOWN(ccc)) return 0;
    else return 1;
}
void cls(){//赟刑道提供,如有侵权请联系删除。    
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD coordScreen = { 0, 0 };    // home for the cursor
    SetConsoleCursorPosition( hConsole, coordScreen );
}
void Line(string str){//该函数如需借鉴请先联系沙兴安 
    int i,l,w;
    w=120;
    l=str.length();
    for(i=0;i<(w-l)/2;i++)
    cout<<" ";
    cout<<str<<endl;
    return ;
}
string change_string(int will_change){//该函数如需借鉴请先联系沙兴安 
    stringstream sin;
    sin<<will_change;
    string change_ok;
    sin>>change_ok;
    return change_ok;
}
void color(int a){
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
void q(char &c){
    if(c>='A' && c<='Z'){
        c=c-'A'+'a';
    }
}
void p(char &c){
    if(c>='a' && c<='z'){
        c=c+'A'-'a';
    }
}
void gw();
void read_project(string sq){
    char sqs[sq.length()];
    strcpy(sqs,sq.data());
    ifstream fin(sqs);
    fin>>n>>roun>>trou>>page;
    for(int i=1;i<=n;i++) 
    for(int i=1;i<=n;i++){
        v.nam="";
        fin>>v.ext>>v.per>>v.intervene;
        getline(fin,v.nam);
        a.push_back(v);
    }
    fin.close();
}
void save_project(string sq){
    char sqs[sq.length()];
    strcpy(sqs,sq.data());
    ofstream fout(sqs);
    fout<<n<<" "<<roun<<" "<<trou<<" "<<page<<endl;
    for(int i=1;i<=n;i++){
        fout<<a[i].ext<<" "<<a[i].per<<" "<<a[i].intervene<<a[i].nam<<endl;
    }
    fout.close();
}
void new_project(){
    string sq=""; 
    system("cls");
    color(159);
    cout<<"                                               公歪摇号 1.0 - 兴安科技出品                                               "<<endl;
    color(14);
    Line("新建摇号工程");
    color(11);
    cout<<"=======================================================输入工程名========================================================"<<endl;
    color(15);
    getline(cin,docnam);
    sq=docnam+".xalot";
    a.push_back(v);
    page=1;
    roun=1;
    trou=1;
    n=0;
    save_project(sq);
    gw();
}
void ask_read(){
    string sq=""; 
    system("cls");
    color(159);
    cout<<"                                               公歪摇号 1.0 - 兴安科技出品                                               "<<endl;
    color(14);
    Line("读取摇号工程");
    color(11);
    cout<<"=======================================================输入工程名========================================================"<<endl;
    color(15);
    getline(cin,docnam);
    sq=docnam+".xalot";
    a.push_back(v);
    read_project(sq);
    gw();
}
void gw(){
    while(cmmd!='P'){
        save_project(docnam+".xalot");
        count=0;
        recho=0;
        chance=roun*trou;
        cheat=0;
        for(int i=1;i<=n;i++){
            /*
            -1:一定不被抽中
            0:不干预结果
            1:一定被抽中
            2:干预结果 
            */
            if(a[i].ext>1) recho=1;
            if(a[i].per==-1) a[i].ext=-1;
            if(a[i].per==0) a[i].ext=0;

            if(a[i].per==-1){
                a[i].intervene=1;
            }else if(a[i].per==0){
                a[i].intervene=-1;
            }else if(a[i].per==1){
                a[i].intervene=0;
            }else{
                a[i].intervene=2;
            }

            if(a[i].intervene==1){
                chance-=a[i].ext;
                cheat=1;
            }else if(a[i].intervene==0 || a[i].intervene==2){
                count+=a[i].per;
            }
            if(a[i].intervene==-1){
                cheat=1;
            }
        }
        system("cls");
        color(159);
        cout<<"                                               公歪摇号 1.0 - 兴安科技出品                                               "<<endl;
        color(14);
        Line(docnam+".xalot");
        color(11);
        cout<<"========================================================基本信息========================================================="<<endl;
        color(15);
        cout<<"摇号名单数:"<<n<<endl;
        cout<<" 抽取轮数 :"<<roun<<endl;
        cout<<"每轮抽取数:"<<trou<<endl;
        color(11);
        cout<<"========================================================高级属性========================================================="<<endl;
        color(15);
        cout<<"作弊:";
        if(cheat==0) cout<<"关";
        else cout<<"开";
        cout<<endl;
        cout<<"重复被抽取:";
        if(recho==0) cout<<"关";
        else cout<<"开";
        cout<<endl;
        color(11);
        cout<<"========================================================名单修改========================================================="<<endl;
        color(15);
        cout<<"Q-新建号   W-插入号   E-删除号   T-开始摇号   Y-修改抽取数   U-修改文件名   I-批量导入摇号名   P-退出公歪摇号"<<endl;
        color(14);
        cout<<"权重";
        color(11);
        cout<<"  <A< ";
        color(15);
        if(xuanz>0) cout<<a[xuanz].per;
        color(11);
        cout<<" >S> ";
        color(14);
        cout<<"| 被抽取上限";
        color(11);
        cout<<"  <K< ";
        color(15);
        if(xuanz>0) cout<<a[xuanz].ext;
        color(11);
        cout<<" >L> ";
        color(14);
        cout<<"| 修改摇号名-R";
        cout<<endl;
        color(11);
        cout<<"========================================================摇号名单========================================================="<<endl;
        color(10);
        cout<<"第"<<page<<"页,共"<<n/20+1<<"页   "<<"-/+ 切换号   [/] 切换页"<<endl;
        color(14);
        cout<<"编号     摇号名              权重    被抽取上限  结果干预     总体抽中概率"<<endl;
        color(15);
        for(int i=(page-1)*20+1;i<=min(page*20,n);i++){
            if(xuanz==i) color(13);
            else color(15);
            cout<<i<<"\t "<<a[i].nam;
            for(int j=1;j<=20-a[i].nam.length();j++) cout<<" ";
            if(a[i].per!=-1) cout<<a[i].per<<"\t     ";
            else cout<<"-       ";
            if(a[i].ext!=-1) cout<<a[i].ext<<"\t         ";
            else if(a[i].per==-1 || a[i].per==0) cout<<"-           ";
            else cout<<"无限制      ";
            if(a[i].intervene==0){
                cout<<"不干预结果  ";
            }else if(a[i].intervene==1){
                cout<<"一定被抽中  ";
            }else if(a[i].intervene==-1){
                cout<<"一定不被抽中";
            }else if(a[i].intervene==2){
                cout<<"干预结果    ";
            }
            cout<<" ";
            if(a[i].intervene==1){
                cout<<"100.00%";
            }else if(a[i].intervene==-1){
                cout<<"0.00%";
            }else if(a[i].intervene==0 || a[i].intervene==2){
                cout<<fixed<<setprecision(2)<<(100.0*a[i].per/count)<<"%";
            }
            cout<<endl;
        }
        cmmd=getch();
        p(cmmd);
        if(cmmd=='Q'){
            n++;
            v.nam="未命名"+change_string(n);
            v.per=1;
            v.ext=1;
            v.intervene=0;
            a.push_back(v);
        }
        if(cmmd=='['){
            page=max(page-1,1);
            xuanz=(page-1)*20+1;
        }
        if(cmmd==']'){
            page=min(page+1,n/20+1);
            xuanz=(page-1)*20+1;
        }
        if(cmmd=='A'){
            a[xuanz].per=max(-1,a[xuanz].per-1);
            if(a[xuanz].per==0) a[xuanz].ext=0;
        }
        if(cmmd=='S'){
            a[xuanz].per=a[xuanz].per+1;
            if(a[xuanz].per==1 && a[xuanz].ext!=-1) a[xuanz].ext=max(1,a[xuanz].ext);
        }
        if(cmmd=='K'){
            a[xuanz].ext=max(-1,a[xuanz].ext-1);
            if(a[xuanz].ext==0) a[xuanz].per=0;
        }
        if(cmmd=='L'){
            a[xuanz].ext=min(chance,a[xuanz].ext+1);
            if(a[xuanz].ext==1 && a[xuanz].per!=-1) a[xuanz].per=max(1,a[xuanz].per);
        }
        if(cmmd=='-'){
            if(xuanz>1){
                if(xuanz-1<(page-1)*20+1){
                    page--;
                }
                xuanz--;    
            }
        }
        if(cmmd=='='){
            if(xuanz<n){
                if(xuanz+1>page*20){
                    page++;
                }
                xuanz++;
            }
        }
        if(cmmd=='R'){
            system("cls");
            color(159);
            cout<<"                                               公歪摇号 1.0 - 兴安科技出品                                               "<<endl;
            color(14);
            Line(docnam+".xalot");
            color(11);
            cout<<"=======================================================修改摇号名========================================================"<<endl;
            color(12);
            Line("摇号名开头不得为数字,否则将被省略");
            color(15);
            cout<<"输入摇号名:";
            getline(cin,a[xuanz].nam);
            for(int i=0;i<a[xuanz].nam.size();i++){
                if(a[xuanz].nam[i]>='0' && a[xuanz].nam[i]<='9'){
                    a[xuanz].nam.erase(i,i+1);
                    i=-1;
                }
                else break;
            }
        }
        if(cmmd=='E'){
            if(n>0){
                a.erase(a.begin()+xuanz);
                n--;
                if(xuanz>n) xuanz=n;    
            }
        }
        if(cmmd=='W'){  
            if(n>0){
                v.nam="未命名";
                v.per=1;
                v.ext=1;
                v.intervene=0;
                a.insert(a.begin()+xuanz,v);
                n++;    
            }   
        }
        if(cmmd=='T'){
            mus.clear();
            for(int i=1;i<=n;i++){
                if(a[i].per==-1) mus.push_back(i);
            }
            if(roun*trou>count){
                system("cls");
                color(159);
                cout<<"                                                          提醒                                                           "<<endl;
                color(14);
                Line(docnam+".xalot");
                color(15);
                Line("当前不允许开始摇号,因为摇号名单的被抽取上限总和小于摇号结果个数。");
                Line("按任意键继续");
                cmmd=getch();
                p(cmmd);
            }else if(mus.size()>roun*trou){
                system("cls");
                color(159);
                cout<<"                                                          提醒                                                           "<<endl;
                color(14);
                Line(docnam+".xalot");
                color(15);
                Line("当前不允许开始摇号,因为摇号名单中一定被抽中的人数大于摇号结果个数。");
                Line("按任意键继续");
                cmmd=getch();
                p(cmmd);
            }else{
                int turns=1,l[10001];
                string sss[10001];
                memset(l,0,sizeof(l));
                while(turns<=roun){
                    while(cmmd!='Q'){
                        system("cls");
                        color(159);
                        cout<<"                                                        准备摇号                                                         "<<endl;
                        color(14);
                        Line(docnam+".xalot");
                        color(11);
                        Line("第"+change_string(turns)+"轮   共"+change_string(roun)+"轮");
                        Line("Q-长按开始摇号");
                        color(15);
                        cmmd=getch();
                        p(cmmd);    
                    }
                    while(kd('Q')){
                        cls();
                        color(159);
                        cout<<"                                                        正在摇号                                                         "<<endl;
                        color(14);
                        Line(docnam+".xalot");
                        color(11);
                        Line("第"+change_string(turns)+"轮   共"+change_string(roun)+"轮");
                        color(15);
                        Line("Q-松手查看结果");
                        string ss=""; 
                        for(int i=1;i<=trou;i++){
                            int u=rdm(1,n);
                            ss=ss+" "+a[u].nam;
                        }
                        Line(ss);
                        Sleep(20);
                    }
                        system("cls");
                        color(159);
                        cout<<"                                                      本轮摇号结果                                                       "<<endl;
                        color(14);
                        Line(docnam+".xalot");
                        color(11);
                        Line("第"+change_string(turns)+"轮   共"+change_string(roun)+"轮");
                        if(turns<roun) Line("W-下一轮摇号");
                        else Line("W-公布结果");
                        color(15);
                        string ss="";
                        for(int i=1;i<=trou;i++){
                            it1:;
                            int u=rdm(1,count),uu=0,uuu=0;
                            while(u>uu){
                                uuu++;
                                if(a[uuu].intervene!=-1) uu+=a[uuu].per;
                            }
                            /*cout<<"try="<<change_string(uuu);
                            for(int i=1;i<=n;i++){
                                if(l[i]<a[i].ext){
                                    cout<<" "<<i;
                                }   
                            }
                            cout<<endl;*/
                            if(l[uuu]<a[uuu].ext || a[uuu].ext==-1){
                                if(mus.size()>0){
                                    ss=ss+" "+a[mus.back()].nam;
                                    mus.pop_back();
                                }else{
                                    l[uuu]++;
                                    ss=ss+" "+a[uuu].nam;   
                                }
                            }else goto it1; 
                        }
                        Line(ss);
                        sss[turns]=ss;
                    while(cmmd!='W'){
                        cmmd=getch();
                        p(cmmd);    
                    }
                    turns++;
                }
                system("cls");
                color(159);
                cout<<"                                                      最终摇号结果                                                       "<<endl;
                color(14);
                Line(docnam+".xalot");
                color(11);
                for(int i=1;i<=roun;i++){
                    Line("第"+change_string(i)+"轮 : "+sss[i]);   
                }
                cmmd=getch();   
            }
        }
        if(cmmd=='Y'){
            system("cls");
            color(159);
            cout<<"                                               公歪摇号 1.0 - 兴安科技出品                                               "<<endl;
            color(14);
            Line(docnam+".xalot");
            color(11);
            cout<<"=======================================================修改抽取数========================================================"<<endl;
            color(15);
            cout<<"输入抽取轮数:";
            cin>>roun;
            cout<<"输入每轮抽取数:";
            cin>>trou;
        }
        if(cmmd=='U'){
            system("cls");
            color(159);
            cout<<"                                               公歪摇号 1.0 - 兴安科技出品                                               "<<endl;
            color(14);
            Line(docnam+".xalot");
            color(11);
            cout<<"=======================================================修改文件名========================================================"<<endl;
            color(15);
            cout<<"输入文件名:";
            cin>>docnam;
        }
        if(cmmd=='I'){
            system("cls");
            color(159);
            cout<<"                                               公歪摇号 1.0 - 兴安科技出品                                               "<<endl;
            color(14);
            Line(docnam+".xalot");
            color(11);
            cout<<"=====================================================批量导入摇号名======================================================"<<endl;
            color(12);
            Line("提醒:请在cpp文件保存目录位置建立名称为""local.txt""的文件,并将名单输入,支持空格读取。");
            color(15);
            int nx;
            cout<<"输入名单个数:";
            cin>>nx;
            ifstream fin("local.txt");
            for(int i=1;i<=nx;i++){
                n++;
                getline(fin,v.nam);
                v.per=1;
                v.ext=1;
                v.intervene=0;
                a.push_back(v);
            }
            fin.close();
        }
        if(n==1) xuanz=1;
    }
}
void fm(){
    while(cmmd!='P'){
        system("cls");
        color(159);
        cout<<"                                               公歪摇号 1.0 - 兴安科技出品                                               "<<endl;
        color(14);
        Line("");
        Line("Q-新建摇号工程");
        Line("W-读取摇号工程");
        Line("P-退出公歪摇号");
        cmmd=getch();
        p(cmmd);
        if(cmmd=='Q'){
            new_project();
            cmmd='?';
        }
        if(cmmd=='W'){
            ask_read();
        }
    }
}
void gw_main(){
    system("mode con:cols=122 lines=36");
    console(); 
    fm();
}
int main(){
    gw_main();
    return 0;
}