// // worm_class.pde // // // Created by Karin Gauch and Fabien Schwartz on 10.06.07. // Copyright 2007 Karin Gauch and Fabien Schwartz. All rights reserved. // class worm { int wormLength = 0; int[] pixelLocation = new int[maxWormLength]; color[] pixelColor = new color[maxWormLength]; int age = 0; int appetite = 0; // constructor worm(int startPoint, color startColor) { pixelLocation[0] = startPoint; pixelColor[0] = startColor; } // go method void go(int repeat) { int nextPixel; for(int i=0;i= maxWormLength-1 && reproduction) splitWorm(maxWormLength-1); nextPixel=selectNext(); if(nextPixel>=0) if(eatable(nextPixel)) { push(nextPixel,img[activeImg].pixels[nextPixel]); // pixel eatable appetite = 0; } else { push(nextPixel); // pixel not eateble appetite++; } } draw(); } // method to select the pixelloacation for the new head int selectNext() { float ran,influence = 0; int r; int a; int bestPixel = -1; int counter = 0; int counter2 = 0; float x,y; boolean crossAllow = false; int[] log = new int[4]; int templ; while(log[3]==0) { influence = 0; ran = random(4); if(ai && !come) { bestPixel = selectBest(pixelLocation[0],pixelColor[0]); if(bestPixel >= 0) { if(ran>3 && bestPixel%img[activeImg].width < pixelLocation[0]%img[activeImg].width) influence = -1; if(ran<3 && ran >2 && bestPixel%img[activeImg].width>pixelLocation[0]%img[activeImg].width) influence = +1; if(ran<2 && ran>1 && bestPixel/img[activeImg].widthpixelLocation[0]/img[activeImg].width) // runterdrŸcken influence = +1; } } if(come) { if(ran>3 && mouseX2 && mouseX>pixelLocation[0]%img[activeImg].width) influence = +(1-pow((1-(mouseX-(float)pixelLocation[0]%img[activeImg].width)/img[activeImg].width),3)); if(ran<2 && ran>1 && mouseYpixelLocation[0]/img[activeImg].width) // runterdrŸcken influence = +(1-pow((1-(mouseY-(float)pixelLocation[0]/img[activeImg].width)/height),3)); } r = int(ran+influence); // 0 for up; 1 for down; 2 for left; 3 for right if(r==0 && pixelLocation[0]-img[activeImg].width >= 0 && (!search(pixelLocation,pixelLocation[0]-img[activeImg].width) || crossAllow)) { // up return pixelLocation[0]-img[activeImg].width; } if(r==1 && pixelLocation[0]+img[activeImg].width < img[activeImg].width*height && (!search(pixelLocation,pixelLocation[0]+img[activeImg].width) || crossAllow)) { // down return pixelLocation[0]+img[activeImg].width; } if(r==2 && pixelLocation[0]-1 >0 && pixelLocation[0]%img[activeImg].width > (pixelLocation[0]-1)%img[activeImg].width && (!search(pixelLocation,pixelLocation[0]-1) || crossAllow)) { // left return pixelLocation[0]-1; } if(r==3 && pixelLocation[0]+1 < img[activeImg].width*height && pixelLocation[0]%img[activeImg].width < (pixelLocation[0]+1)%img[activeImg].width && (!search(pixelLocation,pixelLocation[0]+1) || crossAllow)) { // right return pixelLocation[0]+1; } if(search(log,r+1)==false){ log[counter] = r+1; } counter2++; if(counter2>20) { crossAllow = true; } } return -1; } // method to select a good pixel int selectBest(int pixel, color col) { int influenceArea = 100; int bestPixel = -1; int bestDifference = 10000; int difference; int x, y; int precision = 5; for(int i=0; i < precision; i++) { x = (int)random(influenceArea); y = (int)random(influenceArea); if( abs(pixel%img[activeImg].width - (pixel+img[activeImg].width*(y-influenceArea/2)+x-influenceArea/2)%img[activeImg].width) < influenceArea && pixel+img[activeImg].width*(y-influenceArea/2)+x-influenceArea/2 >= 0 && pixel+img[activeImg].width*(y-influenceArea/2)+x-influenceArea/2 < sq(img[activeImg].width)) { difference = (int)abs(red(img[activeImg].pixels[pixel+img[activeImg].width*(y-influenceArea/2)+x-influenceArea/2]) - red(col)) + (int)abs(green(img[activeImg].pixels[pixel+img[activeImg].width*(y-influenceArea/2)+x-influenceArea/2]) - green(col)) + (int)abs(blue(img[activeImg].pixels[pixel+img[activeImg].width*(y-influenceArea/2)+x-influenceArea/2]) - blue(col)); if(difference < bestDifference || (difference == bestDifference && random(2) > 1)) { bestPixel = pixel+img[activeImg].width*(y-influenceArea/2)+x-influenceArea/2; bestDifference = difference; } } } if(bestPixel >= 0 && img[activeImg].pixels[bestPixel] != color(0) && img[activeImg].pixels[bestPixel] != color(255)) return bestPixel; else return -1; } // method to moove the worm void push(int a) { for(int i=wormLength-1; i>0; i--) { pixelLocation[i]=pixelLocation[i-1]; } pixelLocation[0] = a; } // method to insert a new head in front and move the worm void push(int a, color c) { for(int i=wormLength-1; i>0; i--) { pixelLocation[i]=pixelLocation[i-1]; pixelColor[i]=pixelColor[i-1]; } pixelLocation[0] = a; pixelColor[0] = c; img[activeImg].pixels[pixelLocation[0]] = backgroundColor[activeImg]; pixelsEaten++; if(wormLength0) { c = color(red(pixelColor[i])-30,green(pixelColor[i])-30,blue(pixelColor[i])-30); pixels[pixelLocation[i]-1+(pixelLocation[i]/img[activeImg].width)*menuWidth]=c; pixels[pixelLocation[i]-1-width+(pixelLocation[i]/img[activeImg].width)*menuWidth]=c; pixels[pixelLocation[i]-1+width+(pixelLocation[i]/img[activeImg].width)*menuWidth]=c; pixels[pixelLocation[i]-width+(pixelLocation[i]/img[activeImg].width)*menuWidth]=c; pixels[pixelLocation[i]+width+(pixelLocation[i]/img[activeImg].width)*menuWidth]=c; pixels[pixelLocation[i]+1+(pixelLocation[i]/img[activeImg].width)*menuWidth]=c; pixels[pixelLocation[i]+1-width+(pixelLocation[i]/img[activeImg].width)*menuWidth]=c; pixels[pixelLocation[i]+1+width+(pixelLocation[i]/img[activeImg].width)*menuWidth]=c; } } } for(int i=0; i red(pixelColor[0]) && red(img[activeImg].pixels[pixel])-colorRange < red(pixelColor[0]) && green(img[activeImg].pixels[pixel])+colorRange > green(pixelColor[0]) && green(img[activeImg].pixels[pixel])-colorRange < green(pixelColor[0]) && blue(img[activeImg].pixels[pixel])+colorRange > blue(pixelColor[0]) && blue(img[activeImg].pixels[pixel])-colorRange < blue(pixelColor[0]) && color(img[activeImg].pixels[pixel]) != backgroundColor[activeImg]) return true; else return false; } // method to split a worm for reproduction void splitWorm(int splitLength) { worm tmp = new worm(pixelLocation[splitLength], pixelColor[splitLength]); for(int i = 1; i < splitLength /2; i++) tmp.push(pixelLocation[splitLength - i ], pixelColor[splitLength - i]); population.add(tmp); pixelsEaten -= splitLength /2 - 1; wormLength = splitLength / 2; } }