//------------------ Main Class -------------------//
import java.awt.*;
import java.applet.*;
import java.io.*;
import java.lang.String;
import java.util.Random;
import java.util.Date;
public class myPoint
{
int h,v;
}
public class myPieceType
{
myPoint loc[];
int halfindex[][];
boolean up[],full[];
public myPieceType()
{
int i;
loc=new myPoint[12]; for(i=0;i<12;i++) loc[i]=new myPoint();
halfindex=new int[12][2];
up=new boolean[12];
full=new boolean[12];
}
}
public class myPieceTypeClass
{
myPieceType mytype[];
int totalnum,num0,num1;
public myPieceTypeClass()
{
int i;
mytype=new myPieceType[6]; for(i=0;i<6;i++) mytype[i]=new myPieceType();
}
}
public class myHistory
{
int ID;
boolean up;
}
public class Eternity extends Applet implements Runnable
{
int WIDTH,HEIGHT,CellSize,Width,Height,offW,offH,SS[],SS2[],PP[],badP[],gNum;
Graphics g2,off_g;
Random nrand;
Image offscreen;
myCell gCell[];
myPiece gPiece[];
Color gColor[];
myPieceTypeClass gPieceType[];
myCellUtility cellU;
myTypeUtility typeU;
myHistory history[];
boolean MOVE=false;
Thread runner;
int oldID,badcounter=0,badNum=0,badcounter2=0,badhisID2,count=0,count2=0;
boolean existbad=false,existbad2=false;
public void start()
{
if (runner == null)
{
runner= new Thread(this);
runner.start();
}
}
public void stop()
{
if (runner!=null)
{
runner.stop();
runner=null;
}
}
public void run() //----------------------------------------//
{
// init();
while (true) {
try { Thread.sleep(10); } catch (InterruptedException e){};
if ( isVisible() ) {
DomyRun();
// paint(g2);
}
}
}
public int randomise(Random nrand,int range)
{
if(range==0) return 0;
return( java.lang.Math.abs(nrand.nextInt()) % range);
}
public void init()
{
int i;
mySetUpPiece0 piece0;
mySetUpPiece1 piece1;
mySetUpPiece2 piece2;
mySetUpPiece3 piece3;
mySetUpPiece4 piece4;
mySetUpPiece5 piece5;
mySetUpPiece6 piece6;
mySetUpPiece7 piece7;
mySetUpPiece8 piece8;
mySetUpPiece9 piece9;
mySetUpPiece10 piece10;
mySetUpPiece11 piece11;
mySetUpPiece12 piece12;
mySetUpPiece13 piece13;
mySetUpPiece14 piece14;
mySetUpPiece15 piece15;
mySetUpPiece16 piece16;
mySetUpPiece17 piece17;
mySetUpPiece18 piece18;
mySetUpPiece19 piece19;
mySetUpPiece20 piece20;
Date d=new Date();
nrand=new Random(d.getTime());
WIDTH=this.size().width;
HEIGHT=this.size().height;
offW=WIDTH;
offH=HEIGHT-30;
offscreen = this.createImage(offW, offH);
off_g = offscreen.getGraphics();
off_g.setColor(Color.black);
off_g.fillRect(0,0,offW,offH);
g2=this.getGraphics();
g2.setColor(Color.black);
g2.fillRect(0,0,WIDTH,HEIGHT);
//--------------------------------//
this.setLayout(new FlowLayout(FlowLayout.LEFT));
add(new Button("Run"));
add(new Button("Stop"));
cellU=new myCellUtility();
typeU=new myTypeUtility();
gPiece=new myPiece[209];
for(i=0;i<209;i++){
gPiece[i]=new myPiece();
gPiece[i].DoInit(i);
}
DoInitSet();
SS=new int[209];
SS2=new int[209];
PP=new int[209];
badP=new int[209];
history=new myHistory[100]; for(i=0;i<100;i++) history[i]=new myHistory();
//---------------------------//
gColor=new Color[209];
for(i=0;i<209;i++){
float f0,f1,f2;
int n0;
f0=(float)i*0.0047f;
n0=(i*5) % 209; f1=(float)n0*0.0047f;
n0=(i*9) % 209; f2=(float)n0*0.0035f + 0.25f;
gColor[i]=new Color(Color.HSBtoRGB(f0,f1,f2));
}
//----------------------------//
piece0 =new mySetUpPiece0();
piece1 =new mySetUpPiece1();
piece2 =new mySetUpPiece2();
piece3 =new mySetUpPiece3();
piece4 =new mySetUpPiece4();
piece5 =new mySetUpPiece5();
piece6 =new mySetUpPiece6();
piece7 =new mySetUpPiece7();
piece8 =new mySetUpPiece8();
piece9 =new mySetUpPiece9();
piece10=new mySetUpPiece10();
piece11=new mySetUpPiece11();
piece12=new mySetUpPiece12();
piece13=new mySetUpPiece13();
piece14=new mySetUpPiece14();
piece15=new mySetUpPiece15();
piece16=new mySetUpPiece16();
piece17=new mySetUpPiece17();
piece18=new mySetUpPiece18();
piece19=new mySetUpPiece19();
piece20=new mySetUpPiece20();
gPieceType=new myPieceTypeClass[209];
for(i=0;i<209;i++) gPieceType[i]=new myPieceTypeClass();
piece0.TP_DoSetUpEternityPiece0(gPieceType);
piece1.TP_DoSetUpEternityPiece1(gPieceType);
piece2.TP_DoSetUpEternityPiece2(gPieceType);
piece3.TP_DoSetUpEternityPiece3(gPieceType);
piece4.TP_DoSetUpEternityPiece4(gPieceType);
piece5.TP_DoSetUpEternityPiece5(gPieceType);
piece6.TP_DoSetUpEternityPiece6(gPieceType);
piece7.TP_DoSetUpEternityPiece7(gPieceType);
piece8.TP_DoSetUpEternityPiece8(gPieceType);
piece9.TP_DoSetUpEternityPiece9(gPieceType);
piece10.TP_DoSetUpEternityPiece10(gPieceType);
piece11.TP_DoSetUpEternityPiece11(gPieceType);
piece12.TP_DoSetUpEternityPiece12(gPieceType);
piece13.TP_DoSetUpEternityPiece13(gPieceType);
piece14.TP_DoSetUpEternityPiece14(gPieceType);
piece15.TP_DoSetUpEternityPiece15(gPieceType);
piece16.TP_DoSetUpEternityPiece16(gPieceType);
piece17.TP_DoSetUpEternityPiece17(gPieceType);
piece18.TP_DoSetUpEternityPiece18(gPieceType);
piece19.TP_DoSetUpEternityPiece19(gPieceType);
piece20.TP_DoSetUpEternityPiece20(gPieceType);
{ myPieceType type=new myPieceType();
for(i=0;i<209;i++){
typeU.TP_DomyCopyType(gPieceType[i].mytype[0],type);
typeU.doAddThisType(type,i,gPieceType);
}
}
}
public void paint(Graphics G)
{
G.drawImage(offscreen, 0, 30,Color.black,this);
}
private void DoReDrawOff()
{
int i;
off_g.setColor(Color.black);
off_g.fillRect(0,0,offW,offH);
off_g.setColor(Color.white);
for(i=0;i<1278;i++) gCell[i].DoDrawFrame(off_g,0);
g2.drawImage(offscreen, 0, 30,Color.black,this);
}
public boolean action(Event evt,Object arg)
{
if(evt.target instanceof Button) {
if(((String)arg).equals("Run")) DoMakeNewSet();
else if(((String)arg).equals("Stop")) MOVE=false;
}
return true;
}
//---------------------- Init --------------------------//
private void DoInitSet()
{
int i,j;
myPoint p0=new myPoint(),p1=new myPoint();
boolean up0,up1;
gCell=new myCell[1278];
for(i=0;i<1278;i++) {
gCell[i]=new myCell();
gCell[i].DoInit();
}
for(i=0;i<19;i++) gCell[i].DoSetLoc(i,0);
for(i=0;i<25;i++) gCell[i+19].DoSetLoc(i,1);
for(i=0;i<31;i++) gCell[i+44].DoSetLoc(i,2);
for(i=0;i<37;i++) gCell[i+75].DoSetLoc(i,3);
for(i=0;i<39;i++) gCell[i+112].DoSetLoc(i,4);
for(i=0;i<41;i++) gCell[i+151].DoSetLoc(i,5);
for(i=0;i<43;i++) gCell[i+192].DoSetLoc(i,6);
for(i=0;i<45;i++) gCell[i+235].DoSetLoc(i,7);
for(i=0;i<47;i++) gCell[i+280].DoSetLoc(i,8);
for(i=0;i<49;i++) gCell[i+327].DoSetLoc(i,9);
for(i=0;i<51;i++) gCell[i+376].DoSetLoc(i,10);
for(i=0;i<53;i++) gCell[i+427].DoSetLoc(i,11);
for(i=0;i<53;i++) gCell[i+480].DoSetLoc(i,12);
for(i=0;i<53;i++) gCell[i+533].DoSetLoc(i,13);
for(i=0;i<53;i++) gCell[i+586].DoSetLoc(i,14);
for(i=0;i<53;i++) gCell[i+639].DoSetLoc(i,15);
for(i=0;i<53;i++) gCell[i+692].DoSetLoc(i,16);
for(i=0;i<53;i++) gCell[i+745].DoSetLoc(i,17);
for(i=0;i<53;i++) gCell[i+798].DoSetLoc(i,18);
for(i=0;i<51;i++) gCell[i+851].DoSetLoc(i,19);
for(i=0;i<49;i++) gCell[i+902].DoSetLoc(i,20);
for(i=0;i<47;i++) gCell[i+951].DoSetLoc(i,21);
for(i=0;i<45;i++) gCell[i+998].DoSetLoc(i,22);
for(i=0;i<43;i++) gCell[i+1043].DoSetLoc(i,23);
for(i=0;i<41;i++) gCell[i+1086].DoSetLoc(i,24);
for(i=0;i<39;i++) gCell[i+1127].DoSetLoc(i,25);
for(i=0;i<37;i++) gCell[i+1166].DoSetLoc(i,26);
for(i=0;i<31;i++) gCell[i+1203].DoSetLoc(i,27);
for(i=0;i<25;i++) gCell[i+1234].DoSetLoc(i,28);
for(i=0;i<19;i++) gCell[i+1259].DoSetLoc(i,29);
for(i=0;i<1278;i++) gCell[i].DoSetupUpDown();
for(i=0;i<1277;i++){
for(j=i+1;j<1278;j++){
gCell[i].DoGetLoc(p0);
gCell[j].DoGetLoc(p1);
up0=gCell[i].DoGetUP();
up1=gCell[j].DoGetUP();
if(DoCheckNearCell(p0,p1,up0,up1)) doAddEach(i,j);
}
}
for(i=0;i<1278;i++) gCell[i].DoSetUpmyLoc(gCell);
for(i=0;i<1278;i++) gCell[i].DoSetEdge();
}
private boolean DoCheckNearCell(myPoint P0,myPoint P1,boolean up0,boolean up1)
{
int s0,s1;
s0=myabs(P0.v - P1.v); if(s0>1) return false;
if(s0==0) {
s1=myabs(P0.h - P1.h);
if(s1==1) return true;
else return false;
}
s0= cellU.DoGetCellDistW(P0);
s1= cellU.DoGetCellDistW(P1);
if(s0!=s1) return false;
if(P0.v < P1.v) { if(up0 && !up1) return true;}
else { if(!up0 && up1) return true;}
return false;
}
private void doAddEach(int ID0,int ID1)
{
int i,id0=-1,id1=-1;
for(i=0;i<3;i++){
if(!gCell[ID0].DoGetOpen(i)) { id0=i; break;}
}
if(id0==-1) return;
for(i=0;i<3;i++){
if(!gCell[ID1].DoGetOpen(i)) { id1=i; break;}
}
if(id1==-1) return;
gCell[ID0].DoSetDoorNBID(id0,0,ID1); //doorNB[id0][0]=ID1;
gCell[ID0].DoSetDoorNBID(id0,1,id1); // doorNB[id0][1]=id1;
gCell[ID0].DoSetOpen(id0,true); // open[id0]=true;
gCell[ID1].DoSetDoorNBID(id1,0,ID0); // doorNB[id1][0]=ID0;
gCell[ID1].DoSetDoorNBID(id1,1,id0); // doorNB[id1][1]=id0;
gCell[ID1].DoSetOpen(id1,true); // open[id1]=true;
}
private int myabs(int s0)
{
if(s0<0) return -s0;
else return s0;
}
//--------------------------------------------------//
private void DoMakeNewSet()
{
int i;
for(i=0;i<1278;i++) gCell[i].DoResetPieceID();
for(i=0;i<209;i++) gPiece[i].DoSetExist(false);
DoReDrawOff();
MOVE=true;
gNum=0;
}
private void DomyRun()
{
int i,j,k;
boolean ok=false;
if(!MOVE) return;
if(gNum==0){//-------------------//
int id,s0=0;
for(i=0;i<1278;i++) gCell[i].DoResetPieceID();
for(i=0;i<209;i++) gPiece[i].DoSetExist(false);
ok=false;
while(true){
id=randomise(nrand,209);
if(gPiece[id].DoContactEdge(nrand,gPieceType,gCell,cellU,typeU)) { ok=true; break;}
s0++; if(s0>200) break;
}
if(!ok) return;
PP[0]=oldID=id;
gNum ++;
DoReDrawOff();
g2.setColor(gColor[id]);
gPiece[id].DoReDrawFrame(g2,gCell,30);
existbad=false; badNum=0; badcounter=0;
existbad2=false; badcounter2=0; for(k=0;k<100;k++) history[k].ID=-1;
count=0;
count2=0;
}//----------------------------//
domySort(SS2,SS);
ok=false;
for(i=0;i<209;i++){
int mynextcellid;
if(gPiece[SS[i]].DoGetExist()) continue;
mynextcellid=cellU.PC_DoGetNextEdgeCell(oldID,gCell,gPiece);
if(gPiece[SS[i]].DoContactNext(mynextcellid,nrand, gPieceType, gCell,cellU,typeU)) {
if(doCheckRepeat(SS[i])){
gPiece[SS[i]].DoResetExist(gCell);
continue;
}
ok=true;
PP[gNum]=SS[i]; gNum ++; oldID=SS[i];
if(existbad){//----------------//
badcounter ++;
if(badcounter>=2) existbad=false;
}//----------------------------//
if(existbad2){//----------------//
badcounter2 ++;
if(badcounter2>=3) existbad2=false; // 3
}//-----------------------------//
doaddHistory(SS[i],true);
// off_g.setColor(gColor[SS[i]]);
// gPiece[SS[i]].DoReDrawFrame(off_g,gCell,0);
g2.setColor(gColor[SS[i]]);
gPiece[SS[i]].DoReDrawFrame(g2,gCell,30);
// gPiece[ss[i]].DoReDrawFrame();
if(doCheckIfEndEdge()) {//-------------------//
MOVE=false;
return;
}//------------------------------------------//
}
if(gNum==0) break;
}
//---------------- not exist -----------------------//
if(!ok){
boolean doback=false;
gPiece[PP[gNum-1]].DoResetExist(gCell);
doEraseDraw(PP[gNum-1]); //
doaddHistory(PP[gNum-1],false);//
if(!existbad){//-----------------------//
existbad=true;
badcounter=0;
badNum=1;
badP[0]=PP[gNum-1];
}else {
for(k=0;k=2) gPiece[PP[gNum-2]].DoResetExist(gCell);
existbad=false;
}else {
badP[badNum]=PP[gNum-1];
badNum++;
}
badcounter --;
}//-----------------------------------//
if(!doback){//-------------------------//
if(gNum>=2) oldID=PP[gNum-2];
gNum --;
}else {
doaddHistory(PP[gNum-2],false);//////
doEraseDraw(PP[gNum-2]);
if(gNum>=3) oldID=PP[gNum-3];
gNum -=2;
if(existbad2) badcounter2 --; ///////////
}//----------------------------------//
//------------------------------------------------//
if(!existbad2){
if(history[0].ID!=-1 && history[1].ID!=-1 && history[2].ID!=-1){
if(!history[0].up && !history[1].up){
existbad2=true;
badcounter2=0;
badhisID2=history[0].ID;
}
}
}else {
badcounter2--;
if(badcounter2<0) existbad2=false;
else if(badcounter2==0){
if(badhisID2==history[0].ID){
existbad2=false;
gPiece[PP[gNum-1]].DoResetExist(gCell);//
doaddHistory(PP[gNum-1],false);//////
doEraseDraw(PP[gNum-1]);
if(gNum>=2) oldID=PP[gNum-2];
gNum --;
}
}
} //---------------------------------------//
}//------------------------------- not exist ----------------------------//
{ int s0;//------------------------//
s0=doGetRemainEdgeNum();
if(s0>=80) count ++;
if(count>100){ count=0; gNum=0; }
}//--------------------------------//
}
private void domySort(int ss[],int ss2[])
{
int i,j,num=209,s0;
for(i=0;i<209;i++) ss[i]=i;
for(i=0;i<209;i++){
s0=randomise(nrand,num);
ss2[i]=ss[s0];
for(j=s0;j=1;i--) {
history[i].ID=history[i-1].ID;
history[i].up=history[i-1].up;
}
history[0].ID=id;
history[0].up=up;
}
private boolean doCheckRepeat(int id)
{
int i,num=0;
if(history[0].up) return false;
for(i=0;i<100;i++){
if(history[i].ID==-1) continue;
if(history[i].ID==id){ num ++; if(num>=5) return true;}
}
return false;
}
private int doGetRemainEdgeNum()
{
int i,num=0;
for(i=0;i<1278;i++){
if(!gCell[i].DoGetIfEdge()) continue;
if(!gCell[i].DoCheckIfExistEmpty()) num++;
}
return num;
}
}