//digital.h #include #include #include int near5(int x) { int ret=(x/10)*10; int n=x%10; switch(n) { case 0: case 1: case 2: break; case 3 : case 4 : case 5 : case 6 : case 7 : ret+=5; break; case 8 : case 9 : ret+=10; break; } return(ret); } typedef struct Point { int x,y; } Point; //The base class for all digital gates class Gate { public: int type; int n; int value; int flag; int count; int ox; int oy; int h; int color; int startx; int endx; int starty; int endy; Gate *input[20]; Gate(int); //To be used by derived classes void setSize(int s) { n=s; } void setInput(Gate *g) { input[count++]=g; } void setPosition(int a,int b) { ox=a; oy=b; } void reset() { flag=0; } void resetConn() { count=0; } //To be implemented by derived classes virtual int getOutput(){return(0);}; virtual void draw(int c=1){}; virtual Point getO() { Point p;return(p);}; virtual int isInput(Point p) { return(0);} virtual int isInside(int x,int y) { return(0);} }; Gate::Gate(int s) { n=s; count=0; flag=0; h=(n-1)*10+10; ox=oy=0; } //AND gate class And : public Gate { public: And(int s) : Gate(s) {color=BLUE;type=0;} int getOutput(); void draw(int); Point getO(); int isInput(Point p); int isInside(int a,int b) { if((ox-h/2<=a)&&(oy-h/2<=b)&&(a<=ox+5)&&(b<=oy+h/2)) return(1); return(0); } }; int And::getOutput() { int ret=1; if (flag==1) return(value); flag++; for(int i=0;igetOutput(); } value=ret; return(value); } void And::draw(int c=1) { if (c) setcolor(BLUE); else setcolor(BLACK); line(ox,oy-h/2,ox+5,oy-h/2); line(ox,oy+h/2,ox+5,oy+h/2); line(ox+5,oy-h/2,ox+5,oy+h/2); for(int i=0;igetOutput(); } value=ret; return(value); } void Or::draw(int c=1) { if (c) setcolor(RED); else setcolor(0); line(ox,oy-h/2,ox+5,oy-h/2); line(ox,oy+h/2,ox+5,oy+h/2); for(int i=0;igetOutput(); } value=!ret; return(value); } void Not ::draw(int c=1) { if (c) setcolor(YELLOW); else setcolor(0); circle(ox,oy,2); line(ox+2,oy,ox+10,oy-4); line(ox+2,oy,ox+10,oy+4); line(ox+10,oy-4,ox+10,oy+4); line(ox+10,oy,ox+15,oy);//input line(ox-2,oy,ox-10,oy);//output } Point Not::getO() { Point p; p.x=ox-10; p.y=oy; return(p); } int Not::isInput(Point p) { if ((p.x==(ox+15))&&(p.y==oy)) return(1); return(0); } // LED class Led : public Gate { public: Led() : Gate(1) {color=BROWN;type=5;} int getOutput(); void draw(int); Point getO(); int isInput(Point p); int isInside(int a,int b) { if ((ox-15<=a)&&(oy-5<=b)&&(a<=ox-5)&&(b<=oy+5)) return(1); return(0); } }; int Led::getOutput() { int ret=0; if (flag==1) return(value); flag++; for(int i=0;igetOutput(); } value=ret; draw(2); return(value); } void Led::draw(int c=1) { if (c) setcolor(GREEN); else setcolor(0); line(ox,oy,ox-5,oy);//input (ox,oy) circle(ox-10,oy,5); if (c==2) { if (value==1) { setcolor(YELLOW); setfillstyle(1,YELLOW);} else { setcolor(BLACK); setfillstyle(1,BLACK);} pieslice(ox-10,oy,0,360,4); } } Point Led::getO() { Point p; p.x=-1; p.y=-1; return(p); } int Led::isInput(Point p) { if ((p.x==ox)&&(p.y==oy)) return(1); return(0); } // SWITCH class Switch : public Gate { public: Switch() : Gate(0) {color=BROWN;type=6;value=0;} int getOutput(); void draw(int); Point getO(); int isInput(Point p); int isInside(int a,int b) { if ((ox-7<=a)&&(oy-7<=b)&&(a<=ox+7)&&(b<=oy+7)) return(1); return(0); } void toggle() { value=1-value;} }; int Switch::getOutput() { return(value); } void Switch::draw(int c=1) { if (c) setcolor(BROWN); else setcolor(0); circle(ox,oy,5); rectangle(ox-7,oy-7,ox+7,oy+7); line(ox-7,oy,ox-15,oy); if (c==2) { if (value==1) { setcolor(YELLOW); setfillstyle(1,YELLOW);} else { setcolor(BLACK); setfillstyle(1,BLACK);} pieslice(ox,oy,0,360,4); } } Point Switch::getO() { Point p; p.x=ox-15; p.y=oy; return(p); } int Switch::isInput(Point p) { p.x=p.y; return(0); } // NAND gate class Nand : public Gate { public: Nand(int s) : Gate(s) {color=MAGENTA;type=1;} int getOutput(); void draw(int); Point getO(); int isInput(Point p); int isInside(int a,int b) { if((ox-h/2<=a)&&(oy-h/2<=b)&&(a<=ox+5)&&(b<=oy+h/2)) return(1); return(0); } }; int Nand::getOutput() { int ret=1; if (flag==1) return(value); flag++; for(int i=0;igetOutput(); } value=!ret; return(value); } void Nand::draw(int c=1) { if (c) setcolor(MAGENTA); else setcolor(0); line(ox,oy-h/2,ox+5,oy-h/2); line(ox,oy+h/2,ox+5,oy+h/2); line(ox+5,oy-h/2,ox+5,oy+h/2); for(int i=0;igetOutput(); } value=!ret; return(value); } void Nor::draw(int c=1) { if (c) setcolor(LIGHTBLUE); else setcolor(0); line(ox,oy-h/2,ox+5,oy-h/2); line(ox,oy+h/2,ox+5,oy+h/2); for(int i=0;igetOutput(); } value=ret; return(value); } void Connector::draw(int c) { if (c) setcolor(LIGHTRED); else setcolor(0); line(startx,starty,endx,endy); } Point Connector::getO() { Point p; p.x=endx; p.y=endy; return(p); } int Connector::isInput(Point p) { if ((p.x==startx)&&(p.y==starty)) return(1); return(0); } int Connector::isInside(int x,int y) { int left_x=startx; int top_y=starty; int right_x=endx; int down_y=endy; if (left_x>right_x) { int temp=left_x; left_x=right_x; right_x=temp; }//swap if (top_y>down_y) { int temp=top_y; top_y=down_y; down_y=temp; }//swap if (startx==endx) { left_x-=5; right_x+=5; } if (starty==endy) { top_y-=5; down_y+=5; } if ( (x>=left_x) && (x<=right_x) && (y>=top_y) && (y<=down_y)) return(1); return(0); }