• Nem Talált Eredményt

The implementation of the throw-in

In document Paternoster of Programmers Reloaded (Pldal 58-62)

Let's get started with robot soccer

2.1. The implementation of the throw-in

If we compare the lobogofcpp.h source files of Debrecen Great Forest FC++ and Debreceni Hivatásos FC++

we will see the that the former one is shorter than the latter one. Accordingly, the lexer has also changed as it is shown in the next code snippet from the point of view of the ball:

{BALL}{WS}{FLOAT}{WS}{FLOAT} {

std::sscanf(yytext, "((b) %f %f", &dist_buffer, &ang_buffer);

ball.setDistAng(time, dist_buffer, ang_buffer); }

The lexer had to be extended with further player modes, for example the following referee's messages are received by the clients:

enum RefereePlayMode { before_kick_off,

play_on, half_time, drop_ball, kick_off_r, kick_off_l, corner_kick_r, corner_kick_l, free_kick_l, free_kick_r, kick_in_l, kick_in_r, goal_l, goal_r, free_kick_fault_l, free_kick_fault_r, offside_l, offside_r };

Our lecture notes focus on the corner kick and the throw-in play modes. The kick off and the ball in play modes have already been processed in the previous versions of the teams, see the book [PROP]. The kick off is handled by the beforeKickOff, the ball in play and the newly handled modes are processed by the function playOn: switch

(thisclient->bl.get_play_mode()) { case half_time: case goal_l:

case goal_r: case before_kick_off: beforeKickOff(thisclient);

//beforeKickOff_light_testing(thisclient); break; case play_on: case kick_off_l: case kick_off_r: thisclient->bl.nof_kickin_quantums = 0; playOn(thisclient); //playOn_light_testing(thisclient); break; case kick_in_l: if (thisclient->bl.get_lr() == 'l') kickIn(thisclient);

else playOn(thisclient); break; case kick_in_r: if

(thisclient->bl.get_lr() == 'r') kickIn(thisclient); else playOn(thisclient); break; case corner_kick_r: if

(thisclient->bl.get_lr() == 'r') cornerKickAtt(thisclient); else cornerKickDef(thisclient); break; case corner_kick_l: if

(thisclient->bl.get_lr() == 'l') cornerKickAtt(thisclient); else cornerKickDef(thisclient); break; case free_kick_l: case free_kick_r:

case free_kick_fault_l: case free_kick_fault_r: case offside_l: case offside_r: case drop_ball: playOn(thisclient); break;

}

In this snippet, the commented out beforeKickOff_light_testing was used only to test the simplification.

At taking a throw-in (in the case of kick_in_l and kick_in_r) we distinguish the team which throws in the ball. And finally the attacker and defender teams are treated separately at corner kicks.

2.1. The implementation of the throw-in

We follow the solution shown in the book [MIRC], where we distiguished the moving into the position to make the throw-in and the throw-in itself. The latter activity includes the looking out for teammates to whom the ball can be passed. These activities are not divided into various functions but we use the following kickIn function:

static void kickIn(Client * to; thisclient->coach.set_formation(Formations::F_4_4_2_F); int

tx =

thisclient->coach.get_formation().get_formation_x(squad_number, lr); int ty =

thisclient->coach.get_formation().get_formation_y(squad_number);

if (thisclient->bl.get_ball_dist() < .8) { if ((1)(to =

thisclient->bl.pass_to_farthes(3)) != -1) { std::snprintf(buf, 64, "(kick %d %f)\0",

thisclient->bl.tavhozEro(thisclient->bl.get_own_player(to).getDist()), thisclient->bl.get_own_player(to).getAng());

thisclient->bl.get_ball_ang()); thisclient->sndCmd(buf);

std::cout << thisclient->bl.get_squad_number()<<

1 If an agent can see the ball we will investigate its distance from the ball

2 then the following situations will be investigated:

3 Is the ball close enough to kick it?

4 If yes, then, using the pass_to_farthes function, the agent will ask: whom should be passed to?

5 If there are no suitable teammates, the thrower will kick the ball or turn 25 degrees to look for suitable teammates depending on whether this situation has already happened more than 10 times.

6 Returning to the investigation of the distance of the ball, if the agent can see the ball under an angle smaller than 20 degrees, it will turn in order to try to correct the angle to 0.

7 In the same indentation level if the ball's distance is less than 30 meters and the player is nearest to the ball, the player will sprint to take the throw-in.

8 If none of the above conditions are met, the agent will move towards its tactical position (tx, ty).

9 And finally, if the agent cannot see the ball, it will search the ball, to be more precise, it will make a 40 degrees turn.

2.1.1. Testing the throw-in

We have made a video on testing that can be seen at http://youtu.be/HiaPWqSzYxk,

.

Using screenshots we emphasize some moments in order to better understand how the previous code snippet works. (These pictures are made independently from the video.)

Figure 5.3. Testing the throw-in: player 11 kicks the ball across the touch line.

The next code snippet moves the player towards the ball . } else if

(thisclient->bl.get_ball_dist() < 40.0 &&

((to=thisclient->bl.nof_seen_teammates()) < 3)) { // 40-ról is jön bedobni, ha esetleg lát is társakat (mert az előző ág nem teljesült) std::snprintf(buf, 64, "(dash %f)\0", 100.0/(to + 1.0)); thisclient->sndCmd(buf); std::cout <<

thisclient->bl.get_squad_number()<< " megyUNK dobni "

<< std::endl;

Figure 5.4. Testing of the throw-in: player 4 starts to move towards the ball.

After some simulation cycles the player 4 will be closer to the ball than 30 meters.

} else if

(thisclient->bl.get_ball_dist() < 30.0 &&

thisclient->bl.pass_to_farthes(2)==-1) { // 30-ról is sprintel bedobni, ha nincs közelebbi társ thisclient->sndCmd("(dash 100)"); std::cout <<

thisclient->bl.get_squad_number()<< " megyek dobni 100"

<< std::endl;

Figure 5.5. Testing the throw-in: player 4 is closer than 30 meters.

When the player agent reaches the ball, it will turn in order to see teammates who are available for receiving the ball.

Figure 5.6. Testing of the throw-in: player 4 has just arrived to the ball.

The player 4 has found player 3 who is available for receiving the ball.

if

(thisclient->bl.get_ball_dist() < .8) { if ((to =

thisclient->bl.pass_to_farthes(3)) != -1) { std::snprintf(buf, 64, "(kick %d %f)\0",

thisclient->bl.tavhozEro(thisclient->bl.get_own_player(to).getDist()), thisclient->bl.get_own_player(to).getAng());

thisclient->sndCmd(buf); std::cout << time << " "

<< thisclient->bl.get_squad_number()<< " passz (bedobas) " << to+1 << std::endl;

Figure 5.7. Testing of the throw-in: player 4 passes the ball to player 3.

Figure 5.8. Testing the throw-in: the ball is moving towards player 3.

In document Paternoster of Programmers Reloaded (Pldal 58-62)