1. 程式人生 > >用ege實現簡易計算器

用ege實現簡易計算器

效果如下:

 

程式碼如下:

#include <graphics.h>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;

PIMAGE img;
int dh = 50;
int dw = 100;
int sw = 400;
int sh = 500;
int raw = 6;
int column = 4;
int ih = sh-dh*raw;

char dis[][10]= {"%","sqrt","(",")",
                 "<<",">>","^","del",
                 "7","8","9","/",
                 "4","5","6","*",
                 "1","2","3","-",
                 ".","0","=","+"
                };

void PaintUI() { //初始化一張繪圖畫板
    initgraph(sw,sh);
    img = newimage();
    getimage(img,"D:/bk.jpg",0,0);//讀取圖片
    putimage(0,0,img);//從繪畫板左上角0,0位置開始畫圖
    setfillcolor(EGERGB(0xff,0xff,0xff));
    setfont(32,0,"ЫЮЬх");
}

void PaintPane() {//畫數字鍵盤的方框
    int x = 0,y = sh-dh*6,i,j;
    setcolor(EGERGB(0x00,0x00,0x00));
    for(i=0; i<raw; i++) {
        for(j=0; j<column; j++) {
            rectangle(x,y,x+dw,y+dh);
            x+=dw;
        }
        x=0;
        y+=dh;
    }
}

void PaintDigit() {//繪製數字和運算子
    putimage(0,200,img);
    int x = 0,y = sh-dh*6,i,j,k=0;
    PaintPane();
    setbkmode(TRANSPARENT);
    setfont(32,0,"ЫЮЬх");
    for(i=0; i<raw; i++) {
        for(j=0; j<column; j++) {
            if(i==0&&j==1) {
                outtextxy(x+10,y+10,dis[k++]);
            } else if(i==1&&j==3) {
                outtextxy(x+20,y+10,dis[k++]);
            } else
                outtextxy(x+40,y+10,dis[k++]);
            x+=dw;
        }
        x=0;
        y+=dh;
    }
}

void Destroy() {//程式結束時呼叫,釋放資源
    getch();
    delimage(img);
    closegraph();
    return ;
}

void getxy(int &x,int &y,int &k) {//根據滑鼠的座標,計算點選的是哪一個數字或運算子
    int z = (y-ih)/dh;
    y = z*dh+ih;
    x = (x/dw)*dw;
    k = z*column+x/dw;
}

void shadowDisplay(int x,int y) {//滑鼠移動時,方格樣式變化
    int i=0,k=0;
    getxy(x,y,k);
    bar(x,y,x+dw,y+dh);
    outtextxy(x+40,y+10,dis[k]);
}

void shadowDisappear() {
    PaintDigit();
}

int width = 0;
char str[100];//儲存從鍵盤或者滑鼠輸入的字元
char s1[100];//儲存字尾表示式
int cn = 0;

int priorityValue(char c) {//返回運算子的權重值
    if(c=='$') {
        return 5;
    } else if(c=='*'||c=='/'||c=='%') {
        return 4;
    } else if(c=='+'||c=='-') {
        return 3;
    } else if(c=='<'||c=='>'||c=='^') {
        return 2;
    } else
        return 1;
}

void m2h() {//中綴轉字尾,用來計算多項式(有興趣的可以上網搜尋學習)
    int i=0,j=0,k=0;
    char s2[100];
    while(str[k]!='\0') {
        if(str[k]>='0'&&str[k]<='9'||str[k]=='.') {
            s1[i++]=str[k];
            if((str[k+1]<'0'||str[k+1]>'9')&&str[k+1]!='.'){
                s1[i++]='#';
            }
        } else {
            if(str[k]=='(') {
                s2[j++]='(';
            } else if(str[k]==')') {
                while(s2[--j]!='(') {
                    s1[i++]=s2[j];
                }
            } else {
                if(j==0||priorityValue(str[k])>priorityValue(s2[j-1])) {
                    s2[j++]=str[k];
                } else if(priorityValue(str[k])<=priorityValue(s2[j-1])) {
                    s1[i++]=s2[--j];
                    s2[j++]=str[k];
                }
            }
        }
        k++;
    }
    while(j>0) {
        s1[i++]=s2[--j];
    }
    s1[i]=0;
}

void printResult(double v) {//繪製計算結果
    char ss1[100],ss2[100];
    int i=0,j=0;
    long vv = floor(v);
    while(vv) {
        ss1[i++]=vv%10+'0';
        vv/=10;
    }
    while(i>0) {
        ss2[j++]=ss1[--i];
    }
    v = v - floor(v);
    if(v>0) {
        ss2[j++]='.';
    }
    while(v>1e-10) {
        v=v*10;
        int t = (int)v;
        ss2[j++]=t+'0';
        v=v-t;
    }
    ss2[j]='\0';
    i=0;
    while(ss2[i]!=0) {
        outtextxy(width,10,ss2[i++]);
        width+=15;
    }
}

double calc() {//計算字尾表示式,得到計算結果
    m2h();
    double a[100],c,d,f=0.1,v=0;
    int i=0,j=0,flag = 0;
    if(s1[i]=='#')
        i++;
    while(s1[i]!='\0') {
        if(s1[i]=='.') {
            flag=1;
        } else if(s1[i]>='0'&&s1[i]<='9') {
            if(flag) {
                v+=f*(s1[i]-'0');
                f*=0.1;
            } else {
                v*=10;
                v+=(s1[i]-'0');
            }
        } else if(s1[i]=='#') {
            flag=0;
            f=0.1;
            a[j++]=v;
            v=0;
        } else if(s1[i]=='$') {
            a[j-1]=sqrt(a[j-1]);
        } else {
            d = a[--j];
            c = a[--j];
            switch(s1[i]) {
            case '%':
                a[j]=(long long)c%(long long)d;
                break;
            case '<':
                a[j]=(int)c<<(int)d;
                break;
            case '>':
                a[j]=(int)c>>(int)d;
                break;
            case '+':
                a[j]=c+d;
                break;
            case '-':
                a[j]=c-d;
                break;
            case '*':
                a[j]=c*d;
                break;
            case '/':
                a[j]=c/d;
                break;
            case '^':
                a[j]=(int)c^(int)d;
                break;
            }
            j++;
        }
        i++;
    }
    printf("%lf\n",a[0]);
    printResult(a[0]);
}

void Delete() {//刪除重複或者多輸入的字元
    putimage(0,0,img);
    width=0;
    for(int i=0; i<cn; i++) {
        if(str[i]=='$'){
            outtextxy(width,10,"sqrt");
            width+=65;
        }
        else if(str[i]=='<'){
            outtextxy(width,10,"<<");
            width+=30;
        }
        else if(str[i]=='>'){
            outtextxy(width,10,">>");
            width+=30;
        }
        else{
            outtextxy(width,10,str[i]);
            width+=15;
        }
    }
}

void reciveChar(int k) {//接受滑鼠傳過來的字元,儲存到str數字,並繪製
    if(cn==0) {
        width=0;
        PaintUI();
        PaintPane();
        PaintDigit();
        delay_fps(1000);
    }
    outtextxy(width,10,dis[k]);
    if(k==1)
        width+=65;
    else if(k==4||k==5)
        width+=30;
    else
        width+=15;
    if(k==22) {
        str[cn]='\0';
        calc();
        cn=0;
    } else if(k==7) {
        cn--;
        Delete();
    } else if(k==1) {
        str[cn++]='$';
    } else if(k==6) {
        str[cn++]='^';
    } else if(k==11) {
        str[cn++]='/';
    } else if(k==15) {
        str[cn++]='*';
    } else
        str[cn++]=dis[k][0];
}

void ReciveChar(char c) {//接受鍵盤傳過來的字元,儲存到str數字,並繪製
    if(cn==0) {
        width=0;
        PaintUI();
        PaintPane();
        PaintDigit();
        delay_fps(1000);
    }
    setbkmode(TRANSPARENT);
    setfont(32,0,"ЫЮЬх");
    outtextxy(width,10,c);
    width+=15;
    if(c=='=') {
        printf("====");
        str[cn]=0;
        calc();
    }
    str[cn++]=c;
}

void mouseListener() {//監聽滑鼠事件,得到輸入的字元
    mouse_msg msg = {0};
    int x=0,y=0,x1=0,y1=0,k=0;
    if(mousemsg()) {
        msg = getmouse();

        if(msg.is_left()) {
            x1 = msg.x;
            y1 = msg.y;
            if(msg.is_down()) {
                getxy(x1,y1,k);
                reciveChar(k);
            }
        }
        if(msg.is_move()) {
            x1 = msg.x;
            y1 = msg.y;
            if(y1>=ih) {
                getxy(x1,y1,k);
                if(x1!=x||y1!=y) {
                    shadowDisappear();
                    x = x1;
                    y = y1;
                    shadowDisplay(x,y);
                }
            }
        }

    }
}

void mykeyListener() {//監聽鍵盤事件,得到鍵盤輸入的字元
    if(kbhit()) {
        char c = getch();
        if(c>='0'&&c<='9'||c=='%'||c=='*'||c=='/'||c=='='||c=='-'||c=='+'||c=='('||c==')'||c=='^'||c=='<'||c=='>')
            ReciveChar(c);
    }
}

int main() {
    PaintUI();
    PaintPane();
    PaintDigit();
    delay_fps(1000);
    while(true) {//死迴圈,不斷監聽滑鼠和鍵盤事件
        mykeyListener();
        mouseListener();
    }
    Destroy();
    return 0;
}