RubE On Conveyor Belts/Interpreter
Jump to navigation
Jump to search
#include <stdio.h> #include <windows.h> #include <ctype.h> #include <conio.h> #include <stdlib.h> #include <time.h> #define INITIAL_DELAY 200 #define FAST //#define RIGHTWAYUP int TICK_DELAY=100; #define MAX_PROGRAM_WIDTH 1000 #define MAX_PROGRAM_HEIGHT 1000 #define MAX_CONTROL_LENGTH 1000 #define MAX_CONTROL_TAPE 1000 #pragma warning(disable:4305) // truncation #pragma warning(disable:4309) // truncation of constant value int PROGRAM_WIDTH=80; int PROGRAM_HEIGHT=24; int state=0; // MUST BE UNSIGNED! // Otherwise all sorts of weird things happen. unsigned char program[MAX_PROGRAM_HEIGHT][MAX_PROGRAM_WIDTH]={ " r ", " ! ", " ", " ", " <<<<<<<O>>>>> ", " 4 ", " <<<O = <<<O>>> ", " 1 7 ", " O = O> = O ", " 0 6 8 ", " = O> = = ", " 3 ", " = O ", " 5 ", " O> = ", " 2 ", " = ", " ", " ", " ", " T * T * T ", " F ]F ]F ", "===============================================================================", " " }; char control[MAX_CONTROL_LENGTH]="+[dsti[o[-]]+]"; unsigned short control_tape[MAX_CONTROL_TAPE]; unsigned short xdata[MAX_PROGRAM_HEIGHT][MAX_PROGRAM_WIDTH]; FILE *out; int isFinished=0; int ticks_since_output=0; char input_char=0; bool iscrate(unsigned char c) { return isdigit(c) || c=='b' || c=='r'; } // Returns true if successful bool pushBlocksLeft(int x,int y) { int blocks_left_edge=x; if(y<0 || y>=PROGRAM_HEIGHT || x<0 || x>=PROGRAM_WIDTH) return false; while(iscrate(program[y][blocks_left_edge]) || iscrate(program[y][blocks_left_edge]&0x7F) && blocks_left_edge>0) blocks_left_edge--; if(blocks_left_edge==0) return false; // Can't push into edge of program if(program[y][blocks_left_edge]!=' ' && program[y][blocks_left_edge]!='F' && program[y][blocks_left_edge]!='\\') return false; // Can't push into other objects besides furnace or ramp if(program[y][blocks_left_edge]=='\\' && !pushBlocksLeft(y-1,blocks_left_edge-1)) return false; bool was_furnace=(program[y][blocks_left_edge]=='F'); bool was_ramp=(program[y][blocks_left_edge]=='\\'); for(int k=blocks_left_edge;k<x;k++) { program[y][k]=program[y][k+1]|0x80; xdata[y][k]=xdata[y][k+1]; program[y][k+1]=' '; } if(was_furnace) program[y][blocks_left_edge]='F'; else if(was_ramp) { program[y-1][blocks_left_edge-1]=program[y][blocks_left_edge]; program[y][blocks_left_edge]='\\'; } return true; // Success! } // Returns true if successful bool pushBlocksRight(int x,int y) { int blocks_right_edge=x; if(y<0 || y>=PROGRAM_HEIGHT || x<0 || x>=PROGRAM_WIDTH) return false; while(iscrate(program[y][blocks_right_edge]) || iscrate(program[y][blocks_right_edge]&0x7F) && blocks_right_edge<PROGRAM_WIDTH-1) blocks_right_edge++; if(blocks_right_edge==PROGRAM_WIDTH-1) return false; // Can't push into edge of program if(program[y][blocks_right_edge]!=' ' && program[y][blocks_right_edge]!='F' && program[y][blocks_right_edge]!='/') return false; // Can't push into other objects besides empty space, ramp or furnace. if(program[y][blocks_right_edge]=='/' && !pushBlocksRight(y-1,blocks_right_edge+1)) return false; bool was_furnace=(program[y][blocks_right_edge]=='F'); bool was_ramp=(program[y][blocks_right_edge]=='/'); for(int k=blocks_right_edge;k>x;k--) { if(program[y][k]!=' ') return false; // Error! program[y][k]=program[y][k-1]|0x80; xdata[y][k]=xdata[y][k-1]; program[y][k-1]=' '; } if(was_furnace) program[y][blocks_right_edge]='F'; else if(was_ramp) { program[y-1][blocks_right_edge+1]=program[y][blocks_right_edge]; program[y][blocks_right_edge]='/'; } return true; // Success! } // 0x80 is added to anything which has moved at least once during // the tick. void doGun(int x,int y,int dx,int dy,char target) { char moving; if(x-dx < 0 || y-dy < 0 || x-dx >= PROGRAM_WIDTH || y-dy >= PROGRAM_HEIGHT) return; int ix=x, iy=y; moving=program[y-dy][x-dx]; if(!iscrate(moving)) return; if(moving & 0x80) return; while(true) // Not really { if(x < 0 || y < 0 || x >= PROGRAM_WIDTH || y >= PROGRAM_HEIGHT) break; x+=dx; y+=dy; if(program[y][x] == target) { x+=dx; y+=dy; if(x < 0 || y < 0 || x >= PROGRAM_WIDTH || y >= PROGRAM_HEIGHT) break; if(program[y][x] != ' ') break; program[y][x]=moving | 0x80; program[iy-dy][ix-dx]=' '; break; } } } void doCell(int x,int y,char c) { int p1; int p2; int result; switch(c) { case 'G': // left doGun(x,y,-1,0,'t'); break; case 'H': // down doGun(x,y,0,1,'t'); break; case 'J': // right doGun(x,y,1,0,'t'); break; case 'Y': // up doGun(x,y,0,-1,'t'); break; case '!': if(y<PROGRAM_HEIGHT-1 && y>0 && (iscrate(program[y-1][x]&0x7F) || program[y-1][x]=='r') && program[y+1][x]==' ') { #ifndef FAST if(xdata[y][x]==1) { #endif program[y+1][x]=program[y-1][x]|0x80; xdata[y+1][x]=xdata[y-1][x]; xdata[y][x]=0; #ifndef FAST } else xdata[y][x]=1; #endif } break; case 'i': if(y<PROGRAM_HEIGHT-1 && y>0 && (iscrate(program[y+1][x]&0x7F) || program[y+1][x]=='r') && program[y-1][x]==' ') { #ifndef FAST if(xdata[y][x]==1) { #endif program[y-1][x]=program[y+1][x]|0x80; xdata[y+1][x]=xdata[y-1][x]; xdata[y][x]=0; #ifndef FAST } else xdata[y][x]=1; #endif } break; case 'V': if(y>0 && y<PROGRAM_HEIGHT-1 && iscrate(program[y-1][x]) && (program[y+1][x]==' ' || program[y+1][x]=='V')) { int out_y = y; while(out_y < PROGRAM_HEIGHT-1 && program[out_y][x]=='V') out_y++; if(program[out_y][x]!=' ') break; program[out_y][x]=program[y-1][x]|0x80; xdata[out_y][x]=xdata[y-1][x]; program[y-1][x]=' '; } break; case 'A': if(y>0 && y<PROGRAM_HEIGHT-1 && iscrate(program[y+1][x]) && (program[y-1][x]==' ' || program[y-1][x]=='A')) { int out_y = y; while(out_y > 0 && program[out_y][x]=='A') out_y--; if(program[out_y][x]!=' ') break; program[out_y][x]=program[y+1][x]|0x80; xdata[out_y][x]=xdata[y+1][x]; program[y+1][x]=' '; } break; case 'W': if(y>0 && y<PROGRAM_HEIGHT-1 && iscrate(program[y-1][x]) && program[y+1][x]==' ') { program[y+1][x]=program[y-1][x]|0x80; xdata[y+1][x]=xdata[y-1][x]; program[y-1][x]=' '; program[y][x]='M'; } break; case 'M': if(y>0 && y<PROGRAM_HEIGHT-1 && iscrate(program[y+1][x]) && program[y-1][x]==' ') { program[y-1][x]=program[y+1][x]|0x80; xdata[y-1][x]=xdata[y+1][x]; program[y+1][x]=' '; program[y][x]='W'; } break; case '<': if(y>0 && x>0 && iscrate(program[y-1][x]) /*&& program[y-1][x-1]==' '*/) { /*program[y-1][x-1]=program[y-1][x]|0x80; xdata[y-1][x-1]=xdata[y-1][x]; program[y-1][x]=' ';*/ pushBlocksLeft(x,y-1); } break; case '>': if(y>0 && x<PROGRAM_WIDTH-1 && iscrate(program[y-1][x]) /*&& program[y-1][x+1]==' '*/) { /*program[y-1][x+1]=program[y-1][x]|0x80; xdata[y-1][x+1]=xdata[y-1][x]; program[y-1][x]=' ';*/ pushBlocksRight(x,y-1); } break; case 'O': if(y==0 || !iscrate(program[y-1][x])) break; if(y==PROGRAM_HEIGHT-1 || !iscrate(program[y+1][x]&0x7F)) break; p1=program[y-1][x]-'0'; p2=(program[y+1][x]&0x7F)-'0'; if(p1>p2) // move right { if(x<PROGRAM_WIDTH-1 && program[y-1][x+1]==' ') { program[y-1][x+1]=program[y-1][x]; xdata[y-1][x+1]=xdata[y-1][x]; program[y-1][x]=' '; } } else // move left { if(x>0 && program[y-1][x-1]==' ') { program[y-1][x-1]=program[y-1][x]; xdata[y-1][x-1]=xdata[y-1][x]; program[y-1][x]=' '; } } break; case ']': #ifndef FAST if(xdata[y][x]==0) { xdata[y][x]=1; break; } #endif if(y<PROGRAM_HEIGHT-1 && program[y+1][x]==' ') { program[y+1][x]=']'|0x80; program[y][x]=' '; xdata[y+1][x]=0; } else if(y>1 && program[y-1][x]=='^') { program[y-2][x]=']'|0x80; program[y][x]=' '; xdata[y-2][x]=0; } else if(x>0) { if(iscrate(program[y][x-1])) { if(x<=1 || !pushBlocksLeft(x-1,y)) break; } else if(y<0 && program[y][x-1]=='\\') { if(iscrate(program[y-1][x-1])) if(!pushBlocksLeft(x-1,y-1)) break; program[y-1][x-1]=']'|0x80; program[y][x]=' '; } else if(program[y][x-1]!=' ') break; // don't move program[y][x-1]=']'|0x80; xdata[y][x-1]=0; program[y][x]=' '; if(y>0 && x>1 && program[y-1][x-2]=='T') { program[y][x-1]='['|0x80; xdata[y][x-1]=0; } } break; case '[': #ifndef FAST if(xdata[y][x]==0) { xdata[y][x]=1; break; } #endif if(y<PROGRAM_HEIGHT-1 && program[y+1][x]==' ') { program[y+1][x]='['|0x80; program[y][x]=' '; xdata[y+1][x]=0; } else if(y>1 && program[y-1][x]=='^') { program[y-2][x]='['|0x80; program[y][x]=' '; xdata[y-2][x]=0; } else if(x<PROGRAM_WIDTH-1) { if(iscrate(program[y][x+1])) { if(x>=PROGRAM_WIDTH-2 || !pushBlocksRight(x+1,y)) break; } else if(y<0 && program[y][x+1]=='/') { if(iscrate(program[y-1][x+1])) if(!pushBlocksRight(x+1,y-1)) break; program[y-1][x+1]='['|0x80; program[y][x]=' '; } else if(program[y][x+1]!=' ') break; // don't move program[y][x+1]='['|0x80; program[y][x]=' '; xdata[y][x+1]=0; if(y>0 && x<PROGRAM_WIDTH-2 && program[y-1][x+2]=='T') { program[y][x+1]=']'|0x80; xdata[y][x+1]=0; } } break; case '*': if(y<PROGRAM_HEIGHT-1 && iscrate(program[y+1][x]&0x7F) && !(program[y+1][x]&0x80)) { if(program[y+1][x]=='r') break; // can't output random crate if(program[y+1][x]=='b') fprintf(out," %i",xdata[y+1][x]); else fprintf(out," %c",program[y+1][x]&0x7F); ticks_since_output=0; } break; case '?': if(y<PROGRAM_HEIGHT-1 && input_char!='\0' && program[y+1][x]==' ') program[y+1][x]=input_char; break; case 'r': if(!((y<PROGRAM_HEIGHT-1 && program[y+1][x]=='!') || (y>0 && program[y-1][x]=='i'))) // don't change if on a copier program[y][x]=(rand()%10+'0')|0x80; if(y<PROGRAM_HEIGHT-1 && program[y+1][x]==' ') { program[y+1][x]=program[y][x]|0x80; program[y][x]=' '; } break; case 'F': if(x<PROGRAM_WIDTH-1 && iscrate(program[y][x+1]&0x7F)) program[y][x+1]=' '; if(x>0 && iscrate(program[y][x-1]&0x7F)) program[y][x-1]=' '; if(y>0 && iscrate(program[y-1][x]&0x7F)) program[y-1][x]=' '; if(y<PROGRAM_HEIGHT-1 && iscrate(program[y+1][x]&0x7F)) program[y+1][x]=' '; break; case '-': if(x==0 || x==PROGRAM_WIDTH-1 || y==PROGRAM_HEIGHT-1) break; if(!iscrate(program[y+1][x-1]) || !iscrate(program[y+1][x])) break; if(program[y+1][x+1]!=' ') break; if(program[y+1][x+1]!=' ') break; if(program[y+1][x-1]!='b') p1=program[y+1][x-1]-'0'; else p1=xdata[y+1][x-1]; if(program[y+1][x]!='b') p2=program[y+1][x]-'0'; else p2=xdata[y+1][x]; result=(signed short)p1-(signed short)p2; if(result<10 && result>=0) program[y+1][x+1]=result+'0'|0x80; else { program[y+1][x+1]='b'; xdata[y+1][x+1]=result; } program[y+1][x-1]=' '; program[y+1][x]=' '; break; case '+': if(x==0 || x==PROGRAM_WIDTH-1 || y==PROGRAM_HEIGHT-1) break; if(!iscrate(program[y+1][x-1]) || !iscrate(program[y+1][x]) || program[y+1][x-1]=='r' || program[y+1][x]=='r') break; if(program[y+1][x+1]!=' ') break; if(program[y+1][x-1]!='b') p1=program[y+1][x-1]-'0'; else p1=xdata[y+1][x-1]; if(program[y+1][x]!='b') p2=program[y+1][x]-'0'; else p2=xdata[y+1][x]; result=(signed short)p1+(signed short)p2; if(result<10 && result>=0) program[y+1][x+1]=result+'0'|0x80; else { program[y+1][x+1]='b'; xdata[y+1][x+1]=result; } program[y+1][x-1]=' '; program[y+1][x]=' '; break; /* case 'x': if(x==0 || x==PROGRAM_WIDTH-1 || y==PROGRAM_HEIGHT-1) break; if(!iscrate(program[y+1][x-1]) || !iscrate(program[y+1][x])) break; if(program[y+1][x+1]!=' ') break; if(program[y+1][x+1]!=' ') break; if(program[y+1][x-1]!='b') p1=program[y+1][x-1]-'0'; else p1=xdata[y+1][x-1]; if(program[y+1][x]!='b') p2=program[y+1][x]-'0'; else p2=xdata[y+1][x]; result=p1*p2; if(result<10) program[y+1][x+1]=result+'0'|0x80; else { program[y+1][x+1]='b'; xdata[y+1][x+1]=result; } program[y+1][x-1]=' '; program[y+1][x]=' '; break; case 'd': if(x==0 || x==PROGRAM_WIDTH-1 || y==PROGRAM_HEIGHT-1) break; if(!iscrate(program[y+1][x-1]) || !iscrate(program[y+1][x])) break; if(program[y+1][x+1]!=' ') break; if(program[y+1][x+1]!=' ') break; if(program[y+1][x-1]!='b') p1=program[y+1][x-1]-'0'; else p1=xdata[y+1][x-1]; if(program[y+1][x]!='b') p2=program[y+1][x]-'0'; else p2=xdata[y+1][x]; if(p2==0) result=-1; else result=p1/p2; if(result>=0) { if(result<10) program[y+1][x+1]=result+'0'|0x80; else { program[y+1][x+1]='b'; xdata[y+1][x+1]=result; } } program[y+1][x-1]=' '; program[y+1][x]=' '; break;*/ case 'D': if(x>0 && x<PROGRAM_WIDTH-1) { if(program[y][x-1]!=' ' && program[y][x+1]==' ' && !(xdata[y][x]&2)) { program[y][x+1]='='; xdata[y][x]|=1; } if(program[y][x-1]==' ' && xdata[y][x]&1) { program[y][x+1]=' '; xdata[y][x]&=~1; } if(program[y][x+1]!=' ' && program[y][x-1]==' ' && !(xdata[y][x]&1)) { program[y][x-1]='='; xdata[y][x]|=2; } if(program[y][x+1]==' ' && xdata[y][x]&2) { program[y][x-1]=' '; xdata[y][x]&=~2; } } if(y>0 && y<PROGRAM_WIDTH-1) { if(program[y-1][x]!=' ' && program[y+1][x]==' ' && !(xdata[y][x]&8)) { program[y+1][x]='|'; xdata[y][x]|=4; } if(program[y-1][x]==' ' && xdata[y][x]&4) { program[y+1][x]=' '; xdata[y][x]&=~4; } if(program[y+1][x]!=' ' && program[y-1][x]==' ' && !(xdata[y][x]&4)) { program[y-1][x]='|'; xdata[y][x]|=8; } if(program[y+1][x]==' ' && xdata[y][x]&8) { program[y-1][x]=' '; xdata[y][x]&=~8; } } break; case 's': if(y<PROGRAM_HEIGHT-1 && iscrate(program[y+1][x]&0x7F) && x<PROGRAM_WIDTH-1) { bool moved=(program[y+1][x]&0x7F)?true:false; int num=program[y+1][x]&0x7F; if(num=='r') break; if(num!='b') { program[y+1][x+1]=program[y+1][x]; xdata[y+1][x+1]=xdata[y+1][x]; program[y+1][x]=' '; break; } char buf[10]; sprintf(buf,"%i",xdata[y+1][x]); int len=strlen(buf); if(x<PROGRAM_WIDTH-len) { int found_obstruction=0; for(int k=x+1;k<x+len+1;k++) { if(program[y+1][k]!=' ') { found_obstruction=1; break; } } if(found_obstruction) break; memcpy(&program[y+1][x+1],buf,len); program[y+1][x]=' '; } } break; case 'a': if(y>0 && isdigit(program[y-1][x]&0x7F)) { int respond=(program[y-1][x] & 0x7F)-'0'; if(state!=respond) { if(program[y+1][x]==' ') program[y+1][x]='|'; if(program[y][x+1]==' ') program[y][x+1]='='; if(program[y][x-1]==' ') program[y][x-1]='='; } if(state==respond) { if(program[y+1][x]=='|') program[y+1][x]=' '; if(program[y][x+1]=='=') program[y][x+1]=' '; if(program[y][x-1]=='=') program[y][x-1]=' '; xdata[y][x]=0; } } break; case '\\': if(y>0 && x<PROGRAM_WIDTH-1 && iscrate(program[y-1][x])) { program[y][x+1]=program[y-1][x]|0x80; xdata[y][x+1]=xdata[y-1][x]; program[y-1][x]=' '; } break; case '/': if(y>0 && x>0 && iscrate(program[y-1][x])) { program[y][x-1]=program[y-1][x]|0x80; xdata[y][x-1]=xdata[y-1][x]; program[y-1][x]=' '; } break; case '0':case '1':case '2':case '3':case '4': case '5':case '6':case '7':case '8':case '9': case 'b': if(y<PROGRAM_HEIGHT-1 && program[y+1][x]==' ') { program[y+1][x]=program[y][x]|0x80; xdata[y+1][x]=xdata[y][x]; program[y][x]=' '; } break; } } const COORD topleft={0,0}; const HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE); void ResetCursorPosition() { SetConsoleCursorPosition(hStdout,topleft); } void ShowCurrentState() { for(int k=0;k<PROGRAM_HEIGHT;k++) printf("%s\n",program[k]); } /*void doTick() { ticks_since_output++; for(int x=0;x<PROGRAM_WIDTH;x++) { #ifdef RIGHTWAYUP for(int y=0;y<PROGRAM_HEIGHT;y++) #else for(int y=PROGRAM_HEIGHT-1;y>=0;y--) #endif { doCell(x,y,program[y][x]); } } for(x=0;x<PROGRAM_WIDTH;x++) { for(int y=0;y<PROGRAM_HEIGHT;y++) { if(program[y][x]&0x80) program[y][x]&=0x7F; } } input_char=' '; }*/ void doAllOfType(char c1=0,char c2=0,char c3=0,char c4=0,char c5=0) { for(int x=0;x<PROGRAM_WIDTH;x++) { for(int y=PROGRAM_HEIGHT-1;y>=0;y--) { char c=program[y][x]; if((c1==0 && iscrate(c)) || c==c1 || c==c2 || c==c3 || c==c4 || c==c5) doCell(x,y,c); } } } void doTick() { ticks_since_output++; doAllOfType('*','?','s','a'); doAllOfType('D','F','r'); doAllOfType('A','V','^'); doAllOfType(0,'\\','/'); doAllOfType('i','!','M','W'); doAllOfType('G','H','J','Y'); doAllOfType('[',']','>','<'); doAllOfType('O','+','-'); for(int x=0;x<PROGRAM_WIDTH;x++) { for(int y=0;y<PROGRAM_HEIGHT;y++) { if(program[y][x]&0x80) program[y][x]&=0x7F; } } input_char=' '; } void readProgram(char *from) { FILE *f=fopen(from,"r"); if(!f) { perror(from); exit(1); } char *buf=new char[100]; fgets(buf,100,f); int control_len=0; if(*buf=='c') sscanf(buf,"%*c%i %i %i",&PROGRAM_WIDTH,&PROGRAM_HEIGHT,&control_len); else sscanf(buf,"%i %i",&PROGRAM_WIDTH,&PROGRAM_HEIGHT); PROGRAM_WIDTH++; // the NUL terminator for each line delete [] buf; if(control_len>0) { if(control_len>=MAX_CONTROL_LENGTH) { fprintf(stderr,"Program control too long. Maximum length: %i\n",MAX_CONTROL_LENGTH-1); exit(2); } buf=new char[control_len+3]; fgets(buf,control_len+3,f); char *pStr=strchr(buf,'\n'); if(pStr) *pStr='\0'; else { fprintf(stderr,"The control length must accurately reflect the length of the control.\n"); delete [] buf; exit(3); } strcpy(control,buf); delete [] buf; } if(PROGRAM_HEIGHT>=MAX_PROGRAM_HEIGHT || PROGRAM_WIDTH>=MAX_PROGRAM_WIDTH) { fprintf(stderr,"Program too big. Maximum dimensions: %i by %i\n",MAX_PROGRAM_WIDTH-1,MAX_PROGRAM_HEIGHT-1); exit(2); } buf=new char[PROGRAM_WIDTH+3]; for(int y=0;y<PROGRAM_HEIGHT;y++) { fgets(buf,PROGRAM_WIDTH+3,f); char *pStr=strchr(buf,'\n'); if(pStr) *pStr='\0'; else if(y<PROGRAM_HEIGHT-1) { fprintf(stderr,"Programs must have one line in the file for every program line.\n"); delete [] buf; exit(3); } strcpy((char*)program[y],buf); } delete [] buf; fclose(f); memset(xdata,0,sizeof xdata); } int main(int argc,char **argv) { if(argc>=2) { if(!strcmp(argv[1],"--help")) { printf("RubE On Conveyor Belts usage:\n"); printf("\t%s\n\t\tExecute the default program, which is implementation-dependent\n",argv[0]); printf("\t%s FILENAME\n\t\tExecute the specified program\n",argv[0]); return 0; } if(!strcmp(argv[1],"--version")) { printf("RubE On Conveyor Belts\n"); printf("Whichever version you want it to be\n"); printf("By immibis\n"); return 0; } } if(argc>2) { printf("Too many arguments - for help, use '%s --help'\n",argv[0]); return 1; } if(argc==2) readProgram(argv[1]); // else do nothing - use the default program SMALL_RECT windowSize; windowSize.Left=0; windowSize.Top=0; windowSize.Bottom=max(24,PROGRAM_HEIGHT); windowSize.Right=max(79,PROGRAM_WIDTH); COORD bufferSize; bufferSize.X=max(80,PROGRAM_WIDTH+1); bufferSize.Y=max(25,PROGRAM_HEIGHT+1); if(!SetConsoleScreenBufferSize(hStdout,bufferSize)) { printf("SetConsoleScreenBufferSize: %i\n",GetLastError()); return 1; } if(!SetConsoleWindowInfo(hStdout,TRUE,&windowSize)) { printf("SetConsoleWindowInfo: %i\n",GetLastError()); return 1; } int cc=0; // control counter int tc=0; // tape counter srand(time(NULL)); ResetCursorPosition(); ShowCurrentState(); Sleep(INITIAL_DELAY); out=fopen("program.out","w"); while(!isFinished) { #ifndef BYPASS_CONTROL switch(control[cc]) { case '+': control_tape[tc]++; break; case '-': control_tape[tc]--; break; case '[': if(control_tape[tc]==0) { int level=0; do { if(control[cc]=='\0') { isFinished=1; break; } if(control[cc]=='[') level++; if(control[cc]==']') level--; cc++; } while(level>0); cc--; } break; case ']': if(control_tape[tc]!=0) { int level=0; do { if(cc<0) { isFinished=1; break; } if(control[cc]=='[') level--; if(control[cc]==']') level++; cc--; } while(level>0); cc++; } break; case 'i':case ',': if(_kbhit()) { char ch; ch=_getch(); if(ch=='`') isFinished=1; if(ch=='+') TICK_DELAY=int(double(TICK_DELAY)*0.80); if(ch=='-') TICK_DELAY=int(double(TICK_DELAY+4)*1.25); control_tape[tc]=ch; } else control_tape[tc]=0; break; case '<': if(tc>0) tc--; break; case '>': if(tc<MAX_CONTROL_TAPE-1) tc++; break; case '\0': isFinished=1; break; case 's': Sleep(TICK_DELAY); break; case 't': doTick(); break; case 'd': ResetCursorPosition(); ShowCurrentState(); break; case 'a': state=control_tape[tc]%10; break; case 'o': input_char=(char)control_tape[tc]; if(input_char=='b' || !iscrate(input_char)) input_char='\0'; break; case 'O': input_char=control_tape[tc]+'0'; if(input_char<'0' || input_char>'9') input_char='\0'; break; } cc++; #else ResetCursorPosition(); ShowCurrentState(); Sleep(TICK_DELAY); doTick(); if(_kbhit()) { input_char=_getch(); if(input_char=='`') isFinished=1; if(input_char=='+') TICK_DELAY=int(double(TICK_DELAY)*0.80); if(input_char=='-') TICK_DELAY=int(double(TICK_DELAY+4)*1.25); if(!iscrate(input_char)) input_char='\0'; } #endif } fclose(out); return 0; }