rotate_and_fire.cc を改造した。
ファイル raf.lzh ダウンロード。 主要プログラムリストダウンロード
{}
) としている。
class Robo
{
char* robot_name;
char* robot_colour;
名前と色は Robo 内だけで処理するため、 private
public:
Robo (const char* name, const char* colour);
virtual ~Robo ();
void initValue ();
コンストラクタで名前と色を指定する。 派生クラスを前提としているのでデストラクタは仮想にする。
void robot_option ( const int option_nr, const int value );
void name ( const char* name );
void colour ( const char* home, const char* away );
void rotate ( const int what, const double vel );
...
シミュレータとやりとりする部分は派生クラスでオーバーライドする必要ない ので virtual 指定しない。
void check_messages ( );
check_messages が主メソッド シミュレータからのメッセージを受けとり、解析して各メソッドを呼び出す。
virtual void game_starts (){}
virtual void radar_noobject ( const double dist, const double angle ){}
virtual void radar_robot ( const double dist, const double angle ){}
...
各呼び出されるメソッドは virtual 指定だが、デフォルトでなにもしない関 数として定義される。
bool is_quitting () { return quitting; } protected: bool quitting; // Boolean variables to control if it is allowed to change robot // rotation and acceleration. bool rotate_allowed; bool acceleration_change_allowed;
派生クラスで読み出す可能性のある変数は protected で宣言
void
Robo::robot_option( const int option, const int value )
{
cout << "RobotOption " << option << " " << value << endl;
}
...
サーバ(シミュレータ)へは標準出力でメッセージを送る
void
Robo::check_messages( )
{
quitting = false;
char msg_name[81];
message_to_robot_type msg_t;
cin.clear();
while( !cin.eof() && !quitting )
{
pre_checking_messages();
cin >> msg_name;
msg_t = name2msg_to_robot_type(msg_name);
switch(msg_t)
{
case INITIALIZE:
{
int init;
cin >> init;
initialize( init );
}
break;
case YOUR_NAME:
{
char name[81];
cin >> name;
your_name( name );
}
break;
case YOUR_COLOUR:
{
char col[81];
cin >> col;
your_colour( col );
}
break;
case GAME_OPTION:
{
int nr;
double value;
cin >> nr >> value;
game_option( nr, value );
}
break;
case GAME_STARTS:
game_starts();
break;
case RADAR:
{
double dist, angle;
int object;
cin >> dist >> object >> angle;
switch(object)
{
case NOOBJECT:
radar_noobject( dist, angle );
break;
case ROBOT:
radar_robot( dist, angle );
break;
case WALL:
radar_wall( dist, angle );
break;
case SHOT:
radar_shot( dist, angle );
break;
case COOKIE:
radar_cookie( dist, angle );
break;
case MINE:
radar_mine( dist, angle );
break;
default:
cout << "Print" << _("Unknown Object seen!") << endl;
break;
}
}
break;
case COORDINATES:
{
double x, y, rotation;
cin >> x >> y >> rotation;
coordinates( x, y, rotation );
}
break;
case INFO:
{
double time, speed, cannon_angle;
cin >> time >> speed >> cannon_angle;
info( time, speed, cannon_angle );
}
break;
case ROBOT_INFO:
{
double energy;
int enemy;
cin >> energy >> enemy;
robot_info( energy, enemy );
}
break;
case ROTATION_REACHED:
{
int what;
cin >> what;
rotation_reached( what );
}
break;
case ENERGY:
{
double en;
cin >> en;
energy( en );
}
break;
case ROBOTS_LEFT:
{
int nr;
cin >> nr;
robots_left( nr );
}
break;
case COLLISION:
{
int object;
double angle;
cin >> object >> angle;
switch( object )
{
case NOOBJECT:
collision_noobject( angle );
break;
case ROBOT:
collision_robot( angle );
break;
case WALL:
collision_wall( angle );
break;
case SHOT:
collision_shot( angle );
break;
case COOKIE:
collision_cookie( angle );
break;
case MINE:
collision_mine( angle );
break;
default:
cout << "Print " << _("Collided with Unknown Object!") << endl;
break;
}
}
break;
case WARNING:
{
int type;
char text[81];
cin >> type;
cin.getline(text,80,'\n');
warning( type, text );
}
break;
case DEAD:
dead();
break;
case GAME_FINISHES:
game_finishes();
break;
case EXIT_ROBOT:
exit_robot();
break;
default:
break;
}
}
}
サーバからのメッセージを受けて、対応するメソッドを呼び出す。
class RotateAndFire :public Robo
{
public:
RotateAndFire (const char* name, const char* colour);
// ~RotateAndFire ();
void game_starts ();
// These functions are called when the robot gets a message
// of the corresponding type. There are several radar and
// collision functions. These functions corresponds to each
// object that the robot has collided with or found with the radar.
void radar_robot ( const double dist, const double angle );
void radar_shot ( const double dist, const double angle );
...
実装するメソッドだけ、プロトタイプを記述する。 なにもする必要のないメッセージは親クラス Robo で既になにもしないと 定義されているのでここでは記入しない。
RotateAndFire::RotateAndFire (const char* name, const char* colour)
:Robo (name, colour)
{}
コンストラクタでは親クラス Robo のコンストラクタに名前と色が伝わるよう に指定する。
void
RotateAndFire::radar_robot( const double dist, const double angle )
{
if( radar_and_cannon_rotate != - robot_rotate )
{
radar_and_cannon_rotate = - robot_rotate;
rotate( 6, radar_and_cannon_rotate );
}
if( dist < 2 && acceleration != 0.0 )
{
acceleration = 0.0;
accelerate( acceleration );
brake_value = 1.0;
brake( brake_value );
if( debug_level >= 1 )
std::cout << "Debug "<< _("Brakes locked: Robot found and at distance")
<< " " << dist << std::endl;
}
shoot( 2 );
}
レーダに弾が映った時呼び出されるメソッド。
#include "robo.h"
#include "raf.h"
必要なヘッダファイルを記述する
int
main(int argc, char * argv[])
{
class Robo *raf_obj= new RotateAndFire("Rotate&Fire(new)", "9977dd");
raf_obj->robot_option( USE_NON_BLOCKING, false );
raf_obj->check_messages();
return(0);
}
オブジェクトをコンストラクタで生成したあとは、オプションを指定して
check_message()
メソッドを呼び出すだけである。
raf.robot: robo.o raf.o main.o
$(CXX) -o $@ $^
robo.o: robo.h
robo.o: Messagetypes.h
robo.o: IntlDefs.h
raf.o: raf.h robo.h
raf.o: IntlDefs.h
main.o: raf.h robo.h
#include <cstdlib>
をしてみる。#define rint(arg) ((int)(arg))
と定義する。#include <cstring>
を加え、さらにエラーが出るよ
うだったら、 using std::str(該当関数);
を付け加える。
# define M_PI 3.14159265358979323846
など適
当な精度で定義する。