using System;

namespace Template {

class Game
{
	public Surface screen;
	Cache cache = new Cache();
	const uint FRAMES = 32;		// 32 for buddhabrot debugging, 4096 for brot final, 256 for leaf
	uint _oOo_oOo(){return O>=V|N>=V?0:O*V+N;}
	uint I,N,F,O,M,_O,V=2018;double[]K=new double[999],Q=new double[999];
	public void Init(){V=800;F=0;I=1;}
	float R(){I^=I<<13;I^=I>>17;I^=I<<5;return I*2.3283064365387e-10f*6-3;} // rng
	void STOREUINT(int E,uint P,uint c){cache.Write32bit(4*((uint)E*V*V+P),c);}
	uint LOADUINT(int E,uint P){return cache.Read32bit(4*((uint)E*V*V+P));}
	public void Tick()
	{
        if (true)
		{
			double // based on www.rosettacode.org		ACCESS PATTERN: SOMEWHAT STRUCTURED
			z,q,x=0,y=0;for(F=0;++F<9e5;){N=(uint)
			(775-y*45);z=R();O=(uint)(x*55+400);if
			(z<.14){if(z<.1){if(z<.01){q=.0;y/=5;}
			else q=x/5-y/3;y=(x+y+8)/5;}else{q=y/3
			-.1*x;y=.5+x/3+y/5;}}else{q=.9*x+.04*y		// data access; to be cached:
			;y=.9*y-.04*x+2;}x=q;						STOREUINT( 1, _oOo_oOo (), (uint)(R()*14+80));
														STOREUINT( 2, _oOo_oOo (), (uint)(R()*40+168));
			/* END OF BLACK BOX CODE */					STOREUINT( 3, _oOo_oOo (), (uint)(R()*13+30));}
		}
		else
		{
			if(F<FRAMES)   // based on Paul Bourke		ACCESS PATTERN: MOSTLY RANDOM
			for(int G,M,T,E=0;++E<4;)for(G=0;++G<V
			<<7;){double B=0,y=0,t=R(),e,z=R();for
			(T=0;T<E<<8;){e=2*B*y+z;B=K[T]=B*B-y*y
			+t;y=Q[T++]=e;if(B*B+y*y>9){for(M=0;M<		
			T;){O=(uint)(400+.30*V*Q[M]);N=(uint)(		// data access; to be cached:
			.3*V*K[M++]+520);							STOREUINT( E, _oOo_oOo (),
														 LOADUINT( E, _oOo_oOo () ) + 1);
			/* END OF BLACK BOX CODE */;}break;}}}
		}

		// visualize data - rotated 90 degrees
		for( uint x = 0; x < 800; x++ ) for( uint y = 0; y < 800; y++ )
		{
			uint cr = Math.Min( 255U, LOADUINT( 1, y + x * 800 ) );
			uint cg = Math.Min( 255U, LOADUINT( 2, y + x * 800 ) );
			uint cb = Math.Min( 255U, LOADUINT( 3, y + x * 800 ) );
			screen.Plot( x, y, (int)(cr + (cg << 8) + (cb << 16 )) );
		}
    }
}

} // namespace Template
