10-09-2017, 12:57 AM
(This post was last modified: 10-09-2017, 01:08 AM by Caveman.
Edit Reason: Improved version of code.
)
I would like to know if there is option for hiding walltext(spoiler or smth).
I had the same idea about bots working simultaneously :]
I had troubles with arrays, I went somewhere outside of array, so I decided to rewrite code using lists. It looks simplier.
The idea of this list is to:
store point of position taken,
store next item (null for last element),
and share between bots first item of list (which leads to store whole list) via private static variable (named first);
Then we take position of item, reserve it, do job on it, and free it.
It's extremely error unsafe. One bot can't go to destination, program stops and he blocks item in a list forever, it's need to be restarted. Also somatimes bots want to "steal" eachother material (who will catch titanium produced by converter first - bot that converts it to power cell, or bot that produced it), or somatimes even cell from back(yeah!).
Functions for jobs need to be rewrited, I'll do that when I'll find inspiration and free time.
But when started almost at same time, it works for few "jobs" like it should.
That's my old code:
[edit] I made it work better, with some error handling:
I had the same idea about bots working simultaneously :]
I had troubles with arrays, I went somewhere outside of array, so I decided to rewrite code using lists. It looks simplier.
The idea of this list is to:
store point of position taken,
store next item (null for last element),
and share between bots first item of list (which leads to store whole list) via private static variable (named first);
Then we take position of item, reserve it, do job on it, and free it.
It's extremely error unsafe. One bot can't go to destination, program stops and he blocks item in a list forever, it's need to be restarted. Also somatimes bots want to "steal" eachother material (who will catch titanium produced by converter first - bot that converts it to power cell, or bot that produced it), or somatimes even cell from back(yeah!).
Functions for jobs need to be rewrited, I'll do that when I'll find inspiration and free time.
But when started almost at same time, it works for few "jobs" like it should.
That's my old code:
Code:
public class pointListElement{
//we use point non-achieveable in game for first element
point nanpoint=new point(nan,nan,nan);
//here we store all our public variables:
public point place;
public pointListElement next;
//constructor, function used when new object is created
public void pointListElement(){
this.place=nanpoint;
this.next=null;
}
//another constructor, with starting value
public void pointListElement(point dest){
this.place=dest;
this.next=null;
}
//we add items to end of list, so we "jump" to last element(by searching
//for null value recursively and then create new item of list attached to
//last item's "next".
synchronized public void add(point pointDest){
if(next!=null){
next.add(pointDest);
}else{
next=new pointListElement(pointDest);
}
}
//another recursively function, it returns false if point searched is different than value
//of last element, or true if trough jumping one element is equal.
public bool contains(point searched){
if(this.next==null&&searched!=this.place){
return false;
}
if(this.place==searched){
return true;
}
return this.next.contains(searched);
}
//yet another recursive function, it remove elements by skipping them in a list
//(didn't find option to remove from memory, i hope it's automatic :D)
synchronized public void remove(point removed,pointListElement previous){
if(!contains(removed)){ //just for lulz, didn't see it happen
message("not removed");
return;// false;
}
if(this.place==removed){
previous.next=this.next;
return;// true;
}else{
if(this.next!=null)/*return*/ this.next.remove(removed,this);
}
return;// false;
}
}
public class WorkingClass{
//function added for orders
void findEmptySpace(point here){
goto(space(here));
}
/*first element of list is static->whole list is accessible in different instances
of class*/
static private pointListElement first=null;
int dist;
bool taken;
point findObjectPosition(object robot,int ObjectType){
//it's a smart finding
//it finds only non-taken positions
object item;
if(first==null){
first=new pointListElement(); //it must be in first function that use it
}
dist=0; //minimum starting radar
while(true){
/*
we search for elements by increasing minimum radar range
*/
item=radar(ObjectType,0,360,dist,1000);
if(item==null){
dist=0; //if item not found decrease minimal range to 0 and start again
wait(1); //here it should wait for it's own point
continue;
}else{
//here we check if position is already taken
taken=first.contains(item.position);
//if it's not, then reserve it in last position
if(!(taken)){
first.add(item.position);
return item.position;
}else{
//if taken, increase minimum detection range
dist+=2;
}
}
}
//must be for no error
return robot.position;
}
//object types(categories) are just ints, and they can be threated like that
//for example, mathematically, PowerStation=7(not sure about exact value, but it shows
//the idea
public void workAt(object robot,int work,int ObjectType){
//we get our destination and reserve point at same time
point destination = findObjectPosition(robot,ObjectType);
//turn(direction(radar(ObjectType).position));
switch(work){
case 1:
goto(destination);
grab();
break;
case 2:
goto(destination);
drop();
move(-2.5);
break;
case 3:
goto(destination);
sniff();
break;
case 4:
goto(destination);
findEmptySpace(robot.position);
drop();
break;
default:message("WRONG WORK TYPE");
}
//after job is done, remove point from list
first.remove(destination,first);
}
//this is overloaded version of previous function
//it has additional parameter, waitingFor, which is used for example when want to wait
//for titanium at Converter
public void workAt(
object robot,
int work,
int ObjectType,
int waitingFor)
{
point destination = findObjectPosition(robot,ObjectType);
//turn(direction(radar(ObjectType).position));
switch(work){
case 1:
goto(destination);
if(waitingFor==PowerCell){
wait(20);
}else{
while(radar(waitingFor,0,360,0,5)==null){
wait(1);
}
goto(radar(waitingFor,0,360,0,5).position);
}
grab();
break;
case 2:
goto(destination);
drop();
move(-2.5);
break;
case 3:
goto(destination);
sniff();
break;
case 4:
findEmptySpace(robot.position);
drop();
break;
default:message("WRONG WORK TYPE");
}
first.remove(destination,first);
}
//both functions are really crap, they have to be rewritten in more specific tasks
//and here we use the same idea for refueling
public void refuel(object robot,float treshold){
//int refuelers[]={PowerStation,PowerCaptor};
if(robot.energyCell.energyLevel<treshold){
point destination=findObjectPosition(robot,PowerStation);
goto(destination);
while(robot.energyCell.energyLevel<1){
wait(1);
}
first.remove(destination,first);
}
}
}
extern void object::Work()
{
WorkingClass workfield();
while(true){
workfield.workAt(this,1,TitaniumOre); //go to nearest free TitaniumOre, grab it
workfield.workAt(this,2,Converter); //go to nearest free Converter, drop item
workfield.workAt(this,1,Converter,Titanium); //at converter wait for titanium,
//and grab it
workfield.workAt(this,4,BotFactory);//leave at free space near free BotFactory
workfield.refuel(this,0.4); //:>
}
}
[edit] I made it work better, with some error handling:
Code:
public class pointListElement{
//we use point non-achieveable in game for first element
point nanpoint=new point(nan,nan,nan);
//here we store all our public variables:
public point place;
public pointListElement next;
//constructor, function used when new object is created
public void pointListElement(){
this.place=nanpoint;
this.next=null;
}
//another constructor, with starting value
public void pointListElement(point dest){
this.place=dest;
this.next=null;
}
//we add items to end of list, so we "jump" to last element(by searching
//for null value recursively) and then create new item of list attached to
//last item's "next".
synchronized public void add(point pointDest){
if(next!=null){
next.add(pointDest);
}else{
next=new pointListElement(pointDest);
}
}
//another recursively function, it returns false if point searched is different than value
//of last element, or true if trough jumping one element is equal.
public bool contains(point searched){
if(this.next==null&&distance(searched,this.place)>2){
return false;
}
if(distance(this.place,searched)<=2){
return true;
}
return this.next.contains(searched);
}
//yet another recursive function, it remove elements by skipping them in a list
//(didn't find option to remove from memory, i hope it's automatic :D)
synchronized public void remove(point removed,pointListElement previous){
if(!contains(removed)){ //just for lulz, didn't see it happen
message("not removed");
return;// false;
}
if(this.place==removed){
previous.next=this.next;
return;// true;
}else{
if(this.next!=null)/*return*/ this.next.remove(removed,this);
}
return;// false;
}
}
public class WorkingClass{
/*first element of list is static->whole list is accessible in different instances
of class*/
static private pointListElement first=null;
bool taken;
point findObjectPosition(object robot,int ObjectType){
//it's a smart finding
//it finds only non-taken positions
object item[];
if(first==null){
first=new pointListElement(); //it must be in first function that use it
}
while(true){
item=radarall(ObjectType,0,360,0,1000);
if(item==null){
wait(1); //here it should wait for it's own point
continue;
}else{
for(int i=0;i<sizeof(item);++i){
//here we check if position is already taken
taken=first.contains(item[i].position);
//if it's not, then reserve it in last position
if(!(taken)){
first.add(item[i].position);
return item[i].position;
}else{
}
}
wait(1);
}
}
//must be for no error
return robot.position;
}
point findObjectPosition(object robot,int[] ObjectType){
//it's a smart finding
//it finds only non-taken positions
object item[];
if(first==null){
first=new pointListElement(); //it must be in first function that use it
}
while(true){
item=radarall(ObjectType,0,360,0,1000);
if(item==null){
wait(1); //here it should wait for it's own point
continue;
}else{
for(int i=0;i<sizeof(item);++i){
//here we check if position is already taken
taken=first.contains(item[i].position);
//if it's not, then reserve it in last position
if(!(taken)){
first.add(item[i].position);
return item[i].position;
}else{
}
}
wait(1);
}
}
//must be for no error
return robot.position;
}
point findEmptySpaceNearObjectPosition(object robot,int ObjectType){
//it's a smart finding
//it finds only non-taken positions
object item[];
if(first==null){
first=new pointListElement(); //it must be in first function that use it
}
point emptySpace;
while(true){
item=radarall(ObjectType,0,360,0,1000);
if(item==null){
wait(1); //here it should wait for it's own point
continue;
}else{
for(int i=0;i<sizeof(item);++i){
int j=0;
taken=true;
while(taken&&j<100){
//here we check if position is already taken
emptySpace=space(
item[i].position,16+j,100+j*2,4
);
taken=first.contains(emptySpace);
++j;
}
//if it's not, then reserve it in last position
if(!(taken)){
first.add(emptySpace);
return emptySpace;
}else{
}
}
wait(1);
}
}
//must be for no error
return robot.position;
}
//object types(categories) are just ints, and they can be threated like that
//for example, mathematically, PowerStation=7(not sure about exact value, but it //shows the idea)
public void findAndTake(object robot,int ObjectType){
errmode(0);
while(true){
point destination = findObjectPosition(robot,ObjectType);
//point errdestination;
while(goto(destination)!=0){
//we want another destination in case of error
//errdestination=destination;
//destination = findObjectPosition(robot,ObjectType);
//first.remove(errdestination,first);
}
first.remove(destination,first);
if(grab()!=0){
continue;//in case of this error we repeat whole process
}
errmode(1);
return;
}
errmode(1);
}
public void process(object robot,int processor,int ObjectType){
point destination = findObjectPosition(robot,processor);
//point errdestination;
errmode(0);
while(goto(destination)!=0){
//errdestination=destination;
//destination=findObjectPosition(robot,processor);
//first.remove(errdestination,first);
}
while(drop()!=0){
point start=robot.position;
if(radar(ObjectType,0,45,0,5)!=null){
drop(Behind);
grab();
dropAtEmptySpace(robot,processor);
goto(start);
grab(Behind);
continue;
}else{
move(-6);
wait(5);
goto(start);
}
}
move(-2.5);
switch(ObjectType){
case PowerCell:
wait(17);
move(1);
break;
case NuclearCell:
wait(35);
move(1);
break;
default:
while(radar(ObjectType,0,90,0,5)==null){
wait(1);
}
break;
}
grab();
first.remove(destination,first);
errmode(1);
}
//we want to drop at empty space near object
public void dropAtEmptySpace(object robot,int ObjectType){
point destination = findEmptySpaceNearObjectPosition(robot,ObjectType);
errmode(0);
/*
while(goto(space(destination,0,100,4))!=0){
wait(1);
}*/
while(goto(destination)!=0){
wait(1);
}
while(drop()!=0){
message("Place Taken");
wait(10);
}
first.remove(destination,first);
errmode(1);
}
//and here we use the same idea for refueling
public void refuel(object robot,float treshold){
int refuelers[]={PowerStation,PowerCaptor};
if(robot.energyCell.category==PowerCell){
if(robot.energyCell.energyLevel<treshold){
errmode(0);
point destination=findObjectPosition(robot,refuelers);
//point errdestination;
while(goto(destination)!=0){
//errdestination=destination;
//destination=findObjectPosition(robot,refuelers);
//first.remove(errdestination,first);
}
while(robot.energyCell.energyLevel<1){
wait(1);
}
move(-3);
first.remove(destination,first);
errmode(1);
}
}else{
if(robot.energyCell.energyLevel<treshold){
goto(space(radar(NuclearPlant).position,20,100));
while(robot.energyCell.energyLevel<1){
wait(1);
}
}
}
}
}
public void object::workTitanium(){
//this is a public function, that can be used on produced bots
errmode(0);
move(-5);
errmode(1);
WorkingClass workfield();
while(true){
workfield.findAndTake(this,TitaniumOre);
workfield.process(this,Converter,Titanium);
workfield.dropAtEmptySpace(this,Converter);
if(energyCell.category==PowerCell){
workfield.refuel(this,0.4);
}else{
workfield.refuel(this,0.1);
}
}
}
extern void object::Work()
{
workTitanium();
}