program Records;
@use "screen/screen"
var  
   i,j,shift,k: byte = 0;
/*
	The famous MCMC random walk!	

*/	

	// Monsterbtw: since the difference between hybrid/ multicolor/hires doesn't seem to be that big in terms of code, perhaps we should instead have a drop down list that lets you select multicolor type : record	
	monster_type = record
		prevx, prevy : byte; // previous position of monster
		x,y : byte; // Current position of monster 
		color : byte; // Current colour of monster
		// if you try to declare arrays within a record, you'll get an error message if you try to
		// create another array of the record type
//		faulty : array[10] of byte;
	end;

	randomTable : array[256] of byte;

	// Number of walkers
	const no : byte = 32;
	// Monster array allocation will fail if it is an array. 
	monsters : array[no] of monster_type;
	// The following is allowed even if monster_type contains an array
	singleMonster : monster_type;

	ptr : ^byte;

/*
	Initialize all the monsters
*/
procedure InitMonsters();
begin
	for i:=0 to no do
	begin
		monsters[i].x:=mod(random(),Screen::width); // Random x-position
		monsters[i].y:=mod(random(),Screen::height); // Random t-position
		monsters[i].prevx := monsters[i].x;
		monsters[i].prevy := monsters[i].y;
		monsters[i].color:=mod(random(),14)+blue+1; // Random colour excluding background
	end;

end;
/*
	Render all the monsters by first erasing the old position, then paining the new
*/
procedure RenderMonsters(render_char:byte);
begin
	for i:=0 to no do
	begin
//		screenmemory:=addresstable(#saddr,monsters[i].prevx,monsters[i].prevy);
		ptr := $0400 + Screen::tab40[monsters[i].prevy] + monsters[i].prevx;
		// Clear
		ptr^:=key_space;

		ptr := $0400 + Screen::tab40[monsters[i].y] + monsters[i].x;
		ptr^:=render_char;
		ptr+=+$D400; // point to color memory
		ptr^:=monsters[i].color; // set monter color
		
	end;	

end;



// Random walk: up, down,left,right, stop at walls
// Uses a lookup random table to decide which direction to go
procedure UpdateMonsters();
var
	dx,dy : byte;
begin
	k:=shift;
	for i:=0 to no do
	begin
		monsters[i].prevx := monsters[i].x;
		monsters[i].prevy := monsters[i].y;
		j:=randomTable[k];
		dx:=0;
		dy:=0;
		
		
 		if (monsters[i].x<>0) then
 			if (j=0) then dx:=-1;
 		if (monsters[i].x<>screen_width-1) then
			if (j=3) then dx:=1; // Wall X

		k+=11;			
		j:=randomTable[k];
		
		if (monsters[i].y<>0) then // Wall Y
			if (j=0) then dy:=-1;
			
		if (monsters[i].y<>screen_height-1) then // Wall Y
			if (j=3) then dy:=1;
			
		monsters[i].x+=dx;
		monsters[i].y+=dy;
	end;	

end;

 
begin
	// Initialize
	Screen::background := blue;
	Screen::border := blue;
	Screen::Clear(#Screen::screen0, key_space);
	Screen::Clear(#Screen::color, black);
	// Initialize tables
	for i:=0 to 256 do 
		randomTable[i]:=random()&3;

		
	InitMonsters();
	// Loop	
	while (true) do
	begin
		UpdateMonsters();
		RenderMonsters(0);// 'at' sign
		// Wait a bit each frame
		
		for i:=0 to 4 do
			Screen::WaitForVerticalBlank();
		shift+=1; // Some prime number
	end;	

end.
