diff --git a/.gradle/7.4/executionHistory/executionHistory.lock b/.gradle/7.4/executionHistory/executionHistory.lock index eda81e1..1083b48 100644 Binary files a/.gradle/7.4/executionHistory/executionHistory.lock and b/.gradle/7.4/executionHistory/executionHistory.lock differ diff --git a/.gradle/7.4/fileHashes/fileHashes.lock b/.gradle/7.4/fileHashes/fileHashes.lock index 3b64297..58760a5 100644 Binary files a/.gradle/7.4/fileHashes/fileHashes.lock and b/.gradle/7.4/fileHashes/fileHashes.lock differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 0fa80a8..e229a47 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index f947510..a041905 100644 Binary files a/.gradle/file-system.probe and b/.gradle/file-system.probe differ diff --git a/airSeaRescue.mas2j b/airSeaRescue.mas2j index 35fcd3b..474727e 100644 --- a/airSeaRescue.mas2j +++ b/airSeaRescue.mas2j @@ -14,5 +14,11 @@ MAS airSeaRescue { environment: operator.WorldEnvironment(1,500,yes) - agents: victim#4; + agents: + victim#4; + searchDrone#2; + + operator; + + } diff --git a/miner.asl b/miner.asl new file mode 100644 index 0000000..747fa90 --- /dev/null +++ b/miner.asl @@ -0,0 +1,294 @@ +/* beliefs */ + +last_dir(null). // the last movement I did +free. + +/* rules */ + +// next line is the bottom of the quadrant +// if 2 lines bellow is too far +calc_new_y(AgY,QuadY2,QuadY2) :- AgY+2 > QuadY2. + +// otherwise, the next line is 2 lines bellow +calc_new_y(AgY,_,Y) :- Y = AgY+2. + + +/* plans for sending the initial position to leader */ + ++gsize(S,_,_) : true // S is the simulation Id + <- !send_init_pos(S). ++!send_init_pos(S) : pos(X,Y) + <- .send(leader,tell,init_pos(S,X,Y)). ++!send_init_pos(S) : not pos(_,_) // if I do not know my position yet + <- .wait("+pos(X,Y)", 500); // wait for it and try again + !!send_init_pos(S). + +/* plans for wandering in my quadrant when I'm free */ + ++free : last_checked(X,Y) <- !prep_around(X,Y). ++free : quadrant(X1,Y1,X2,Y2) <- !prep_around(X1,Y1). ++free : true <- !wait_for_quad. + +@pwfq[atomic] ++!wait_for_quad : free & quadrant(_,_,_,_) + <- -+free. ++!wait_for_quad : free + <- .wait("+quadrant(X1,Y1,X2,Y2)", 500); + !!wait_for_quad. ++!wait_for_quad : not free + <- .print("No longer free while waiting for quadrant."). +-!wait_for_quad // .wait might fail + <- !!wait_for_quad. + +// if I am around the upper-left corner, move to upper-right corner ++around(X1,Y1) : quadrant(X1,Y1,X2,Y2) & free + <- .print("in Q1 to ",X2,"x",Y1); + !prep_around(X2,Y1). + +// if I am around the bottom-right corner, move to upper-left corner ++around(X2,Y2) : quadrant(X1,Y1,X2,Y2) & free + <- .print("in Q4 to ",X1,"x",Y1); + !prep_around(X1,Y1). + +// if I am around the right side, move to left side two lines bellow ++around(X2,Y) : quadrant(X1,Y1,X2,Y2) & free + <- ?calc_new_y(Y,Y2,YF); + .print("in Q2 to ",X1,"x",YF); + !prep_around(X1,YF). + +// if I am around the left side, move to right side two lines bellow ++around(X1,Y) : quadrant(X1,Y1,X2,Y2) & free + <- ?calc_new_y(Y,Y2,YF); + .print("in Q3 to ", X2, "x", YF); + !prep_around(X2,YF). + +// last "around" was none of the above, go back to my quadrant ++around(X,Y) : quadrant(X1,Y1,X2,Y2) & free & Y <= Y2 & Y >= Y1 + <- .print("in no Q, going to X1"); + !prep_around(X1,Y). ++around(X,Y) : quadrant(X1,Y1,X2,Y2) & free & X <= X2 & X >= X1 + <- .print("in no Q, going to Y1"); + !prep_around(X,Y1). + ++around(X,Y) : quadrant(X1,Y1,X2,Y2) + <- .print("It should never happen!!!!!! - go home"); + !prep_around(X1,Y1). + ++!prep_around(X,Y) : free + <- -around(_,_); -last_dir(_); !around(X,Y). + ++!around(X,Y) + : // I am around to some location if I am near it or + // the last action was skip (meaning that there are no paths to there) + (pos(AgX,AgY) & jia.neighbour(AgX,AgY,X,Y)) | last_dir(skip) + <- +around(X,Y). ++!around(X,Y) : not around(X,Y) + <- !next_step(X,Y); + !!around(X,Y). ++!around(X,Y) : true + <- !!around(X,Y). + ++!next_step(X,Y) + : pos(AgX,AgY) + <- jia.get_direction(AgX, AgY, X, Y, D); + //.print("from ",AgX,"x",AgY," to ", X,"x",Y," -> ",D); + -+last_dir(D); + do(D). ++!next_step(X,Y) : not pos(_,_) // I still do not know my position + <- !next_step(X,Y). +-!next_step(X,Y) : true // failure handling -> start again! + <- .print("Failed next_step to ", X,"x",Y," fixing and trying again!"); + -+last_dir(null); + !next_step(X,Y). + + +/* Gold-searching Plans */ + +// I perceived unknown gold and I am free, handle it +@pcell[atomic] // atomic: so as not to handle another + // event until handle gold is initialised ++cell(X,Y,gold) + : not carrying_gold & free + <- -free; + +gold(X,Y); + .print("Gold perceived: ",gold(X,Y)); + !init_handle(gold(X,Y)). + +// if I see gold and I'm not free but also not carrying gold yet +// (I'm probably going towards one), abort handle(gold) and pick up +// this one which is nearer +@pcell2[atomic] ++cell(X,Y,gold) + : not carrying_gold & not free & + .desire(handle(gold(OldX,OldY))) & // I desire to handle another gold which + pos(AgX,AgY) & + operator.dist(X, Y, AgX,AgY,DNewG) & + operator.dist(OldX,OldY,AgX,AgY,DOldG) & + DNewG < DOldG // is farther than the one just perceived + <- +gold(X,Y); + .drop_desire(handle(gold(OldX,OldY))); + .print("Giving up current gold ",gold(OldX,OldY), + " to handle ",gold(X,Y)," which I am seeing!"); + .print("Announcing ",gold(OldX,OldY)," to others"); + .broadcast(tell,gold(OldX,OldY)); + .broadcast(untell, committed_to(gold(OldX,OldY))); + !init_handle(gold(X,Y)). + +// I am not free, just add gold belief and announce to others ++cell(X,Y,gold) + : not gold(X,Y) & not committed_to(gold(X,Y)) + <- +gold(X,Y); + .print("Announcing ",gold(X,Y)," to others"); + .broadcast(tell,gold(X,Y)). + +// someone else sent me a gold location ++gold(X1,Y1)[source(A)] + : A \== self & + not allocated(gold(X1,Y1),_) & // The gold was not allocated yet + not carrying_gold & // I am not carrying gold + free & // and I am free + pos(X2,Y2) & + .my_name(Me) + <- operator.dist(X1,Y1,X2,Y2,D); // bid + .send(leader,tell,bid(gold(X1,Y1),D,Me)). + +// bid high as I'm not free ++gold(X1,Y1)[source(A)] + : A \== self & .my_name(Me) + <- .send(leader,tell,bid(gold(X1,Y1),10000,Me)). + +// gold allocated to me +@palloc1[atomic] ++allocated(Gold,Ag)[source(leader)] + : .my_name(Ag) & free // I am still free + <- -free; + .print("Gold ",Gold," allocated to ",Ag); + !init_handle(Gold). + +// some gold was allocated to me, but I can not +// handle it anymore, re-announce +@palloc2[atomic] ++allocated(Gold,Ag)[source(leader)] + : .my_name(Ag) & not free // I am no longer free + <- .print("I can not handle ",Gold," anymore!"); + .print("(Re)announcing ",Gold," to others"); + .broadcast(tell,Gold). + + +// someone else picked up the gold I am going to go, +// so drops the intention and chose another gold +@ppgd[atomic] ++picked(G)[source(A)] + : .desire(handle(G)) | .desire(init_handle(G)) + <- .print(A," has taken ",G," that I am pursuing! Dropping my intention."); + .abolish(G); + .drop_desire(handle(G)); + !!choose_gold. + +// someone else picked up a gold I know about, +// remove from my belief base ++picked(gold(X,Y)) + <- -gold(X,Y)[source(_)]. + + +@pih1[atomic] ++!init_handle(Gold) + : .desire(around(_,_)) + <- .print("Dropping around(_,_) desires and intentions to handle ",Gold); + .drop_desire(around(_,_)); + !init_handle(Gold). +@pih2[atomic] ++!init_handle(Gold) + : pos(X,Y) + <- .print("Going for ",Gold); + -+last_checked(X,Y); + !!handle(Gold). // must use !! to perform "handle" as not atomic + ++!handle(gold(X,Y)) + : not free + <- .print("Handling ",gold(X,Y)," now."); + .broadcast(tell, committed_to(gold(X,Y))); + !pos(X,Y); + !ensure(pick,gold(X,Y)); + // broadcast that I got the gold(X,Y), to avoid someone + // else to pursue this gold + .broadcast(tell,picked(gold(X,Y))); + ?depot(_,DX,DY); + !pos(DX,DY); + !ensure(drop, 0); + -gold(X,Y)[source(_)]; + .print("Finish handling ",gold(X,Y)); + !!choose_gold. + +// if ensure(pick/drop) failed, pursue another gold +-!handle(G) : G + <- .print("failed to catch gold ",G); + .abolish(G); // ignore source + !!choose_gold. +-!handle(G) : true + <- .print("failed to handle ",G,", it isn't in the BB anyway"); + !!choose_gold. + +// no known gold to choose from +// become free again to search for gold ++!choose_gold + : not gold(_,_) + <- -+free. + +// Finished one gold, but others left +// find the closest gold among the known options, +// that nobody else committed to ++!choose_gold + : gold(_,_) + <- .findall(gold(X,Y),gold(X,Y),LG); + !calc_gold_distance(LG,LD); + .length(LD,LLD); LLD > 0; + .print("Uncommitted gold distances: ",LD,LLD); + .min(LD,d(_,NewG)); + .print("Next gold is ",NewG); + !!handle(NewG). +-!choose_gold <- -+free. + ++!calc_gold_distance([],[]). ++!calc_gold_distance([gold(GX,GY)|R],[d(D,gold(GX,GY))|RD]) + : pos(IX,IY) & not committed_to(gold(GX,GY)) + <- operator.dist(IX,IY,GX,GY,D); + !calc_gold_distance(R,RD). ++!calc_gold_distance([_|R],RD) + <- !calc_gold_distance(R,RD). + + +// BCG! +// !pos is used when it is algways possible to go +// so this plans should not be used: +!pos(X,Y) : last_dir(skip) <- +// .print("It is not possible to go to ",X,"x",Y). +// in the future +//+last_dir(skip) <- .drop_goal(pos) ++!pos(X,Y) : pos(X,Y) <- .print("I've reached ",X,"x",Y). ++!pos(X,Y) : not pos(X,Y) + <- !next_step(X,Y); + !pos(X,Y). + + ++!ensure(pick,_) : pos(X,Y) & cell(X,Y,gold) + <- do(pick); ?carrying_gold. +// fail if no gold there or not carrying_gold after pick! +// handle(G) will "catch" this failure. + ++!ensure(drop, _) : pos(X,Y) & depot(_,X,Y) + <- do(drop). //TODO: not ?carrying_gold. + + +/* end of a simulation */ + ++end_of_simulation(S,_) : true + <- .drop_all_desires; + .abolish(quadrant(_,_,_,_)); + .abolish(gold(_,_)); + .abolish(committed_to(_)); + .abolish(picked(_)); + .abolish(last_checked(_,_)); + -+free; + .print("-- END ",S," --"). + + diff --git a/operator.asl b/operator.asl new file mode 100644 index 0000000..15ccd4c --- /dev/null +++ b/operator.asl @@ -0,0 +1,76 @@ +// Agent operator in project airSeaRescue.mas2j + +/* quadrant allocation */ + +@quads[atomic] ++gsize(W,H) : true + <- // calculate the area of each quadrant and remember them + .print("Defining quadrants for ",W,"x",H," simulation ",S); + +quad(1, 0, 0, W div 2 - 1, H - 1); + +quad(2, W div 2, 0, W-1, H - 1); + .print("Finished all quadrs for "). + ++init_pos(X,Y)[source(A)] + : // if all miners have sent their position + .count(init_pos(_,_),2) + <- .print("* InitPos ",A," is ",X,"x",Y); + // remember who doesn't have a quadrant allocated + // (initially all miners) + +~quad(searchDrone1); +~quad(searchDrone2); + !assign_all_quads([1,2]). ++init_pos(X,Y)[source(A)] + <- .print("- InitPos ",A," is ",X,"x",Y). + + ++!assign_all_quads([]). ++!assign_all_quads([Q|T]) + <- !assign_quad(Q); + !assign_all_quads(T). +// assign quadrant Q to a miner ++!assign_quad(Q) + : quad(Q,X1,Y1,X2,Y2) & + ~quad(_) // there still is a miner without quadrant + <- .findall(Ag, ~quad(Ag), LAgs); + !calc_ag_dist(Q,LAgs,LD); + .min(LD,d(Dist,Ag)); + .print(Ag, "'s Quadrant is: ",Q); + -~quad(Ag); + .send(Ag,tell,quadrant(X1,Y1,X2,Y2)). + ++!calc_ag_dist(Q,[],[]). ++!calc_ag_dist(Q,[Ag|RAg],[d(Dist,Ag)|RDist]) + : quad(Q,X1,Y1,X2,Y2) & init_pos(AgX,AgY)[source(Ag)] + <- // get the distance between X1,Y1 and AgX,AgY + operator.dist(X1,Y1,AgX,AgY,Dist); + !calc_ag_dist(Q,RAg,RDist). + + +/* negotiation for found gold */ + ++bid(Gold,D,Ag) + : .count(bid(Gold,_,_),3) // three bids were received + <- .print("bid from ",Ag," for ",Gold," is ",D); + !allocate_miner(Gold); + .abolish(bid(Gold,_,_)). ++bid(Gold,D,Ag) + <- .print("bid from ",Ag," for ",Gold," is ",D). + ++!allocate_miner(Gold) + <- .findall(op(Dist,A),bid(Gold,Dist,A),LD); + .min(LD,op(DistCloser,Closer)); + DistCloser < 10000; + .print("Gold ",Gold," was allocated to ",Closer, " options were ",LD); + .broadcast(tell,allocated(Gold,Closer)). + //-Gold[source(_)]. +-!allocate_miner(Gold) + <- .print("could not allocate gold ",Gold). + + +/* end of simulation plans */ + +@end_of_simulation[atomic] ++end_of_simulation(_) : true + <- .print("-- END "," --"); + .abolish(init_pos(_,_)). + + diff --git a/searchDrone.asl b/searchDrone.asl new file mode 100644 index 0000000..f4be3d4 --- /dev/null +++ b/searchDrone.asl @@ -0,0 +1,276 @@ +// Agent searchDrone in project airSeaRescue.mas2j + +/* Initial beliefs and rules */ +free. +life(500). + +/* Initial goals */ +// next line is the bottom of the quadrant +// if 2 lines bellow is too far +calc_new_y(AgY,QuadY2,QuadY2) :- AgY+2 > QuadY2. + +// otherwise, the next line is 2 lines bellow +calc_new_y(AgY,_,Y) :- Y = AgY+2. + + ++gsize(_,_) : true + <- !send_init_pos. ++!send_init_pos : pos(X,Y) + <- .print("Position initialised"); + .send(operator,tell,init_pos(X,Y)). ++!send_init_pos : not pos(_,_) // if I do not know my position yet + <- .wait("+pos(X,Y)", 500); // wait for it and try again + !!send_init_pos(S). + ++free : last_checked(X,Y) <- !prep_around(X,Y). ++free : quadrant(X1,Y1,X2,Y2) <- !prep_around(X1,Y1). ++free : true <- !wait_for_quad. + +@pwfq[atomic] ++!wait_for_quad : free & quadrant(_,_,_,_) + <- -+free. ++!wait_for_quad : free + <- .wait("+quadrant(X1,Y1,X2,Y2)", 500); + !!wait_for_quad. ++!wait_for_quad : not free + <- .print("No longer free while waiting for quadrant."). +-!wait_for_quad // .wait might fail + <- !!wait_for_quad. + +// if I am around the upper-left corner, move to upper-right corner ++around(X1,Y1) : quadrant(X1,Y1,X2,Y2) & free + <- .print("in Q1 to ",X2,"x",Y1); + !prep_around(X2,Y1). + +// if I am around the bottom-right corner, move to upper-left corner ++around(X2,Y2) : quadrant(X1,Y1,X2,Y2) & free + <- .print("in Q4 to ",X1,"x",Y1); + !prep_around(X1,Y1). + +// if I am around the right side, move to left side two lines bellow ++around(X2,Y) : quadrant(X1,Y1,X2,Y2) & free + <- ?calc_new_y(Y,Y2,YF); + .print("in Q2 to ",X1,"x",YF); + !prep_around(X1,YF). + +// if I am around the left side, move to right side two lines bellow ++around(X1,Y) : quadrant(X1,Y1,X2,Y2) & free + <- ?calc_new_y(Y,Y2,YF); + .print("in Q3 to ", X2, "x", YF); + !prep_around(X2,YF). + +// last "around" was none of the above, go back to my quadrant ++around(X,Y) : quadrant(X1,Y1,X2,Y2) & free & Y <= Y2 & Y >= Y1 + <- .print("in no Q, going to X1"); + !prep_around(X1,Y). ++around(X,Y) : quadrant(X1,Y1,X2,Y2) & free & X <= X2 & X >= X1 + <- .print("in no Q, going to Y1"); + !prep_around(X,Y1). + ++around(X,Y) : quadrant(X1,Y1,X2,Y2) + <- .print("It should never happen!!!!!! - go home"); + !prep_around(X1,Y1). + ++!prep_around(X,Y) : free + <- -around(_,_); -last_dir(_); !around(X,Y). + ++!around(X,Y) + : // I am around to some location if I am near it or + // the last action was skip (meaning that there are no paths to there) + (pos(AgX,AgY) & searchDrone.neighbour(AgX,AgY,X,Y)) | last_dir(skip) + <- +around(X,Y). ++!around(X,Y) : not around(X,Y) + <- !next_step(X,Y); + !!around(X,Y). ++!around(X,Y) : true + <- !!around(X,Y). + ++!next_step(X,Y) + : pos(AgX,AgY) + <- searchDrone.get_direction(AgX, AgY, X, Y, D); + //.print("from ",AgX,"x",AgY," to ", X,"x",Y," -> ",D); + -+last_dir(D); + do(D). ++!next_step(X,Y) : not pos(_,_) // I still do not know my position + <- !next_step(X,Y). +-!next_step(X,Y) : true // failure handling -> start again! + <- .print("Failed next_step to ", X,"x",Y," fixing and trying again!"); + -+last_dir(null); + !next_step(X,Y). + + +/* Gold-searching Plans */ + +// I perceived unknown gold and I am free, handle it +@pcell[atomic] // atomic: so as not to handle another + // event until handle gold is initialised ++cell(X,Y,gold) + : not carrying_gold & free + <- -free; + +gold(X,Y); + .print("Gold perceived: ",gold(X,Y)); + !init_handle(gold(X,Y)). + +// if I see gold and I'm not free but also not carrying gold yet +// (I'm probably going towards one), abort handle(gold) and pick up +// this one which is nearer +@pcell2[atomic] ++cell(X,Y,gold) + : not carrying_gold & not free & + .desire(handle(gold(OldX,OldY))) & // I desire to handle another gold which + pos(AgX,AgY) & + operator.dist(X, Y, AgX,AgY,DNewG) & + operator.dist(OldX,OldY,AgX,AgY,DOldG) & + DNewG < DOldG // is farther than the one just perceived + <- +gold(X,Y); + .drop_desire(handle(gold(OldX,OldY))); + .print("Giving up current gold ",gold(OldX,OldY), + " to handle ",gold(X,Y)," which I am seeing!"); + .print("Announcing ",gold(OldX,OldY)," to others"); + .broadcast(tell,gold(OldX,OldY)); + .broadcast(untell, committed_to(gold(OldX,OldY))); + !init_handle(gold(X,Y)). + +// I am not free, just add gold belief and announce to others ++cell(X,Y,gold) + : not gold(X,Y) & not committed_to(gold(X,Y)) + <- +gold(X,Y); + .print("Announcing ",gold(X,Y)," to others"); + .broadcast(tell,gold(X,Y)). + +// someone else sent me a gold location ++gold(X1,Y1)[source(A)] + : A \== self & + not allocated(gold(X1,Y1),_) & // The gold was not allocated yet + not carrying_gold & // I am not carrying gold + free & // and I am free + pos(X2,Y2) & + .my_name(Me) + <- operator.dist(X1,Y1,X2,Y2,D); // bid + .send(leader,tell,bid(gold(X1,Y1),D,Me)). + +// bid high as I'm not free ++gold(X1,Y1)[source(A)] + : A \== self & .my_name(Me) + <- .send(leader,tell,bid(gold(X1,Y1),10000,Me)). + +// gold allocated to me +@palloc1[atomic] ++allocated(Gold,Ag)[source(leader)] + : .my_name(Ag) & free // I am still free + <- -free; + .print("Gold ",Gold," allocated to ",Ag); + !init_handle(Gold). + +// some gold was allocated to me, but I can not +// handle it anymore, re-announce +@palloc2[atomic] ++allocated(Gold,Ag)[source(leader)] + : .my_name(Ag) & not free // I am no longer free + <- .print("I can not handle ",Gold," anymore!"); + .print("(Re)announcing ",Gold," to others"); + .broadcast(tell,Gold). + + +// someone else picked up the gold I am going to go, +// so drops the intention and chose another gold +@ppgd[atomic] ++picked(G)[source(A)] + : .desire(handle(G)) | .desire(init_handle(G)) + <- .print(A," has taken ",G," that I am pursuing! Dropping my intention."); + .abolish(G); + .drop_desire(handle(G)); + !!choose_gold. + +// someone else picked up a gold I know about, +// remove from my belief base ++picked(gold(X,Y)) + <- -gold(X,Y)[source(_)]. + + +@pih1[atomic] ++!init_handle(Gold) + : .desire(around(_,_)) + <- .print("Dropping around(_,_) desires and intentions to handle ",Gold); + .drop_desire(around(_,_)); + !init_handle(Gold). +@pih2[atomic] ++!init_handle(Gold) + : pos(X,Y) + <- .print("Going for ",Gold); + -+last_checked(X,Y); + !!handle(Gold). // must use !! to perform "handle" as not atomic + ++!handle(gold(X,Y)) + : not free + <- .print("Handling ",gold(X,Y)," now."); + .broadcast(tell, committed_to(gold(X,Y))); + !pos(X,Y); + !ensure(pick,gold(X,Y)); + // broadcast that I got the gold(X,Y), to avoid someone + // else to pursue this gold + .broadcast(tell,picked(gold(X,Y))); + ?depot(_,DX,DY); + !pos(DX,DY); + !ensure(drop, 0); + -gold(X,Y)[source(_)]; + .print("Finish handling ",gold(X,Y)); + !!choose_gold. + +// if ensure(pick/drop) failed, pursue another gold +-!handle(G) : G + <- .print("failed to catch gold ",G); + .abolish(G); // ignore source + !!choose_gold. +-!handle(G) : true + <- .print("failed to handle ",G,", it isn't in the BB anyway"); + !!choose_gold. + +// no known gold to choose from +// become free again to search for gold ++!choose_gold + : not gold(_,_) + <- -+free. + +// Finished one gold, but others left +// find the closest gold among the known options, +// that nobody else committed to ++!choose_gold + : gold(_,_) + <- .findall(gold(X,Y),gold(X,Y),LG); + !calc_gold_distance(LG,LD); + .length(LD,LLD); LLD > 0; + .print("Uncommitted gold distances: ",LD,LLD); + .min(LD,d(_,NewG)); + .print("Next gold is ",NewG); + !!handle(NewG). +-!choose_gold <- -+free. + ++!calc_gold_distance([],[]). ++!calc_gold_distance([gold(GX,GY)|R],[d(D,gold(GX,GY))|RD]) + : pos(IX,IY) & not committed_to(gold(GX,GY)) + <- operator.dist(IX,IY,GX,GY,D); + !calc_gold_distance(R,RD). ++!calc_gold_distance([_|R],RD) + <- !calc_gold_distance(R,RD). + + +// BCG! +// !pos is used when it is algways possible to go +// so this plans should not be used: +!pos(X,Y) : last_dir(skip) <- +// .print("It is not possible to go to ",X,"x",Y). +// in the future +//+last_dir(skip) <- .drop_goal(pos) ++!pos(X,Y) : pos(X,Y) <- .print("I've reached ",X,"x",Y). ++!pos(X,Y) : not pos(X,Y) + <- !next_step(X,Y); + !pos(X,Y). + + ++!ensure(pick,_) : pos(X,Y) & cell(X,Y,gold) + <- do(pick); ?carrying_gold. +// fail if no gold there or not carrying_gold after pick! +// handle(G) will "catch" this failure. + ++!ensure(drop, _) : pos(X,Y) & depot(_,X,Y) + <- do(drop). //TODO: not ?carrying_gold. diff --git a/src/java/operator/WorldEnvironment.java b/src/java/operator/WorldEnvironment.java index 628e770..b51c8ca 100644 --- a/src/java/operator/WorldEnvironment.java +++ b/src/java/operator/WorldEnvironment.java @@ -1,9 +1,6 @@ package operator; -import jason.asSyntax.Literal; -import jason.asSyntax.NumberTerm; -import jason.asSyntax.Structure; -import jason.asSyntax.Term; +import jason.asSyntax.*; import jason.environment.Environment; import jason.environment.grid.Location; @@ -31,7 +28,6 @@ public class WorldEnvironment extends Environment { UP, DOWN, RIGHT, LEFT } - ; @Override public void init(String[] args) { @@ -56,10 +52,57 @@ public class WorldEnvironment extends Environment { } private void updateAgetPos(int i) { - clearPercepts("victom" + (i + 1)); + String prefix = ""; + if (i < 4) + prefix = "victim"; + else if (i < 6) { + prefix = "searchDrone"; + } + int offset = 0; + if (i > 3 && i < 6) { + offset = 4; + } + clearPercepts(prefix + (i + 1)); Location l = model.getAgPos(i); - addPercept("victim" + (i + 1), Literal.parseLiteral("pos(" + l.x + "," + l.y + ")")); + addPercept(prefix + (i + 1 - offset), Literal.parseLiteral("pos(" + l.x + "," + l.y + ")")); + } + + private void updateAgPercept(int ag) { + updateAgPercept(getNameFromId(ag), ag); + } + + private void updateAgPercept(String agName, int ag) { + clearPercepts(agName); + // its location + Location l = model.getAgPos(ag); + addPercept(agName, Literal.parseLiteral("pos(" + l.x + "," + l.y + ")")); + updateAgPercept(agName, l.x - 1, l.y - 1); + updateAgPercept(agName, l.x - 1, l.y); + updateAgPercept(agName, l.x - 1, l.y + 1); + updateAgPercept(agName, l.x, l.y - 1); + updateAgPercept(agName, l.x, l.y); + updateAgPercept(agName, l.x, l.y + 1); + updateAgPercept(agName, l.x + 1, l.y - 1); + updateAgPercept(agName, l.x + 1, l.y); + updateAgPercept(agName, l.x + 1, l.y + 1); + } + + private void updateAgPercept(String agName, int x, int y) { + if (model == null || !model.inGrid(x,y)) return; + if (model.hasObject(WorldModel.OBSTACLE, x, y)) { + addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",obstacle)")); + } else { + if (model.hasObject(WorldModel.VICTIM, x, y)) { + addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",gold)")); + } + if (model.hasObject(WorldModel.ENEMY, x, y)) { + addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",enemy)")); + } + if (model.hasObject(WorldModel.AGENT, x, y)) { + addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",ally)")); + } + } } @@ -72,44 +115,62 @@ public class WorldEnvironment extends Environment { @Override public boolean executeAction(String ag, Structure action) { - boolean result = false; - try { - if (sleep > 0) { - Thread.sleep(sleep); - } - int agId = getAgIdBasedOnName(ag); + synchronized(this) { + boolean result = false; + try { + if (sleep > 0) { + Thread.sleep(sleep); + } + int agId = getAgIdBasedOnName(ag); - if (action.equals(up)) { - result = model.move(Move.UP, agId); - } else if (action.equals(down)) { - result = model.move(Move.DOWN, agId); - } else if (action.equals(right)) { - result = model.move(Move.RIGHT, agId); - } else if (action.equals(left)) { - result = model.move(Move.LEFT, agId); - } else if (action.equals(skip)) { - result = true; - } else if (action.getFunctor().equals("decLife")) { - int life = (int)((NumberTerm)action.getTerm(0)).solve(); - System.out.println(life); - result = true; - //removePercept(ag,Literal.parseLiteral("life("+life+")")); - // addPercept(ag,Literal.parseLiteral("life("+(life-1)+")")); - } else { - logger.info("executing: " + action + ", but not implemented!"); + if (action.equals(up)) { + result = model.move(Move.UP, agId); + } else if (action.equals(down)) { + result = model.move(Move.DOWN, agId); + } else if (action.equals(right)) { + result = model.move(Move.RIGHT, agId); + } else if (action.equals(left)) { + result = model.move(Move.LEFT, agId); + } else if (action.equals(skip)) { + result = true; + } else if (action.getFunctor().equals("decLife")) { + int life = (int) ((NumberTerm) action.getTerm(0)).solve(); + System.out.println(life); + result = true; + //removePercept(ag,Literal.parseLiteral("life("+life+")")); + // addPercept(ag,Literal.parseLiteral("life("+(life-1)+")")); + } else { + logger.info("executing: " + action + ", but not implemented!"); + } + if (result) { + updateAgPercept(agId); + return true; + } + } catch (Exception e) { + logger.log(Level.SEVERE, "error executing " + action + " for " + ag, e); } - if (result) { - //updateAgPercept(agId); - return true; - } - } catch (Exception e) { - logger.log(Level.SEVERE, "error executing " + action + " for " + ag, e); + return false; } - return false; } - private int getAgIdBasedOnName(String agName) { - return (Integer.parseInt(agName.substring(agName.length() - 1)) - 1); + public static int getAgIdBasedOnName(String agName) { + int i = Integer.parseInt(agName.substring(agName.length() - 1)) - 1; + if (agName.startsWith("victim")) { + return i; + } + if (agName.startsWith("searchDrone")) { + return i + 4; + } + return -1; + } + + public String getNameFromId(int i) { + if(i < 4) { + return "victim"+(i+1); + } else if (i < 6) { + return "searchDrone"+(i+5); + } + return ""; } public void setSleep(int value) { diff --git a/src/java/operator/WorldModel.java b/src/java/operator/WorldModel.java index db62872..a869cec 100644 --- a/src/java/operator/WorldModel.java +++ b/src/java/operator/WorldModel.java @@ -20,7 +20,7 @@ public class WorldModel extends GridWorldModel { static WorldModel senario1() { - WorldModel result = new WorldModel(35, 35, 4); + WorldModel result = new WorldModel(35, 35, 6); Random random1 = new Random(); for (int i = 0; i <= 4; i++) { result.add(WorldModel.OBSTACLE, random1.nextInt(34), random1.nextInt(34)); @@ -29,11 +29,15 @@ public class WorldModel extends GridWorldModel { result.setAgPos(1, 20, 0); result.setAgPos(2, 3, 20); result.setAgPos(3, 20, 20); + System.out.println(result.getNbOfAgs()); + result.setAgPos(4,33,34); + result.setAgPos(5,0,34); result.add(DEPOT,34,34); + model = result; return result; } - boolean move(WorldEnvironment.Move dir, int ag) throws Exception { + synchronized boolean move(WorldEnvironment.Move dir, int ag) throws Exception { Location l = getAgPos(ag); switch (dir) { case UP: @@ -62,7 +66,6 @@ public class WorldModel extends GridWorldModel { @Override public Location getAgPos(int ag) { - System.out.println(agPos.length+" "+ag+" "+agPos[0].x+" "+agPos[0].y); return super.getAgPos(ag); } diff --git a/src/java/operator/WorldView.java b/src/java/operator/WorldView.java index 22240a1..fc392f4 100644 --- a/src/java/operator/WorldView.java +++ b/src/java/operator/WorldView.java @@ -25,8 +25,8 @@ public class WorldView extends GridWorldView { } JLabel jlMouseLoc; - JSlider jSpeed; - JLabel jGoldsC; + JSlider jSpeed; + JLabel jGoldsC; @Override public void initComponents(int width) { @@ -44,11 +44,11 @@ public class WorldView extends GridWorldView { jSpeed.setMajorTickSpacing(100); jSpeed.setMinorTickSpacing(20); jSpeed.setInverted(true); - Hashtable labelTable = new Hashtable(); - labelTable.put( 0, new JLabel("max") ); - labelTable.put( 200, new JLabel("speed") ); - labelTable.put( 400, new JLabel("min") ); - jSpeed.setLabelTable( labelTable ); + Hashtable labelTable = new Hashtable(); + labelTable.put(0, new JLabel("max")); + labelTable.put(200, new JLabel("speed")); + labelTable.put(400, new JLabel("min")); + jSpeed.setLabelTable(labelTable); JPanel p = new JPanel(new FlowLayout()); p.setBorder(BorderFactory.createEtchedBorder()); p.add(jSpeed); @@ -82,7 +82,7 @@ public class WorldView extends GridWorldView { jSpeed.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (env != null) { - env.setSleep((int)jSpeed.getValue()); + env.setSleep((int) jSpeed.getValue()); } } }); @@ -99,26 +99,36 @@ public class WorldView extends GridWorldView { udpateCollectedGolds();*/ } } - public void mouseExited(MouseEvent e) {} - public void mouseEntered(MouseEvent e) {} - public void mousePressed(MouseEvent e) {} - public void mouseReleased(MouseEvent e) {} + + public void mouseExited(MouseEvent e) { + } + + public void mouseEntered(MouseEvent e) { + } + + public void mousePressed(MouseEvent e) { + } + + public void mouseReleased(MouseEvent e) { + } }); getCanvas().addMouseMotionListener(new MouseMotionListener() { - public void mouseDragged(MouseEvent e) { } + public void mouseDragged(MouseEvent e) { + } + public void mouseMoved(MouseEvent e) { int col = e.getX() / cellSizeW; int lin = e.getY() / cellSizeH; if (col >= 0 && lin >= 0 && col < getModel().getWidth() && lin < getModel().getHeight()) { - jlMouseLoc.setText(col+","+lin+")"); + jlMouseLoc.setText(col + "," + lin + ")"); } } }); } public void udpateCollectedGolds() { - WorldModel wm = (WorldModel)model; + WorldModel wm = (WorldModel) model; //jGoldsC.setText(wm.getGoldsInDepot() + "/" + wm.getInitialNbGolds()); } @@ -140,14 +150,16 @@ public class WorldView extends GridWorldView { @Override public void drawAgent(Graphics g, int x, int y, Color c, int id) { Color idColor = Color.black; - /*if (((WorldModel)model).isCarryingGold(id)) { - super.drawAgent(g, x, y, Color.yellow, -1); - } else {*/ - super.drawAgent(g, x, y, Color.GREEN, -1); - idColor = Color.white; + if(id <4){ + idColor = Color.RED; + } else if (id < 6) { + idColor = Color.MAGENTA; + } + super.drawAgent(g, x, y, idColor, -1); + idColor = Color.white; //} g.setColor(idColor); - drawString(g, x, y, defaultFont, String.valueOf(id+1)); + drawString(g, x, y, defaultFont, String.valueOf(id + 1)); } public void drawDepot(Graphics g, int x, int y) { @@ -182,13 +194,13 @@ public class WorldView extends GridWorldView { public static void main(String[] args) throws Exception { WorldEnvironment env = new WorldEnvironment(); - env.init(new String[] {"5","50","yes"}); + env.init(new String[]{"5", "50", "yes"}); } @Override public void drawEmpty(Graphics g, int x, int y) { g.setColor(Color.blue); - g.fillRect(x * cellSizeW + 1, y * cellSizeH+1, cellSizeW-1, cellSizeH-1); + g.fillRect(x * cellSizeW + 1, y * cellSizeH + 1, cellSizeW - 1, cellSizeH - 1); g.setColor(Color.cyan); g.drawRect(x * cellSizeW, y * cellSizeH, cellSizeW, cellSizeH); } diff --git a/src/java/operator/dist.java b/src/java/operator/dist.java new file mode 100644 index 0000000..5659285 --- /dev/null +++ b/src/java/operator/dist.java @@ -0,0 +1,27 @@ +package operator; + +import jason.asSemantics.DefaultInternalAction; +import jason.asSemantics.TransitionSystem; +import jason.asSemantics.Unifier; +import jason.asSyntax.NumberTerm; +import jason.asSyntax.NumberTermImpl; +import jason.asSyntax.Term; +import jason.environment.grid.Location; + +public class dist extends DefaultInternalAction { + + @Override + public Object execute(TransitionSystem ts, Unifier un, Term[] terms) throws Exception { + try { + int iagx = (int) ((NumberTerm) terms[0]).solve(); + int iagy = (int) ((NumberTerm) terms[1]).solve(); + int itox = (int) ((NumberTerm) terms[2]).solve(); + int itoy = (int) ((NumberTerm) terms[3]).solve(); + int dist = new Location(iagx, iagy).distance(new Location(itox, itoy)); + return un.unifies(terms[4], new NumberTermImpl(dist)); + } catch (Throwable e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/src/java/searchDrone/get_direction.java b/src/java/searchDrone/get_direction.java new file mode 100644 index 0000000..12eae8e --- /dev/null +++ b/src/java/searchDrone/get_direction.java @@ -0,0 +1,55 @@ +package searchDrone; + +import jason.asSemantics.DefaultInternalAction; +import jason.asSemantics.TransitionSystem; +import jason.asSemantics.Unifier; +import jason.asSyntax.Atom; +import jason.asSyntax.NumberTerm; +import jason.asSyntax.Term; +import jason.environment.grid.Location; +import operator.WorldEnvironment; +import operator.WorldModel; + +public class get_direction extends DefaultInternalAction { + + @Override + public Object execute(TransitionSystem ts, Unifier un, Term[] terms) throws Exception { + try { + String sAction = "skip"; + int id = WorldEnvironment.getAgIdBasedOnName(ts.getAgArch().getAgName()); + WorldModel model = WorldModel.get(); + Location agent_loc =model.getAgPos(id); + + int agent_x = agent_loc.x; + int agent_y = agent_loc.y; + int to_x = (int)((NumberTerm)terms[2]).solve(); + int to_y = (int)((NumberTerm)terms[3]).solve(); + + if (model.inGrid(to_x,to_y)) { + Location agnet_location = new Location(agent_x, agent_y); + while (!model.isFreeOfObstacle(to_x,to_y) && to_x > 0) to_x--; + while (!model.isFreeOfObstacle(to_x,to_y) && to_x < model.getWidth()) to_x++; + while (!model.isFreeOfObstacle(to_x,to_y) && to_y > 0) to_y--; + while (!model.isFreeOfObstacle(to_x,to_y) && to_y < model.getHeight()) to_y++; + + System.out.println("To: "+to_x+", "+to_y+"\t"+agent_x+", "+agent_y); + + if(to_x < agent_x && model.isFreeOfObstacle(agent_x-1,agent_y)){ + sAction = "left"; + }else if (to_x > agent_x && model.isFreeOfObstacle(agent_x+1,agent_y)){ + sAction = "right"; + } + if (to_y < agent_y && model.isFreeOfObstacle(agent_x,agent_y-1)){ + sAction = "up"; + } else if (to_y > agent_y && model.isFreeOfObstacle(agent_x,agent_y+1)) { + sAction = "down"; + } + } + System.out.println(sAction); + return un.unifies(terms[4], new Atom(sAction)); + } catch (Throwable e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/src/java/searchDrone/neighbour.java b/src/java/searchDrone/neighbour.java new file mode 100644 index 0000000..dddd8fa --- /dev/null +++ b/src/java/searchDrone/neighbour.java @@ -0,0 +1,26 @@ +package searchDrone; + +import jason.asSemantics.DefaultInternalAction; +import jason.asSemantics.TransitionSystem; +import jason.asSemantics.Unifier; +import jason.asSyntax.NumberTerm; +import jason.asSyntax.Term; +import jason.environment.grid.Location; + +public class neighbour extends DefaultInternalAction { + + @Override + public Object execute(TransitionSystem ts, Unifier un, Term[] terms) throws Exception { + try { + int iagx = (int)((NumberTerm)terms[0]).solve(); + int iagy = (int)((NumberTerm)terms[1]).solve(); + int itox = (int)((NumberTerm)terms[2]).solve(); + int itoy = (int)((NumberTerm)terms[3]).solve(); + + return new Location(iagx, iagy).isNeigbour(new Location(itox, itoy)); + } catch (Throwable e) { + e.printStackTrace(); + return false; + } + } +} \ No newline at end of file diff --git a/src/java/victim/get_direction.java b/src/java/victim/get_direction.java index 6f67d82..0342d10 100644 --- a/src/java/victim/get_direction.java +++ b/src/java/victim/get_direction.java @@ -28,7 +28,6 @@ public class get_direction extends DefaultInternalAction { List actions = new ArrayList<>(); - System.out.println("X: "+AgX+" Y: "+AgY); if(AgX < 34) actions.add("right"); if(AgX > 0) @@ -38,7 +37,6 @@ public class get_direction extends DefaultInternalAction { if(AgY >= 0) actions.add("up"); String action = actions.get(r.nextInt(actions.size())); - System.out.println(actions); return un.unifies(terms[2], new Atom(action)); } catch (Throwable e) { e.printStackTrace(); diff --git a/victim.asl b/victim.asl index d01563d..cb37cfe 100644 --- a/victim.asl +++ b/victim.asl @@ -1,4 +1,4 @@ -// Agent sample_agent in project airSeaRescue +// Agent victim in project airSeaRescue /* Initial beliefs and rules */ free.