ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 10) онлайн
Разработка лошадиных скачек
Как мы можем применить ООП для пашей программы? Первый вопрос заключа- ется в том, существует ли в нашей программе группа похожих объектов, с которы- ми мы будем работать? Ответ положительный, это лошади. Кажется разумным представить каждую лошадь как объект. Мы создадим класс horse, в котором будут содержаться данные для каждой из лошадей, такие, как ее номер и дистан- ция, на которой эта лошадь была самой быстрой.
Однако у нас есть еще данные, которые имеют отношение к маршруту ска- чек. Они включают в себя длину дистанции, время, затраченное на ее прохожде- ние в минутах и секундах (0:00 на старте), и общее количество лошадей. Поэто- му имеет смысл создать объект, который будет одиночным членом класса track. На ум приходят и другие объекты, которые ассоциируются с лошадиными скач- ками, например жокеи или конюхи, но они не будут использоваться в нашей программе.
Существуют ли другие способы разработки программы? Например, исполь- зование наследования для того, чтобы сделать класс horse производным класса track? В нашем случае это не имеет смысла, так как лошади не являются чем-то, имеющим отношение к дистанции скачек; это совсем разные вещи. Другая воз- можность — переделать данные дистанции в статические данные класса horse. Однако обычно лучше использовать отдельный класс для каждой предметной области. Это выгоднее, так как позволяет упростить использования классов
для других целей, например при использовании класса track в автомобильных гонках.
Как же будут взаимодействовать объекты классов track и horse? (Или, в терми- нах UML, в чем состоит их связь?) Массив указателей на объекты класса horse может быть членом класса track, при этом track сможет иметь доступ к horse через эти указатели. При создании track будут созданы и horse. Track передаст каждому объекту класса horse указатель на себя, и они смогут иметь к нему доступ. Вот листинг программы HORSE:
// horse.cpp
// модель лошадиных скачек
#include "msoftcon.h" //for console graphics
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
const int CPF = 5;
const int maxHorses = 7;
class track;
///////////////////////////////////////////////////////////
class horse
{
private:
const track* ptrTrack;
const int horse_number;
float finish_time;
float distance_run;
public:
horse ( const int n, const track* ptrT ) :
horse_number ( n ),
ptrTrack ( ptrT ),
distance_run ( 0.0 )
{ }
~horse ( )
{ }
void display_horse ( const float elapsed_time );
};
///////////////////////////////////////////////////////////
class track
{
private:
horse* hArray [ maxHorses ];
int total_horses;
int horse_count;
const float track_length;
float elapsed_time;
public:
track ( float lenT, int nH );
~track ( );
void display_track ( );
void run ( );
float get_track_len ( ) const;
};
///////////////////////////////////////////////////////////
void horse::display_horse ( float elapsed_time ) {
set_cursor_pos ( 1 + int ( distance_run * CPF ), 2 + horse_number * 2 );
set_color ( static_cast<color>( cBLUE + horse_number ) );
char horse_char = '0' + static_cast<char>( horse_number );
putch ( ' ' ); putch ( '\xDB' ); putch ( horse_char ); putch ( '\xDB' );
if ( distance_run < ptrTrack->get_track_len ( ) + 1.0 / CPF )
{
if ( rand ( ) % 3 )
distance_run += 0.2F;
finish_time = elapsed_time;
}
else
{
int mins = int(finish_time)/60;
int secs = int(finish_time) - mins*60;
cout << " Время =" << mins << ":" << secs; }
}
///////////////////////////////////////////////////////////
track::track ( float lenT, int nH ) :
track_length ( lenT ),
total_horses ( nH ),
horse_count ( 0 ),
elapsed_time ( 0.0 )
{
init_graphics ( );
total_horses = ( total_horses > maxHorses ) ? maxHorses : total_horses;
for ( int j = 0; j < total_horses; j++ )
hArray [ j ] = new horse ( horse_count++, this );
time_t aTime;
srand ( static_cast<unsigned>( time ( &aTime ) ) );
display_track ( );
}
///////////////////////////////////////////////////////////
track::~track ( )
{
for ( int j = 0; j < total_horses; j++ )
delete hArray [ j ];
}
///////////////////////////////////////////////////////////
void track::display_track ( )
{
clear_screen ( );
for ( int f = 0; f <= track_length; f++ )
for ( int r = 1; r <= total_horses * 2 + 1; r++ )
{
set_cursor_pos ( f * CPF + 5, r );
if ( f == 0 || f == track_length )
cout << '\xDE';
else
cout << '\xB3';
}
}
///////////////////////////////////////////////////////////
void track::run ( )
{
while ( !kbhit ( ) )
{
elapsed_time += 1.75;
for ( int j = 0; j < total_horses; j++ )
hArray [ j ]->display_horse ( elapsed_time );
wait ( 500 );
}
getch ( );
cout << endl;
}
///////////////////////////////////////////////////////////
float track::get_track_len ( ) const
{ return track_length; }
///////////////////////////////////////////////////////////
int main ( )
{
float length;
int total;
cout << "\nВведите длину дистанции (от 1 до 12): ";
cin >> length;
cout << "\nВведите количество лошадей (от 1 до 7): ";
cin >> total;
track theTrack ( length, total );
theTrack.run ( );
return 0;
}
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
