I just wrote an easy goal program, here it is, took very little effort! I bet a kid can do this.
The motivation is a game where theres so many teams of so many robots and they have to flip the opponent teams robots over. If they get flipped 3 times, then they will not unturn themselves anymore. I do that by checking the state, and then i dont remove the flip angle from the score anymore, and then they should play dead once they get their 3rd flip.
They move around by retreating if they get more than 1 robot ganging up on them, and then theyll flee to their closest ally.
Also theres a little thing in there that if one of their friends is flipped nearby, they will unflip him, if he has no power to flip himself because his flipcount has gone to 3, but if the robot manages to flip him over he can temporarily come back alive again, because their friends flip angle is also put into their score, so they are motivated by it.
Thats how its sitting in the algorythm as it is right now anyhow. Just wrote it, took about an hour, *facepalm* going so slowly, have no motivation myself. score really low personally.... cant code for nuts at the moment, just got to keep on truckin'.
(the full code for a team robot wrestling game motivator.)
struct STATE_MEM
{
float flipweight; //ranging from 0 -> 1 is how flipped the robot is. (just do it with the angle of the central body.)
bool flipped; //if this is true, this has to unflip for it to get flipped again.
uint flips; //if this goes to 3, the robot will not unturn itself anymore, just plays dead.
};
struct GBBOT
{
STATE_MEM state_mem;
PNT pnt[GBBOT_PNTS];
PNT vel[GBBOT_PNTS];
int hinge_pos[GBBOT_HINGES]; //the actual hinge position. this only moves at 1 set speed. (u get speed changes below this set speed by it deactivating and activating.)
int hinge_min[GBBOT_HINGES];
int hinge_max[GBBOT_HINGES];
int hinge_tpos[GBBOT_HINGES]; //target virtual position of the hinge has a position
int hinge_tvel[GBBOT_HINGES]; //and a velocity, and operates in a low passed fashion.
EDG edge[GBBOT_EDGES];
TEN tendon[GBBOT_TENDONS]; //so these tendons get their lengths set to rotate the legs! (best way i think!)
uint motorstring[GBBOT_HINGES*PROJECTIONS]; //set the hinge animation with these.
uint closest[GBSIMBOTS-1]; //closest 2 other bots.
uint closest_stick[2]; //my stick and the closer robots stick
PLN closest_plane[GBBOT_PNTS]; //plane for the floor underneath the foot.
uint team;
uint bot;
};
struct ENVIRO
{
PNT ground[ENVIRO_PNTS];
GROUNDGRID groundgrid[GGSECS_X*GGSECS_Y];
GBBOT gbbot[GBBOTS*GBTEAMS+1]; //dont forget the +1 for the default robot stance.
GBBOT gbbotsim[GBSIMBOTS]; //sim it and 2 closest.
GBBOT gbbotsim2[GBSIMBOTS]; //sim it and 2 closest.
};
#define FLIPS_TILL_OUT 3
#define FLIPSCOREWEIGHT 1000
#define UNFLIPFRIENDPROXIMITY 40
void step_statemem(GBBOT* bot)
{
bool flipped=false;
//get the angle of the body.
int bodyvec=(bot->pnt[0].x-bot->pnt[4].x);
float fw=(-(bodyvec/bot->edge[48].length)*2)-1;
if(fw>0.5) flipped=true;
if(flipped==false){if(bot->state_mem.flipped){bot->state_mem.flipped=false;}}
if(flipped==true){if(bot->state_mem.flipped==false){bot->state_mem.flips++;bot->state_mem.flipped=true;}}
}
int compute_gb_score(void) //in here goes the sim bots. (and the terrain if u want, but u wont need it for this.)
{
uint i,j,k,l,m;
int score=0;
//update the flip state. (they have a small amount of temporary memory to remember some values.
for(i=0;i<GBSIMBOTS;i++){step_statemem(&enviro.gbbotsim2[i]);}
// compute what team the n simulated bots are on.
uint hometeam=enviro.gbbotsim2[0].team;
bool enemy[GBSIMBOTS-1];
for(i=0;i<GBSIMBOTS-1;i++){if(enviro.gbbotsim2[i+1].team==hometeam){enemy[i]=false;}else{enemy[i]=true;}}
//then you want the enemies flipped, and it unflipped. (only if its not its last flip.)
if(enviro.gbbotsim2[0].state_mem.flips<FLIPS_TILL_OUT){score-=enviro.gbbotsim2[0].state_mem.flipweight*1000;}
for(i=0;i<GBSIMBOTS-1;i++){if(enemy[i]==false){score-=enviro.gbbotsim2[i+1].state_mem.flipweight*FLIPSCOREWEIGHT;}else{score+=enviro.gbbotsim2[i+1].state_mem.flipweight*FLIPSCOREWEIGHT;}}
PNT centrepos1[GBSIMBOTS];
//get the centrepositions of the sim bots.
for(i=0;i<GBSIMBOTS;i++)
{
for(k=0;k<GBBOT_PNTS;k++)
{
centrepos1[i].x+=enviro.gbbotsim2[i].pnt[k].x;
centrepos1[i].y+=enviro.gbbotsim2[i].pnt[k].y;
centrepos1[i].z+=enviro.gbbotsim2[i].pnt[k].z;
}
centrepos1[i].x/=GBBOT_PNTS;
centrepos1[i].y/=GBBOT_PNTS;
centrepos1[i].z/=GBBOT_PNTS;
}
//then if your friend is flipped, and ur nearby, you reduce proximity to help him unflip.
for(i=0;i<GBSIMBOTS-1;i++)
{
if(enemy[i]==false){float distance=abs(centrepos1[0].x-centrepos1[i+1].x)+abs(centrepos1[0].y-centrepos1[i+1].y)+abs(centrepos1[0].z-centrepos1[i+1].z);if(distance<UNFLIPFRIENDPROXIMITY){score-=distance;}}
}
bool finding_friend=false;
//RETREATING
uint enemies=0;
uint friends=0;
for(i=0;i<GBSIMBOTS-1;i++){if(enemy[i]){enemies++;}else{friends++;}}
if(enemies-friends>1)
{
//go to the nearest friend on the map. (doesnt need to be an updated position.)
finding_friend=true;
}
//get the centrepositions of the bots mainlist.
bool friend1[GBTEAMS*GBBOTS];
bool flipped1[GBTEAMS*GBBOTS];
PNT centrepos[GBTEAMS*GBBOTS];
memset(centrepos,0,sizeof(PNT)*GBTEAMS*GBBOTS);
for(i=0;i<GBTEAMS;i++)
{
for(j=0;j<GBBOTS;j++)
{
if(i==hometeam){friend1[i*GBBOTS+j]=true;}else{friend1[i*GBBOTS+j]=false;}
flipped1[i*GBBOTS+j]=enviro.gbbot[i*GBBOTS+j].state_mem.flipped;
for(k=0;k<GBBOT_PNTS;k++)
{
centrepos[i*GBBOTS+j].x+=enviro.gbbot[i*GBBOTS+j].pnt[k].x;
centrepos[i*GBBOTS+j].y+=enviro.gbbot[i*GBBOTS+j].pnt[k].y;
centrepos[i*GBBOTS+j].z+=enviro.gbbot[i*GBBOTS+j].pnt[k].z;
}
centrepos[i*GBBOTS+j].x/=GBBOT_PNTS;
centrepos[i*GBBOTS+j].y/=GBBOT_PNTS;
centrepos[i*GBBOTS+j].z/=GBBOT_PNTS;
}
}
//if finding friend is true i go to closest friend.
//otherwise i go to closest unflipped enemy.
//MOVING (changing battle topology.)
uint closest=0;
uint closest_dist=1000000000;
for(i=0;i<GBTEAMS;i++)
{
for(j=0;j<GBBOTS;j++)
{
if(enviro.gbbotsim2[0].bot!=j || enviro.gbbotsim2[0].team!=i)
{
uint dist=abs(centrepos1[0].x-centrepos[i*GBBOTS+j].x)+abs(centrepos1[0].y-centrepos[i*GBBOTS+j].y)+abs(centrepos1[0].z-centrepos[i*GBBOTS+j].z);
if(dist<closest_dist)
{
bool mark=false;
if(finding_friend){if(friend1[i*GBBOTS+j]){mark=true;}}
else{if(friend1[i*GBBOTS+j]==false && flipped1[i*GBBOTS+j]==false){mark=true;}}
if(mark){closest=i*GBBOTS+j;closest_dist=dist;}
}
}
}
}
score-=closest_dist;
return score;
}
So... I want to get this thing actually running, Ive nearly got the rest of the framework in, but its probably another couple of days cause Im working so slowly...
But hopefully Ill get the little robot wrestling game going.
I hope once I get it going in the computer, Ill be able to run it on the gtx2070 bot in real life and it may be able to do it outside my house in the driveway!
Ill keep going.