#include "graphics.h" #include "math.h" #include "stdio.h" #include "conio.h" #include "bios.h" #include "dos.h" #include "io.h"
char key_state[128],key_pressed[128]; void interrupt far (*OldInt9Handler)();
enum modes {AUTO, HIGH}; enum bool {FALSE=0, TRUE=1}; #define MODE enum modes #define BOOL enum bool #define K_ENTER 0x1c #define K_DOWN 0x50 #define K_UP 0x48 #define K_SPACE 0x39 #define K_ESC 0x01 #define K_C 0x2e #define K_A 0x1e #define K_X 0x2d #define UP 0 #define DOWN 1 #define PI 3.1415 #define MODE_KEY 0 #define MODE_CMD 1 #define MAX_CMD_NUM 15
/*Instruction define*/ #define EXIT 0 #define CHM 1 #define PU 2 #define PD 3 #define CHC 4 #define CHHT 5 #define ADTH 6 #define FW 7 #define BW 8 #define CLR 9 #define CHP 10
enum hlpmsg{ALL_CMD, IN_ERROR, PU_OK, PD_OK, CHC_OK, CHP_OK, CHM_OK, FW_OK, BW_OK, CHHT_OK, ADTH_OK, CLR_OK, M_KEY, IN_COLOR, IN_POS, IN_HEAD, IN_STEPS}; #define HLPMSG enum hlpmsg typedef int penState; typedef struct{float v,h;}aPoint; typedef struct { float heading; penState pen; int color; aPoint Pos; }newTurtle;
newTurtle turtle; char GMODE=MODE_CMD; char CmdWords[MAX_CMD_NUM][4]={ {'E', 'X', 'I', 'T'}, {'C', 'H', 'M', ' '}, {'P', 'U', ' ', ' '}, {'P', 'D', ' ', ' '}, {'C', 'H', 'C', ' '}, {'C', 'H', 'H', 'T'}, {'A', 'D', 'T', 'H'}, {'F', 'W', ' ', ' '}, {'B', 'W', ' ', ' '}, {'C', 'L', 'R', ' '}, {'C', 'H', 'P', ' '}, }; char CmdTmp[4]; unsigned char NumTmp[4]; unsigned char NumTmp1[4]; typedef struct node { int color; int x1, x2, y1, y2; }NODE;
/*---------------------------------------*/ /*other functions*/ void OpenSecCmdWnd() { setcolor(2); rectangle(510, 250, 595, 275); while(bioskey(1)==0) { setcolor(2); line(513, 270, 518, 270); setcolor(0); line(513, 270, 518, 270); } window(66, 17, 66, 17); } void CloseSecCmdWnd() { setfillstyle(SOLID_FILL, 0); bar(511, 250, 595, 275); } int Cvt4CToInt(int i) { if(i==0) return NumTmp[0]+NumTmp[1]*10+NumTmp[2]*100+NumTmp[3]*1000-53328; else return NumTmp1[0]+NumTmp1[1]*10+NumTmp1[2]*100+NumTmp1[3]*1000-53328; } int GetAn4BInterger() { int i, j; union REGS regs; unsigned char t; regs.h.ah=0x07; IN_AGAIN: for(i=0;i<4;i++) NumTmp[i]=48; for(i=0;i<4;i++) { IN: while(bioskey(1)==0) {;}; if(bioskey(1)==0x1c0d) { bioskey(0); goto OUT;} int86(0x21, ®s, ®s); t=regs.h.al; if(t>57 || t<48) goto IN; else { for(j=3;j>0;j--) NumTmp[j]=NumTmp[j-1]; NumTmp[0]=t; printf("%c", t); } } while(bioskey(1)==0) {;} if(bioskey(1)!=0x1c0d) { bioskey(0); CloseSecCmdWnd(); OpenSecCmdWnd(); goto IN_AGAIN; } OUT: return Cvt4CToInt(0); } void StoreTwo4BInterger() { int i, j; union REGS regs; unsigned char t; regs.h.ah=0x07; IN_AGAIN1: for(i=0;i<4;i++) { NumTmp[i]=48; NumTmp1[i]=48; } for(i=0;i<4;i++) { IN1: while(bioskey(1)==0) {;}; if(bioskey(1)==0x1c0d) { bioskey(0); goto OVER;} int86(0x21, ®s, ®s); t=regs.h.al; if(t==44) { printf("%c", t); goto OUT1; } if(t>57 || t<48) goto IN1; else { for(j=3;j>0;j--) NumTmp[j]=NumTmp[j-1]; NumTmp[0]=t; printf("%c", t); } } while(bioskey(1)==0) {;} if(bioskey(1)!=0x1c0d) { int86(0x21, ®s, ®s); t=regs.h.al; if(t==44) { printf("%c", t); goto OUT1; } CloseSecCmdWnd(); OpenSecCmdWnd(); goto IN_AGAIN1; } OUT1: for(i=0;i<4;i++) NumTmp1[i]=48; for(i=0;i<4;i++) { IN2: while(bioskey(1)==0) {;}; if(bioskey(1)==0x1c0d) { bioskey(0); goto OVER;} int86(0x21, ®s, ®s); t=regs.h.al; if(t>57 || t<48) goto IN2; else { for(j=3;j>0;j--) NumTmp1[j]=NumTmp1[j-1]; NumTmp1[0]=t; printf("%c", t); } } while(bioskey(1)==0) {;} if(bioskey(1)!=0x1c0d) { bioskey(0); CloseSecCmdWnd(); OpenSecCmdWnd(); goto IN_AGAIN1; } OVER: ; } void far interrupt NewInt9(void) { unsigned char ScanCode,temp; ScanCode=inportb(0x60); temp=inportb(0x61); outportb(0x61,temp | 0x80); outportb(0x61,temp & 0x7f); if(ScanCode&0x80) { ScanCode&=0x7f; key_state[ScanCode]=0; } else { key_state[ScanCode]=1; key_pressed[ScanCode]=1; } outportb(0x20,0x20); }; void InstallKeyboard(void) { int i; for(i=0;i<128;i++) key_state[i]=key_pressed[i]=0; OldInt9Handler=getvect(9); setvect(9,NewInt9); }
void ShutDownKeyboard(void) { setvect(9,OldInt9Handler); } int GetKey(int ScanCode) { int res; res=key_state[ScanCode]|key_pressed[ScanCode]; key_pressed[ScanCode]=0; return res; } void InitMyGraph(MODE m) { int graphdriver, graphmode; if(m==AUTO) graphdriver=DETECT; else if(m==HIGH) { graphdriver=VGA; graphmode=VGAHI; } else { printf("Wrong prameter of \"init_mygraph();\""); return ; } /*registerbgidriver(EGAVGA_driver);*/ initgraph(&graphdriver, &graphmode, ""); }; int GetKey1() { union REGS rg; rg.h.ah=0; int86(0x16, &rg, &rg); return rg.h.ah; }; void InputNote() { while(bioskey(1)==0) { setcolor(9); line(467, 270, 472, 270); setcolor(0); line(467, 270, 472, 270); }
} void GetACmd() { int i, j; window(60, 17, 60, 17); InputNote(); for(i=0;i<4;i++) { AGAIN: while(bioskey(1)==0) {}; if(bioskey(1)==0x0f09) {bioskey(0); goto AGAIN;} if(bioskey(1)==0x0e08) {bioskey(0); goto AGAIN;} if(bioskey(1)==0x1c0d) { for(;i<4;i++) CmdTmp[i]=' '; break; }; CmdTmp[i]=getch(); printf("%c", CmdTmp[i]); } } int DecideCmd() { int i, j, r=MAX_CMD_NUM; for(i=0;i<MAX_CMD_NUM;i++) { if(CmdWords[i][0]==CmdTmp[0]) { r=i; for(j=1;j<4;j++) { if(CmdWords[i][j]!=CmdTmp[j]) { r=MAX_CMD_NUM; break; }
} } if(r!=MAX_CMD_NUM) break; } return r; } /*display the turtle to every prameter of its own*/ void DisTurtle() { float x, y, h, v, x1, y1; circle(turtle.Pos.h-8, turtle.Pos.v, 4); circle(turtle.Pos.h+8, turtle.Pos.v, 4); circle(turtle.Pos.h, turtle.Pos.v+8, 4); circle(turtle.Pos.h, turtle.Pos.v-8, 4); circle(turtle.Pos.h, turtle.Pos.v, 15); h=18*cos(turtle.heading*PI/180); v=18*sin(turtle.heading*PI/180); x=turtle.Pos.h+h; y=turtle.Pos.v-v; circle(x, y, 3); x=turtle.Pos.h-h; y=turtle.Pos.v+v; x1=turtle.Pos.h-15*cos(turtle.heading*PI/180+PI/45); y1=turtle.Pos.v+15*sin(turtle.heading*PI/180+PI/45); line(x, y, x1, y1); x1=turtle.Pos.h-15*cos(turtle.heading*PI/180-PI/45); y1=turtle.Pos.v+15*sin(turtle.heading*PI/180-PI/45); line(x, y, x1, y1); } void DisHelpMenu() { setcolor(2); outtextxy(465, 55, "HELP:"); outtextxy(465, 300, "TURTLE STATE:"); outtextxy(465, 240, "STRUCTION INPUT:"); rectangle(465, 250, 510, 275); } void DisTState() { setfillstyle(SOLID_FILL, 8); bar(465, 310, 595, 445); setcolor(1); outtextxy(480, 315, "Pen:"); outtextxy(480, 328, "GMode:"); outtextxy(480, 341, "Color:"); outtextxy(480, 353, "Heading:"); outtextxy(480, 365, "Position"); outtextxy(490, 377, "x:"); outtextxy(490, 389, "y:"); outtextxy(480, 401, "X Range:"); outtextxy(480, 422, "Y Range;"); setcolor(7); outtextxy(520, 413, "0 ~ 360"); outtextxy(520, 435, "0 ~ 350"); } void RenovateTState() { char* t; setfillstyle(SOLID_FILL, 0); bar(520, 315, 599, 322); setcolor(7); if(turtle.pen==UP) outtextxy(520, 315, "UP "); else outtextxy(520, 315, "DOWN"); bar(536, 328, 599, 335); if(GMODE==MODE_KEY) outtextxy(536, 328, "Key"); else outtextxy(536, 328, "Command"); bar(550, 353, 599, 360); sprintf(t, "%.1f", turtle.heading); outtextxy(550, 353, t); bar(515, 377, 599, 384); sprintf(t, "%.2f", turtle.Pos.h-65); outtextxy(515, 377, t); bar(515, 389, 599, 396); sprintf(t, "%.2f", turtle.Pos.v-75); outtextxy(515, 389, t); setfillstyle(SOLID_FILL, turtle.color); bar(536, 341, 590, 348); if(turtle.color==8) { setcolor(7); rectangle(536, 341, 590, 348); } } int GetAColor() { int c; OpenSecCmdWnd(); c=GetAn4BInterger(); return c; } float GetAnAngle() { float h; OpenSecCmdWnd(); h=GetAn4BInterger(); return h; } float GetX(float s) { float x; x=turtle.Pos.h+s*cos(turtle.heading*PI/180); return x; } float GetY(float s) { float y; y=turtle.Pos.v-s*sin(turtle.heading*PI/180); return y; } void RenovateDArea() { FILE* fp; NODE n; if((fp=fopen("temp.txt", "rb"))==NULL) { ; } else { if(filelength(fileno(fp))!=0) { fseek(fp, 0, 0); while(!feof(fp)) { fread(&n, sizeof(NODE), 1, fp); setcolor(n.color); line(n.x1, n.y1, n.x2, n.y2); }
} fclose(fp); } setcolor(2); DisTurtle(); line(65, 75, 70, 75); line(65, 75, 65, 80); line(425, 75, 420, 75); line(425, 75, 425, 80); line(425, 425, 420, 425); line(425, 425, 425, 420); line(65, 425, 70, 425); line(65, 425, 65, 420); } void ClearDrawing() { FILE* fp; NODE n; if((fp=fopen("temp.txt", "rb"))==NULL) { ;} else { if(filelength(fileno(fp))!=0) { fseek(fp, 0, 0); while(!feof(fp)) { fread(&n, sizeof(NODE), 1, fp); setcolor(0); line(n.x1, n.y1, n.x2, n.y2); } } fclose(fp); } if((fp=fopen("temp.txt", "w"))==NULL) { ; } else { fclose(fp); } } void HelpMsg(HLPMSG hm) { setfillstyle(SOLID_FILL, 8); bar(465, 65, 595, 235); switch(hm) { case ALL_CMD: { setcolor(1); outtextxy(470, 70, "Cmds Listed:"); setcolor(7); outtextxy(490, 85, "PU, PD, CHC,"); outtextxy(490, 100, "FW, BW, CHP,"); outtextxy(490, 115, "CHHT, ADTH,"); outtextxy(490, 130, "CLR, CHM,"); outtextxy(490, 145, "EXIT"); setcolor(1); outtextxy(470, 175, "Make sure:"); setcolor(7); outtextxy(480, 190, "CAPITAL"); setcolor(1); outtextxy(545, 190, "input!"); break; } case IN_ERROR: { setcolor(4); outtextxy(480, 140, "Illegal Cmd!!!"); break; } case PU_OK: { setcolor(14); outtextxy(480, 140, "Pen Uo Ok!"); break; } case PD_OK: { setcolor(14); outtextxy(480, 140, "Pen Down Ok!"); break; } case FW_OK: { setcolor(14); outtextxy(480, 140, "ForWard Ok!"); break; } case BW_OK: { setcolor(14); outtextxy(480, 140, "BackWard Ok!"); break; } case CHC_OK: { setcolor(14); outtextxy(470, 130, "ChaNge Color"); outtextxy(520, 160, "OK!"); setfillstyle(SOLID_FILL, 8); bar(535, 160, 590, 170); outtextxy(535, 160, "!"); break; } case CHP_OK: { setcolor(14); outtextxy(470, 140, "ChaNge"); setfillstyle(SOLID_FILL, 8); bar(470, 140, 590, 159); outtextxy(470, 140, "ChaNge Postion"); outtextxy(520, 160, "Ok!"); break; } case CLR_OK: { setcolor(14); outtextxy(480, 140, "CLeaR Ok!"); break; } case CHHT_OK: { setcolor(14); outtextxy(470, 140, "ChaNge Head To-"); outtextxy(520, 160, "Ok!"); break; } case ADTH_OK: { setcolor(14); outtextxy(480, 140, "ADd To Head"); outtextxy(520, 160, "Ok!"); break; } case M_KEY: { setcolor(1); outtextxy(470, 70, "Key in use:"); setcolor(7); outtextxy(470, 80, "UP ARROW:"); setcolor(1); outtextxy(520, 90, "Forword"); setcolor(7); outtextxy(470, 100, "DOWN ARROW:"); setcolor(1); outtextxy(520, 110, "Backword"); setcolor(7); outtextxy(470, 120, "A:"); setcolor(1); outtextxy(490, 120, "Change color"); setcolor(7); outtextxy(470, 130, "ENTER:"); setcolor(1); outtextxy(469, 140, "Change pen state"); setcolor(7); outtextxy(470, 150, "SPACE:"); setcolor(1); outtextxy(480, 160, "Change heading"); setcolor(7); outtextxy(470, 170, "C:"); setcolor(1); outtextxy(490, 170, "Clear draw"); setcolor(7); outtextxy(470, 180, "X:"); setcolor(1); outtextxy(490, 180, "Exit"); setcolor(7); outtextxy(470, 190, "ESC:"); setcolor(1); outtextxy(490, 200, "Return to"); outtextxy(490, 210, "Command Mode"); break; } case IN_COLOR: { setcolor(1); outtextxy(470, 100, "Graph"); outtextxy(490, 115, "Driver&Mode:"); setcolor(7); outtextxy(490, 130, "VGA&VGAHI"); outtextxy(470, 150, "Input a number"); outtextxy(470, 165, "between 1~15"); setcolor(12); outtextxy(470, 185, "Thanks"); setcolor(13); outtextxy(540, 185, ":)"); setcolor(12); outtextxy(470, 200, "for cooperation!"); break; } case IN_HEAD: { setcolor(7); outtextxy(480, 140, "Using degrees!"); break; } case IN_POS: { setcolor(7); outtextxy(470, 70, "With \",\""); outtextxy(470, 85, "between x and y"); setcolor(1); outtextxy(470, 105, "Example:"); setcolor(7); outtextxy(490, 120, "24 166"); outtextxy(470, 140, "Best Within"); outtextxy(470, 155, "the X&Y range"); outtextxy(520, 170, "below!"); setcolor(12); outtextxy(470, 185, "Thanks"); setcolor(13); outtextxy(540, 185, ":)"); setcolor(12); outtextxy(470, 200, "for cooperation!"); break; } case IN_STEPS: { setcolor(7); outtextxy(470, 110, "Best Within"); outtextxy(470, 125, "the X&Y range"); outtextxy(520, 140, "below!"); setcolor(12); outtextxy(470, 155, "Thanks"); setcolor(13); outtextxy(540, 155, ":)"); setcolor(12); outtextxy(470, 170, "for cooperation!"); break; } }
} /*---------------------------------------*/
void StartTurtleGraphics() { setcolor(2); rectangle(10, 10, 630, 470); line(40, 40, 600, 40); outtextxy(70, 30, "MyName: CSDN"); outtextxy(220, 30, "Experiment Num: 008"); outtextxy(420, 30, "Question Num: 008"); rectangle(40, 50, 450, 450); rectangle(460, 50, 600, 450); rectangle(15, 15, 625, 465); } void StartTurtle() { turtle.Pos.h=245; turtle.Pos.v=250; turtle.color=GREEN; turtle.heading=0; turtle.pen=UP; setcolor(2); DisTurtle(); } void PenUp() { turtle.pen=UP; } void PenDown() { turtle.pen=DOWN; } int TurtleHeading() { return turtle.heading; } aPoint* TurtlePos() { return &turtle.Pos; } void MoveTTo(aPoint newPos) { FILE* fp; NODE n; if(newPos.h>425) newPos.h=65; if(newPos.h<65) newPos.h=425; if(newPos.v>425) newPos.v=75; if(newPos.v<75) newPos.v=425; if(turtle.pen==DOWN) { setcolor(turtle.color); n.x1=turtle.Pos.h; n.y1=turtle.Pos.v; n.x2=newPos.h; n.y2=newPos.v; if((fp=fopen("temp.txt", "ab"))==NULL) { ; } else { fwrite(&n, sizeof(NODE), 1, fp); fclose(fp); } } setcolor(0); DisTurtle(); turtle.Pos=newPos; setcolor(2); DisTurtle(); } void Move(int steps) { FILE* fp; NODE n; aPoint p; BOOL sc=FALSE; p.h=GetX(steps); p.v=GetY(steps); if(p.h>425) { if(turtle.pen==DOWN) sc=TRUE; p.h=65; turtle.pen=UP; } if(p.h<65) { if(turtle.pen==DOWN) sc=TRUE; p.h=425; turtle.pen=UP; } if(p.v>425) { if(turtle.pen==DOWN) sc=TRUE; p.v=75; turtle.pen=UP; } if(p.v<75) { if(turtle.pen==DOWN) sc=TRUE; p.v=425; turtle.pen=UP; } setcolor(0); DisTurtle(); if(turtle.pen==UP) MoveTTo(p); else { n.color=turtle.color; n.x1=(int)turtle.Pos.h; n.y1=(int)turtle.Pos.v; MoveTTo(p); n.x2=(int)turtle.Pos.h; n.y2=(int)turtle.Pos.v; if((fp=fopen("temp.txt", "ab"))==NULL) { ; } else { fwrite(&n, sizeof(NODE), 1, fp); fclose(fp); } } setcolor(2); DisTurtle(); if(sc==TRUE) turtle.pen=DOWN; } void Turn(int degrees) { turtle.heading+=degrees; if(turtle.heading>360) while(turtle.heading>360) {turtle.heading-=360;}; if(turtle.heading<0) while(turtle.heading<0) {turtle.heading+=360;}; } void TurnTTo(float angle) { turtle.heading=angle; } void SetTurtleColor(int color) { turtle.color=color; }
main() { int i, j, size; float t; FILE* fp; NODE n; aPoint p; BOOL quit=FALSE; HLPMSG hm=ALL_CMD; InitMyGraph(HIGH); StartTurtleGraphics(); DisHelpMenu(); StartTurtle(); DisTState(); RenovateTState(); RenovateDArea(); while(quit==FALSE) { hm=ALL_CMD; HelpMsg(hm); GetACmd(); if(GetKey1()==K_ENTER) { i=DecideCmd(); switch(i) { case EXIT: { ClearDrawing(); quit=TRUE; break; } case MAX_CMD_NUM: { HelpMsg(IN_ERROR); sleep(1); break; } case PU: { PenUp(); hm=PU_OK; break; } case PD: { PenDown(); hm=PD_OK; break; } case CHM: { if(GMODE==MODE_KEY) GMODE=MODE_CMD; else GMODE=MODE_KEY; for(i=0;i<4;i++) CmdTmp[i]=0; window(60, 17, 60, 17); printf(" "); HelpMsg(M_KEY); InstallKeyboard(); while(1) { RenovateDArea(); RenovateTState(); delay(1000); if(GetKey(K_ESC)) break; if(GetKey(K_UP)) { Move(10); } if(GetKey(K_DOWN)) { Move(-10); } if(GetKey(K_SPACE)) { t=1.0; setcolor(0); DisTurtle(); Turn(t); setcolor(2); DisTurtle(); } if(GetKey(K_A)) { turtle.color++; if(turtle.color>15) turtle.color=1; } if(GetKey(K_ENTER)) { if(turtle.pen==UP) turtle.pen=DOWN; else turtle.pen=UP; } if(GetKey(K_C)) { ClearDrawing(); }; if(GetKey(K_X)) { ClearDrawing(); goto end; } } ShutDownKeyboard(); GMODE=MODE_CMD; break; } case CHC: { HelpMsg(IN_COLOR); SetTurtleColor(GetAColor()); CloseSecCmdWnd(); hm=CHC_OK; break; } case CHHT: { HelpMsg(IN_HEAD); t=GetAnAngle(); setcolor(0); DisTurtle(); TurnTTo(t); setcolor(2); DisTurtle(); CloseSecCmdWnd(); hm=CHHT_OK; break; } case ADTH: { HelpMsg(IN_HEAD); t=GetAnAngle(); setcolor(0); DisTurtle(); Turn(t); setcolor(2); DisTurtle(); CloseSecCmdWnd(); hm=ADTH_OK; break; } case CHP: { HelpMsg(IN_POS); OpenSecCmdWnd(); StoreTwo4BInterger(); p.h=Cvt4CToInt(0); p.v=Cvt4CToInt(1); p.h+=65; p.v+=75; MoveTTo(p); CloseSecCmdWnd(); hm=CHP_OK; break; } case FW: { HelpMsg(IN_STEPS); OpenSecCmdWnd(); t=GetAn4BInterger(); Move((int)t); CloseSecCmdWnd(); hm=FW_OK; break; } case BW: { HelpMsg(IN_STEPS); OpenSecCmdWnd(); t=GetAn4BInterger(); Move((int)(-t)); CloseSecCmdWnd(); hm=BW_OK; break; } case CLR: { ClearDrawing(); hm=CLR_OK; break; } }; } for(i=0;i<4;i++) CmdTmp[i]=0; window(60, 17, 60, 17); printf(" "); RenovateDArea(); RenovateTState(); if(hm!=ALL_CMD && hm!=IN_ERROR) {HelpMsg(hm); sleep(1);} } end: closegraph(); unlink("temp.txt"); }

|