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;
}