Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Several mining bots working simultaneously
#4
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:

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();
}


Messages In This Thread
RE: Several mining bots working simultaneously - by Caveman - 10-09-2017, 12:57 AM

Forum Jump:


Users browsing this thread: 4 Guest(s)