int V=960,t,k=640,E=480,o,n,e=0,m[][],O=25;PImage q;S $,_;void setup(){PGraphics J;size(960,640,P2D);frameRate(30);for(;e<2;e++){J=createGraphics(50,300);J.beginDraw();J.stroke(255,0,0);if(e==1){J.stroke(0,0,255);}J.strokeWeight(5);J.ellipse(O,O,50,50);J.line(O,50,25,150);J.line(O,150,0,300);J.line(O,150,50,300);J.line(O,50,0,150);J.line(O,50,50,150);J.endDraw();q=J.get();if(e==1){_=new S(0,0,0,q,1);}else{$=new S(0,0,0,q,1);}}J=createGraphics(4,4);J.beginDraw();J.fill(0);J.rect(0,0,4,4);J.endDraw();q=J.get();fill(0);textSize(72);text("P1: Arrow Keys and M",85,160);text("P2: ESDF and Q",200,E);}boolean W=true,f=false,v[][];int M=1;void draw(){t=millis();if(W){if(M-->0)return;W=false;M=1;while(millis()-t<3000);$.h=_.h=100;m=new int[n=(int)random(15,20)][o=(int)random(15,20)];D(1,1,o-2,n-2);int x=0,y=$.b=_.b=0;for(;x<o;x++){m[0][x]=1;m[n-1][x]=1;}for(;y<n;y++){m[y][0]=1;m[y][o-1]=1;}f=false;while(!f){v=new boolean[n][o];p($);p(_);F((int)$.x,(int)$.y);}b.clear();return;}noStroke();background(60,143,50);fill(60,43,150);rect(0,k/4,V,k/4);rect(0,k*3/4,V,k/4);stroke(128);$.r(160);$.R(_,$.d,160);d($,$.d,160);_.r(E);_.R($,_.d,E);d(_,_.d,E);stroke(0);line(0,k/2,V,k/2);line(V/2,155,V/2,165);line(V/2-5,160,V/2+5,160);line(V/2,475,V/2,485);line(V/2-5,E,V/2+5,E);U($,K,t-e);U(_,H,t-e);for(int i=b.size()-1;i>=0;i--){S B=b.get(i);float T=min(A(B,B.a),float(t-e)/100),X=G(B.a)*T,Y=-I(B.a)*T,Q=0;if(C(B.x+X,B.y+Y)){B.x+=X;B.y+=Y;}else{Q=1;}if(sqrt(sq(B.x-$.x)+sq(B.y-$.y))<.2){$.h-=10;Q=1;}if(sqrt(sq(B.x-_.x)+sq(B.y-_.y))<.2){_.h-=10;Q=1;}if(Q==1){B.p.b--;b.remove(i);}}textSize(30);fill(0);text("\u2665"+$.h+" Wins: "+$.w,10,310);text("\u2665"+_.h+" Wins: "+_.w,10,630);if($.h<=0){textSize(72);fill(255);text("P2 WINS",340,E);W=true;_.w++;}if(_.h<=0){textSize(72);fill(255);text("P1 WINS",340,160);W=true;$.w++;}e=t;}float N(float a){while(a<0)a+=360;while(a>=360)a-=360;return a;}float T(float a){return tan(radians(a));}float I(float a){return sin(radians(a));}float G(float a){return cos(radians(a));}void p(S p){int x=0,y=0;while(m[y][x]!=0){y=(int)random(n);x=(int)random(o);}p.x=x+.5;p.y=y+.5;}void F(int x,int y){if(v[y][x])return;v[y][x]=true;if(x==floor(_.x)&&y==floor(_.y))f=true;if(f||m[y][x]==1)return;F(x-1,y);F(x,y-1);F(x+1,y);F(x,y+1);}void D(int x,int y,int w,int h){if(w<6||h<6)return;boolean H=true;if(h<=w)H=false;int Q=x+(H?0:int(random(w-2))),L=y+(H?int(random(h-2)):0),A=Q+(H?int(random(w)):0),B=L+(H?0:int(random(h))),i=H?w:h;for(;i>=0;i--){if(Q!=A||L!=B){m[L][Q]=1;}Q+=H?1:0;L+=H?0:1;}D(x,y,H?w:Q-x+1,H?L-y+1:h);D(H?x:Q+1,H?L+1:y,H?w:x+w-Q-1,H?y+h-L-1:h);}ArrayList<S> b=new ArrayList<S>();void c(S p){if(p.b>5)return;p.b++;S Z=new S(p.x,p.y,p.a,q,.1);Z.p=p;Z.x+=G(Z.a)/2;Z.y-=I(Z.a)/2;b.add(Z);}void d(S p,float[]d,int c){for(S B:b){p.R(B,d,c);}}int g[]={38,37,40,39},h[]={'e','s','d','f'};boolean K[]=new boolean[4],H[]=new boolean[4];boolean C(float a,float b){int x=floor(a),y=floor(b),w=ceil(a),z=ceil(b);if(m[y][x]!=0||m[y-1][x]!=0&&abs(b-y)<.2||m[z][x]!=0&&abs(z-y)<.2||m[y][x-1]!=0&&abs(a-x)<.2||m[y][w]!=0&&abs(w-x)<.2)return false;return true;}void U(S p,boolean Z[],float T){if(Z[0]){float D=min(T/400,A(p,p.a)),j=G(p.a)*D,v=-I(p.a)*D;if(C(p.x+j,p.y))p.x+=j;if(C(p.x,p.y+v))p.y+=v;}if(Z[1])p.a+=.08*T;if(Z[2]){float D=min(T/400,A(p,N(p.a-180))),j=G(p.a)*D,v=-I(p.a)*D;if(C(p.x-j,p.y))p.x-=j;if(C(p.x,p.y-v))p.y-=v;}if(Z[3])p.a-=.08*T;p.a=N(p.a);}void keyPressed(){l(true);if(key=='m')c($);if(key=='q')c(_);}void keyReleased(){l(false);}void l(boolean x){for(int i=0;i<4;i++){if(key==h[i])H[i]=x;if(keyCode==g[i])K[i]=x;}}float A(S p,float r){boolean R=r<90||r>270,u=r<180;float s=T(r),z=R?1:-1,v=R?ceil(p.x):floor(p.x),w=p.y+(v-p.x)*-s,t=sqrt(sq(v-p.x)+sq(w-p.y)),h=sqrt(sq(s)+1),L=u?-1:1,W=u?floor(p.y):ceil(p.y),V=p.x+(W-p.y)/-s,Q=sqrt(sq(V-p.x)+sq(W-p.y)),H=sqrt(1/sq(s)+1);while(true){if(Q<t){if(P(r,V,W,1)){return sqrt(sq(V-p.x)+sq(W-p.y));}else{Q+=H;V+=-L/s;W+=L;}}else{if(P(r,v,w,0)){return sqrt(sq(v-p.x)+sq(w-p.y));}else{t+=h;v+=z;w+=-z*s;}}}}boolean P(float r,float a,float b,int t){int x=floor(a),y=floor(b);if(t==0&&r>90&&r<270)x--;if(t==1&&r<180)y--;if(x>=o||y>=n||m[y][x]>0)return true;return false;}class S{float x,y,a,s,d[];int b,w,h=100;S p;PImage i;S(float A,float B,float C,PImage D,float E){x=A;y=B;a=C;i=D;s=E;}void r(int M){d=new float[960];float C=N(a+45);for(int i=0;i<V;i++){float D=A(this,C),P=G(a-C),S=min(E/(P*D),k/2);d[i]=D;line(i,M-S/2,i,M+S/2);C=N(a-degrees(atan(float(i)/E-1)));}}void R(S s,float[]Q,int M){float A=s.x-x,B=s.y-y,C=sqrt(sq(A)+sq(B)),D=s.i.height,F=s.i.width,H=N(degrees(-atan2(B,A)))-a;while(H>180)H-=360;while(H<=-180)H+=360;if(abs(H)>45)return;float I=min(abs(E*s.s/(G(H)*C)),1000),J=F*(I/D);int K=int(V/2-T(H)*E-J/2);int O=min((int)J,V-K),P=min((int)I,k/2);PImage L=createImage(O,P,ARGB);L.copy(s.i,(int)max(0,(.5-(V/2)/J)*F),(int)max(0,(.5-(k/4)/I)*D),(int)min(F,(.5+(V/2)/J)*F)-(int)max(0,(.5-(V/2)/J)*F),(int)min(D,(.5+(k/4)/I)*D)-(int)max(0,(.5-(k/4)/I)*D),0,0,O,P);int[]Z=new int[O*P];int X=0;if(K<0)X=-K;for(;X<O;X++){if(C<Q[X+K]){for(int y=0;y<P;y++){Z[y*O+X]=(int)alpha(L.pixels[y*O+X]);}}}L.mask(Z);image(L,K,M-P/2);}}