///////////////////////// rp.slt - russian pusher //////////////////////////
//
// - Written.....: by Insight corp.
// - Date........: 09/04/91 02:24am
// - Subject.....: программа продолжает славную серию реализаций игрушки
// Soko-Ban на различных языках программирования,
// представляя язык SALT телекоммуникационного пакета Telix...
// - Compile line: cs rp
// ------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
int f_esc = 0x001b,
f_restart = 0x0020;
int f_left = 0x4b00,
f_right = 0x4d00,
f_up = 0x4800,
f_down = 0x5000;
// 15 + (16 * 04) -- белым по красному
int game_color = 0x4f;
int c_cntrl_bit = 0x80,
c_bit_mask = 0x7f;
int s_free_place, s_man, s_wall, s_box,
sb_free_place, sb_man, sb_wall, sb_box;
// 30 * 13 = 390
str maze[ 390 ]; // фактически - локальная переменная, но ограничение
// длины локальных переменных до 255 символов
// вынуждает вынести ее на глобальное место
str game_field[ 390 ]; // массив содержит рабочий массив игрушки
int man_x, man_y, // координаты двигателя
score_all, score_new, // переменные содержат счетчики очков
kbrd_key; // введенный символ
//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\
main()
{
int work_frame;
// фактически - инициализация констант, но невозможность
// использовать при инициализации выражения вынуждает
// инициировать эти константы здесь
s_free_place = 0; sb_free_place = c_cntrl_bit + s_free_place;
s_man = 1; sb_man = c_cntrl_bit + s_man;
s_wall = 9; sb_wall = c_cntrl_bit + s_wall;
s_box = 4; sb_box = c_cntrl_bit + s_box;
cursor_onoff ( 0 );
work_frame = vsavearea ( 5, 4, 70, 20 );
box ( 5, 4, 70, 20, 2, 0, game_color );
alarm ( 1 );
pstraxy ( "(c) Insight corp., 1991", 25, 16, game_color );
pstraxy ( "Init iNit inIt iniT....", 25, 18, game_color );
maze_init ();
pstraxy ( "Moving Up/Down/Left/Right : Finish Esc/Space",
18, 18, game_color );
alarm ( 1 );
game_round ();
pstraxy ( " " ,
18, 18, game_color );
gotoxy ( 28, 18 );
if ( score_new == score_all )
pstra ( "*** маладец! ***", game_color );
else
pstra ( "*** слаб-ба-к ***", game_color );
alarm ( 1 );
kbrd_key = inkeyw ();
vrstrarea ( work_frame );
cursor_onoff ( 1 );
}
//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\
//------------------//----------------------//-------------------//--------//
// -------- функции сконструированные для работы с массивами -----------
// выбрать элемент из массива array по координате [colunm, row]
item_from_array ( str array, int column, int row )
{
return ( subchr ( array, row*30+column ) );
}
// поместить данное item в массив array по координате [column, row]
item_to_array ( str array, int column, int row, int item )
{
setchr ( array, row*30+column, item );
}
//------------------//----------------------//-------------------//--------//
// функция выводит на экран изображение спрайта
sprite_out ( int sprite_type )
{
if ( sprite_type == s_free_place )
pstra ( " ", game_color );
else if ( sprite_type == sb_free_place )
pstra ( ". ", game_color );
else if ( (sprite_type == s_man) or (sprite_type == sb_man) )
pstra ( "><", game_color );
else if ( (sprite_type == s_wall) or (sprite_type == sb_wall) )
pstra ( "^178^178", game_color );
else if ( sprite_type == s_box )
pstra ( "<>", game_color );
else if ( sprite_type == sb_box )
pstra ( "^017^016", game_color );
}
//------------------//----------------------//-------------------//--------//
//
sprite_show ( int sprite_x, int sprite_y, int sprite_type )
{
if ( item_from_array ( game_field, sprite_x, sprite_y ) == sb_box )
if ( sprite_type != s_box )
--score_new;
if ( (item_from_array ( game_field, sprite_x, sprite_y )
& c_cntrl_bit ) != 0 )
if (sprite_type == s_box )
++score_new;
item_to_array ( game_field, sprite_x, sprite_y ,
(item_from_array( game_field, sprite_x, sprite_y) & c_cntrl_bit)
| (sprite_type) );
// 5+3, 4+1 - смещения в home при выводе в окнышко
gotoxy ( 5+3 + sprite_x*2, 4+1 + sprite_y );
sprite_out ( item_from_array (game_field, sprite_x, sprite_y ));
}
//------------------//----------------------//-------------------//--------//
//
maze_init ()
{
int i, j, crnt_char;
// 0 1 2 3
// 1234567890123456789012345678901
maze = "000000000000000000000000000000" ;
strcat ( maze, "000000099999000000000000000000" );
strcat ( maze, "000000090009000000000000000000" );
strcat ( maze, "000000094009000000000000000000" );
strcat ( maze, "000009990049990000000000000000" );
strcat ( maze, "000009004004090000000000000000" );
strcat ( maze, "000999090999090000099999900000" );
strcat ( maze, "000900090999099999990033900000" );
strcat ( maze, "000904004000000000000033900000" );
strcat ( maze, "000999990999909199990033900000" );
strcat ( maze, "000000090000009990099999900000" );
strcat ( maze, "000000099999999000000000000000" );
strcat ( maze, "000000000000000000000000000000" );
// ---------------------------------- считывание лабиринта--------
score_all = 0;
score_new = 0;
for ( i = 0; i < 13; ++i )
for ( j = 0; j < 30; ++j )
{
item_to_array ( game_field, j, i, 0 );
// сначала избавимся от мусора...
crnt_char = item_from_array ( maze, j, i );
// а теперь - от необходимости повторять правое выражение в
// в каждом if-е
if ( crnt_char == ь0ь )
sprite_show ( j, i, s_free_place );
else if (crnt_char == ь9ь)
sprite_show ( j, i, s_wall );
else if (crnt_char == ь4ь)
sprite_show ( j, i, s_box );
else if (crnt_char == ь3ь)
{
sprite_show ( j, i, sb_free_place );
++score_all;
}
else if (crnt_char == ь7ь)
{
sprite_show ( j, i, sb_box );
++score_all;
++score_new;
}
else if (crnt_char == ь1ь)
{
sprite_show ( j, i, s_man );
man_x = j;
man_y = i;
}
else if (crnt_char == ь2ь)
{
sprite_show ( j, i, sb_man );
man_x = j;
man_y = i;
++score_all;
}
else
sprite_show ( j, i, s_free_place );
}
}
//------------------//----------------------//-------------------//--------//
//
moving ( int dlt_x, int dlt_y )
{
// а вот здесь обратим внимание на наличие скобок в выражениях
// (SALT - это тот самый язык, где лишняя пара скобок не
// повредит (sic! rules of precedence (то бишь, правила
// предшествования)))
// свободно ли следующее поле?
if ( (item_from_array( game_field, man_x+dlt_x, man_y+dlt_y)
& c_bit_mask) == s_free_place )
// перемещение двигателя на следующее поле
{
man_x = man_x + dlt_x;
man_y = man_y + dlt_y;
}
else
// проверим, может это - ящик?
if ( (item_from_array ( game_field, man_x+dlt_x, man_y+dlt_y)
& c_bit_mask) == s_box )
// свободно ли поле за ящиком?
if ( (item_from_array( game_field, man_x+(dlt_x*2),
man_y+(dlt_y*2)) & c_bit_mask) == s_free_place )
// переместим ящик и двигателя на поле в данном направлении
{
sprite_show ( man_x+dlt_x, man_y+dlt_y, s_free_place );
sprite_show ( man_x+(dlt_x*2), man_y+(dlt_y*2), s_box );
man_x = man_x + dlt_x;
man_y = man_y + dlt_y;
}
}
//------------------//----------------------//-------------------//--------//
//
game_round ()
{
do {
sprite_show ( man_x, man_y, s_man );
kbrd_key = inkeyw ();
sprite_show ( man_x, man_y, s_free_place );
if ( kbrd_key == f_left )
moving ( -1, 0 );
else if (kbrd_key == f_right)
moving ( 1, 0 );
else if (kbrd_key == f_up)
moving ( 0, -1 );
else if (kbrd_key == f_down)
moving ( 0, 1 );
} while ( !( (score_new == score_all) or
(kbrd_key == f_esc) or
(kbrd_key == f_restart) ) );
}
//////////////////////////// the end ////////////////////////////////////////