Это программа в общее пользование
Code:
REPORT ZTETRIS NO STANDARD PAGE HEADING.
include <icon>.
* логический тип
types:
TBool type c.
constants:
true type TBool value 'X',
false type TBool value space.
* поле
data:
C_FIELD_WIDTH type i,
C_FIELD_HEIGHT type i.
C_FIELD_WIDTH = 15.
C_FIELD_HEIGHT = sy-srows / 2.
types:
begin of TCell,
X type i,
Y type i,
content(4) type c,
end of TCell.
data:
g_t_cell type hashed table of TCell
with unique key Y X.
* поле для сброса
types:
TTCell type table of TCell with default key,
TTRow type table of TTCell.
* фигуры
constants:
C_NUM_FIGURES type i value 7.
types:
begin of TPos,
X type i,
Y type i,
end of TPos,
TTPos type table of TPos with default key,
begin of TFigure,
fig_num type i,
rot_num type i,
t_pos type TTPos,
end of TFigure,
TTFigure type hashed table of TFigure
with unique key fig_num rot_num.
data:
g_t_figure type TTFigure,
begin of g_act_figure,
fig_num type i,
rot_num type i,
X type i,
Y type i,
end of g_act_figure.
* заствака
perform show_top_users.
return.
* очки
data:
g_score type i,
g_speed type i,
g_is_game_over type TBool.
*ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ
*
* процесс...
*
*ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ
form process.
g_speed = 500.
perform init_figures.
perform init_field.
perform init_field_figure.
perform redraw.
call function 'ZDELAY'
starting new task 'TETRIS'
performing return_info on end of task
exporting
p_milsec = g_speed
exceptions
others = 1.
endform.
*ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ
*
* движение...
*
*ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ
* асинхронный вызов
form return_info using taskname.
receive results from function 'ZDELAY'
exceptions
others = 1.
set user-command 'MOVE'.
endform.
* движение
at user-command.
if sy-ucomm = 'MOVE'.
data:
v_old_figure like g_act_figure,
v_new_figure like g_act_figure.
v_old_figure = v_new_figure = g_act_figure.
v_new_figure-Y = v_new_figure-Y + 1.
perform move_figure
using
v_old_figure
v_new_figure
true.
if sy-subrc <> 0.
perform check_field.
perform init_field_figure.
if sy-subrc <> 0.
perform game_over.
else.
perform redraw.
call function 'ZDELAY'
starting new task 'TETRIS'
performing return_info on end of task
exporting
p_milsec = g_speed
exceptions
others = 1.
endif.
endif.
endif.
* перевернуть фигуру
at pf7.
if g_is_game_over = true or g_speed = 0.
exit.
endif.
v_old_figure = v_new_figure = g_act_figure.
if v_new_figure-rot_num = 4.
clear v_new_figure-rot_num.
endif.
v_new_figure-rot_num = v_new_figure-rot_num + 1.
perform move_figure
using
v_old_figure
v_new_figure
false.
* сдвинуть фигуру влево
at pf6.
if g_is_game_over = true or g_speed = 0.
exit.
endif.
v_old_figure = v_new_figure = g_act_figure.
v_new_figure-X = v_new_figure-X - 1.
perform move_figure
using
v_old_figure
v_new_figure
false.
* сдвинуть фигуру вправо
at pf8.
if g_is_game_over = true or g_speed = 0.
exit.
endif.
v_old_figure = v_new_figure = g_act_figure.
v_new_figure-X = v_new_figure-X + 1.
perform move_figure
using
v_old_figure
v_new_figure
false.
* бросить вниз
at pf5.
if g_is_game_over = true or g_speed = 0.
exit.
endif.
do.
v_old_figure = v_new_figure = g_act_figure.
v_new_figure-Y = v_new_figure-Y + 1.
perform move_figure
using
v_old_figure
v_new_figure
false.
if sy-subrc <> 0.
perform check_field.
perform init_field_figure.
perform redraw.
call function 'ZDELAY'
starting new task 'TETRIS'
performing return_info on end of task
exporting
p_milsec = g_speed
exceptions
others = 1.
exit.
endif.
enddo.
* сдвинуть фигуру
* {
* sy-subrc = 0 - успешно
* }
form move_figure
using
p_old_figure like g_act_figure
p_new_figure like g_act_figure
p_do_more type TBool.
clear sy-lsind.
perform set_field_figure
using
space
false.
g_act_figure = p_new_figure.
perform set_field_figure
using
ICON_STATUS_BEST
true.
if sy-subrc = 0.
perform set_field_figure
using
ICON_STATUS_BEST
false.
perform redraw.
if p_do_more = true.
call function 'ZDELAY'
starting new task 'TETRIS'
performing return_info on end of task
exporting
p_milsec = g_speed
exceptions
others = 1.
endif.
clear sy-subrc.
else.
g_act_figure = p_old_figure.
perform set_field_figure
using
ICON_STATUS_BEST
false.
sy-subrc = 1.
endif.
endform.
* проверить поле и сбросить строки
form check_field.
* копируем во временную таблицу
data:
v_t_row type TTRow,
v_cell like line of g_t_cell[].
do C_FIELD_HEIGHT times.
v_cell-Y = sy-index.
field-symbols:
<row> like line of v_t_row[].
append initial line to v_t_row assigning <row>.
do C_FIELD_WIDTH times.
v_cell-X = sy-index.
field-symbols:
<cell> like line of g_t_cell[].
read table g_t_cell
with table key
Y = v_cell-Y
X = v_cell-X
assigning
<cell>.
append <cell> to <row>.
enddo.
enddo.
* удаляем заполненные строки
loop at v_t_row assigning <row>.
data:
v_row_num type i.
v_row_num = sy-tabix.
loop at <row> assigning <cell>.
if sy-tabix = 1.
continue.
endif.
if <cell>-content <> ICON_STATUS_BEST.
exit.
endif.
endloop.
if <cell>-X = C_FIELD_WIDTH.
delete v_t_row index v_row_num.
endif.
endloop.
* удаляем заполненные строки
v_row_num = C_FIELD_HEIGHT - lines( v_t_row ).
data:
v_row like <row>.
do C_FIELD_WIDTH times.
v_cell-X = sy-index.
if v_cell-X = 1 or v_cell-X = C_FIELD_WIDTH.
v_cell-content = ICON_OO_CLASS.
else.
v_cell-content = space.
endif.
append v_cell to v_row.
enddo.
do v_row_num times.
insert v_row into v_t_row index 1.
g_score = g_score + 100.
g_speed = g_speed - 2.
enddo.
* переписываем строки в хэш таблицу
loop at v_t_row assigning <row>.
v_row_num = sy-tabix.
loop at <row> assigning <cell>.
field-symbols:
<cell2> like line of g_t_cell[].
read table g_t_cell
with table key
Y = v_row_num
X = sy-tabix
assigning
<cell2>.
<cell2>-content = <cell>-content.
endloop.
endloop.
endform.
*ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ
*
* подпрограммы...
*
*ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ
* подготовить фигуры
form init_figures.
data:
v_figures type string.
define DEF_FIGURE.
concatenate v_figures &1 into v_figures.
end-of-definition.
DEF_FIGURE `0 0 0 -1 0 1 1 1 0 0 -1 0 1 0 1 -1 0 0 0 -1 -1 -1 0 1 0 0 -1 0 1 0 -1 1`.
DEF_FIGURE ` 0 0 0 -1 1 -1 1 0 0 0 0 -1 1 -1 1 0 0 0 0 -1 1 -1 1 0 0 0 0 -1 1 -1 1 0`.
DEF_FIGURE ` 0 0 0 -1 1 0 1 1 0 0 -1 0 0 -1 1 -1 0 0 0 -1 1 0 1 1 0 0 -1 0 0 -1 1 -1`.
DEF_FIGURE ` 0 0 0 -1 0 1 0 2 0 0 -1 0 1 0 2 0 0 0 0 -1 0 1 0 2 0 0 -1 0 1 0 2 0`.
DEF_FIGURE ` 0 0 0 -1 0 1 -1 1 0 0 1 0 -1 0 -1 -1 0 0 0 -1 1 -1 0 1 0 0 -1 0 1 0 1 1`.
DEF_FIGURE ` 0 0 1 0 1 -1 0 1 0 0 -1 0 0 1 1 1 0 0 1 0 1 -1 0 1 0 0 -1 0 0 1 1 1`.
DEF_FIGURE ` 0 0 -1 0 1 0 0 1 0 0 0 -1 0 1 1 0 0 0 -1 0 1 0 0 -1 0 0 0 -1 0 1 -1 0`.
data:
v_t_figure_str type table of string with header line.
split v_figures at space into table v_t_figure_str.
data:
v_figure like line of g_t_figure[],
v_index type i.
field-symbols:
<pos> like line of v_figure-t_pos[].
do C_NUM_FIGURES times.
v_figure-fig_num = sy-index.
clear v_figure-rot_num.
do 4 times.
v_figure-rot_num = sy-index.
refresh v_figure-t_pos[].
do 4 times.
append initial line to v_figure-t_pos assigning <pos>.
v_index = v_index + 1.
read table v_t_figure_str index v_index.
<pos>-X = v_t_figure_str.
v_index = v_index + 1.
read table v_t_figure_str index v_index.
<pos>-Y = v_t_figure_str.
enddo.
insert v_figure into table g_t_figure.
enddo.
enddo.
endform.
* инициировать поле
form init_field.
data:
v_cell like line of g_t_cell[].
do C_FIELD_HEIGHT times.
v_cell-Y = sy-index.
do C_FIELD_WIDTH times.
v_cell-X = sy-index.
if v_cell-X = 1 or v_cell-X = C_FIELD_WIDTH or v_cell-Y = C_FIELD_HEIGHT.
v_cell-content = ICON_OO_CLASS.
else.
v_cell-content = space.
endif.
insert v_cell into table g_t_cell.
enddo.
enddo.
endform.
* разместить фигуру на поле
* {
* sy-subrc = 0 - успешно
* }
form init_field_figure.
data:
v_value type f.
perform get_random_value
changing
v_value.
g_act_figure-fig_num = trunc( v_value * 100 / ( 100 / C_NUM_FIGURES ) ) + 1.
g_act_figure-rot_num = 1.
g_act_figure-X = 7.
g_act_figure-Y = 2.
perform set_field_figure
using
ICON_STATUS_BEST
true.
if sy-subrc = 0.
perform set_field_figure
using
ICON_STATUS_BEST
false.
g_score = g_score + 10.
endif.
endform.
* установить фигуру на поле
* {
* sy-subrc = 0 - успешно
* }
form set_field_figure
using
p_content type TCell-content
p_check type TBool.
field-symbols:
<figure> like line of g_t_figure[].
read table g_t_figure
with table key
fig_num = g_act_figure-fig_num
rot_num = g_act_figure-rot_num
assigning
<figure>.
field-symbols:
<pos> like line of <figure>-t_pos[].
loop at <figure>-t_pos assigning <pos>.
perform set_field_cell
using
g_act_figure-X
g_act_figure-Y
<pos>-X
<pos>-Y
p_content
p_check.
if sy-subrc <> 0.
return.
endif.
endloop.
clear sy-subrc.
endform.
* установить ячейку поля
* {
* sy-subrc = 0 - успешно
* }
form set_field_cell
using
value(p_X) type TCell-X
value(p_Y) type TCell-Y
p_X_offs type TPos-X
p_Y_offs type TPos-Y
p_content type TCell-content
p_check type TBool.
p_X = p_X + p_X_offs.
p_Y = p_Y + p_Y_offs.
field-symbols:
<cell> like line of g_t_cell[].
read table g_t_cell
with table key
Y = p_Y
X = p_X
assigning
<cell>.
if not <cell>-content is initial and not p_content is initial.
sy-subrc = 1.
else.
if p_check = false.
<cell>-content = p_content.
endif.
clear sy-subrc.
endif.
endform.
* перерисовать поле
form redraw.
sy-linno = 1.
data:
v_X type i,
v_Y type i,
v_score_Y type i.
v_score_Y = C_FIELD_HEIGHT / 2 - 1.
do C_FIELD_HEIGHT times.
v_Y = sy-index.
do C_FIELD_WIDTH times.
v_X = sy-index.
field-symbols:
<cell> like line of g_t_cell[].
read table g_t_cell
with table key
Y = v_Y
X = v_X
assigning
<cell>.
if sy-subrc = 0.
data:
v_show_X type i.
v_show_X = v_X * 4.
write at v_show_X <cell>-content.
endif.
enddo.
if v_score_Y = v_Y.
data:
v_score_str type string.
v_score_str = g_score.
condense v_score_str.
concatenate `Очки: ` v_score_str into v_score_str.
data:
v_score_X type i.
v_score_X = C_FIELD_WIDTH * 4 + ( sy-scols - C_FIELD_WIDTH * 4 - ( strlen( ICON_READ_FILE ) + 8 ) ) / 2.
if v_score_X <= C_FIELD_WIDTH.
v_score_X = C_FIELD_WIDTH * 4 + 5.
endif.
write: at v_score_X ICON_READ_FILE as icon, v_score_str.
endif.
write /.
enddo.
endform.
* получить случайное число в диапазоне от 0..1
form get_random_value
changing
p_value type f.
statics:
v_random_seed type i.
constants:
v_s type i value 16807,
v_m(6) type p value 2147483648.
data:
v_ks type string.
if v_random_seed is initial.
v_ks = sy-uzeit.
shift v_ks circular.
shift v_ks circular.
shift v_ks circular.
shift v_ks circular.
v_random_seed = v_ks * v_ks mod ( v_m - 1 ).
endif.
v_random_seed = ( v_random_seed * v_s ) mod ( v_m - 1 ).
p_value = v_random_seed / v_m.
endform.
* показать чемпионов
form show_top_users.
data:
v_t_user type table of ztetuser with header line.
select
*
into table
v_t_user
from
ztetuser.
sort v_t_user by score descending.
loop at v_t_user.
if sy-tabix > 10.
delete v_t_user index sy-tabix.
endif.
endloop.
data:
v_col type i,
v_row type i.
v_row = ( sy-srows - ( lines( v_t_user ) + 14 ) * 2 ) / 2.
do v_row times.
write /.
enddo.
v_col = ( sy-scols - 68 ) / 2 + 33.
write: /, at v_col 'ТЕТРИС', /, /.
v_col = v_col - 33.
v_col = v_col + 17.
write: /,
at v_col ICON_COLUMN_LEFT as icon, '- (F6)',
ICON_MODIFY as icon, '- (F7)',
ICON_COLUMN_RIGHT as icon, '- (F8)',
ICON_PREVIOUS_VALUE as icon, '- (F5)', /, /.
v_col = v_col - 17.
v_col = v_col + 25.
write: /, at v_col 'Список бездельников!'.
write: /, at v_col '--------------------', /.
v_col = v_col - 25.
loop at v_t_user.
data:
v_user type USR03,
v_full_name type string.
v_full_name = sy-tabix.
clear v_user.
CALL FUNCTION 'SUSR_SHOW_USER_DETAILS'
EXPORTING
BNAME = v_t_user-username
NO_DISPLAY = 'X'
CHANGING
USER_USR03 = v_user.
concatenate
v_full_name ` ` v_t_user-username ` (` v_user-name1 ` ` v_user-name2 `)`
into
v_full_name.
write: /, at v_col v_full_name.
v_col = v_col + 60.
write at v_col v_t_user-score.
v_col = v_col - 60.
endloop.
call function 'ZDELAY'
starting new task 'TETRIS0'
performing return_info0 on end of task
exporting
p_milsec = 5000
exceptions
others = 1.
endform.
* задержка
form return_info0 using taskname.
receive results from function 'ZDELAY'
exceptions
others = 1.
perform process.
endform.
* конец игры
form game_over.
g_is_game_over = true.
constants:
C_GAME_OVER type string value 'Конец игры!'.
sy-linno = 1.
data:
v_cnt type i.
v_cnt = sy-srows / 2 - 1.
do v_cnt times.
write /.
enddo.
v_cnt = ( sy-scols - strlen( C_GAME_OVER ) ) / 2.
write at v_cnt C_GAME_OVER.
data:
v_user type ztetuser.
select single
*
into
v_user
from
ztetuser
where
username = sy-uname.
if sy-subrc = 0.
if v_user-score >= g_score.
exit.
endif.
endif.
v_user-username = sy-uname.
v_user-score = g_score.
modify ztetuser from v_user.
endform.
FUNCTION ZDELAY.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" VALUE(P_MILSEC) TYPE I
*"----------------------------------------------------------------------
data:
v_ts type timestampl,
v_ts_new type timestampl,
v_delta type i.
get time stamp field v_ts.
while v_delta <= p_milsec.
get time stamp field v_ts_new.
v_delta = ( v_ts_new - v_ts ) * 1000.
endwhile.
ENDFUNCTION.