StateFlow   ОКМ   ДМ   экономическая информатика   визуальные среды - 4GL   Теория и практика обработки информации

Cистема численно-математического моделирования MatLab

Обзор примера игры Tetris Stateflow

Объявленные переменные :

Name

Type

Dim.

Знач.

Вид.

Описание

1

Grid

Int8

20 60

-

local

Переменная хранит размеры игрового поля

2

GridH

Int32

-

60

local

Высота игрового поля

3

GridW

Int32

-

20

local

Ширина игрового поля

4

Shapes

Int32

6

-

local

Массив для хранения 6-ти фигур

5

S1

Int32

-

0x202222

local

Геометрия и цвет фигуры 1

6

S2

Int32

-

0x3044c0

local

Геометрия и цвет фигуры 2

7

S3

Int32

-

0x150360

local

Геометрия и цвет фигуры 3

8

S4

Int32

-

0x250c60

local

Геометрия и цвет фигуры 4

9

S5

Int32

-

0x3504e0

local

Геометрия и цвет фигуры 5

10

S6

Int32

-

0x170223

local

Геометрия и цвет фигуры 6

12

nS

Int32

-

-

local

Геометрия и цвет фигуры после переворота

13

s

Int32

-

-

local

Геометрия и цвет активной фигуры

14

x

Int32

-

-

local

Положение фигуры по оси х

15

y

Int32

-

-

local

Положение фигуры по оси y

16

nx

Int32

-

-

local

Возможное положение фигуры по оси х

17

ny

Int32

-

-

local

Возможное положение фигуры по оси y

18

delay

double

-

-

local

Длительность задержки

19

Level

Int32

-

-

local

Уровень

20

Offscreen

Int32

-

-

local

Количество точек фигуры находящ. вне. ИП

21

Score

Int32

-

-

local

Счёт

22

t

double

-

-

local

Для орг. Задержки

23

tOld

double

-

-

local

Для орг. Задержки

24

ClearedRows

Int32

-

-

local

Количество полностью заполненных строк

Объявленные процедуры и функции :

Объявление

Переменные

Краткое описание

1

Num:=Clear_rows()

#

Name

Type

Visibility

1

Num

double

Output

2

X

Int32

Temporary

3

Y

Int32

Temporary

Функция удаляет полностью заполненных строки - возвращает их количество

2

c = get(x,y)

#

Name

Type

Visibility

1

C

Int32

Out

2

X

Int32

Input

3

Y

Int32

Input

Функция возвращает значение Grid[x][y]

3

r = okay(x,y,s)

#

Name

Type

Visibility

1

r

Bool

Output

2

x

Int32

Input

3

y

Int32

Input

4

s

Int32

Input

5

i

Int32

Temporary

6

dy

Int32

Temporary

7

dx

Int32

Temporary

Функция проверяет может ли фигура S перемещена в координату x,y

4

ns = rot(s,right)

#

Name

Type

Visibility

1

ns

Int32

Output

2

right

Bool

Input

3

s

Int32

Input

4

nx

Int32

Temporary

5

ny

Int32

Temporary

6

i

Int32

Temporary

7

x

Int32

Temporary

8

y

Int32

Temporary

Функция производит вращение фигуры S в одном из направлений

5

e = set(x,y,c)

#

Name

Type

Visibility

1

e

Int32

Output

2

c

Int32

Input

3

x

Int32

Input

4

y

Int32

Input

Устанавливает новое значение Grid[x][y]

И Image.Cdata[x,y]

6

e = show(x,y,s,c)

#

Name

Type

Visibility

1

e

Int32

Output

2

c

Int32

Input

3

s

Int32

Input

4

x

Int32

Input

5

y

Int32

Input

6

i

Int32

Temporary

7

dx

Int32

Temporary

8

dy

Int32

Temporary

Обрисовывает фигуру на игровом поле

Объявленные блоки :

Имя

Инструкции

Описание

1

A

entry: ml.sf_tetris_gui("paint",level,score);

exit: t = ml.cputime();

Блок отправляет GUI API параметры текущего уровня и счёт на отрисовку

2

P

-

Пустой блок предназначен для установки игры в режим <пауза> и выхода из него

3

Q

entry:

ml.sf_tetris_gui('gameover');

QuitOut;

Блок завершения игры. GUI API отрисовывает , Simulink модель получает команду завершения процесса симуляции

Объявленные события :

Имя

Тип

Триггер

Порт

Описание

1

Ticks

Input

Either

9

Посылает импульсы каждые 2 секунды

2

Left

Input

Either

1

Переместить фигуры влево

3

Right

Input

Either

2

Переместить фигуры вправо

4

Restart

Input

Either

7

Начать заново

5

RotLeft

Input

Either

3

Повернуть фигуру против часовой стрелки

6

RotRight

Input

Either

4

Повернуть фигуру по часовой стрелки

7

Pause

Input

Either

5

Приостановить

5

Drop

Input

Either

8

Кинуть фигуру

6

Quit

Input

Either edge

6

Выйти

7

QuitOut

Out

1

Остановка симуляции

Общие положения.

В качестве основы пользовательского интерфейса игры Tetris была выбран модуль

в качестве формы.

На котором размещены компоненты : "Image" и 2 компонента "Text"

"Image" используется в качестве игрового поля .

Один из "Text" применяется для вывода информации о состоянии игрового процесса : счёт и уровень ,

другой "Text" для вывода сообщения об окончании игры (Game over).

Игровое поле "Image" имеет свойство "Cdata" - двумерный массив целых чисел , размерностью 60х20 . Он и используется в алгоритмах для отображения , хранения и оперирования фигурами.

Фигура. Всего используемых фигур в игре шесть . Фигура является объектом над которым предусмотрены следующие действия : Перемещение по Х и Y , вращение по часовой и против часовой стрелки. Фигура в программе это 22 битное двоичное число , где в последних 16-ти битах

закодирована геометрия фигуры , а в оставшихся её цвет . Ниже приведены подробная расшифровка фигуры S1 , для остальных 5 фигур всё аналогично

Фигура S1

Hex код фигуры : 0x202222 в двоичной форме [100000][0010][0010][0010][0010]

Цвет : 6 бит

Фигура 16 бит (4х4)

1 строка

2 строка

3 строка

4 строка

Номера битов

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

1

0

0

0

0

0

0

0

1

0

0

0

1

0

0

0

1

0

0

0

1

0

Правило построения фигуры :

0

1

0

0

Строка № 4

0

1

0

0

Строка № 3

0

1

0

0

Строка № 2

0

1

0

0

Строка № 1



Фигура S2

Hex код фигуры : 0x3044C0

Двоичная форма : 110000 0100010011000000

Код цвета : 110000 = 48

0

0

0

0

0

0

1

1

0

0

1

0

0

0

1

0

Фигура S3

Hex код фигуры : 0x150360

Двоичная форма : 010101 0000001101100000

Код цвета : 010101 = 21

0

0

0

0

0

1

1

0

1

1

0

0

0

0

0

0

Фигура S4

Hex код фигуры : 0x250c60

Двоичная форма : 100101 0000110001100000

Код цвета : 100101= 37

0

0

0

0

0

1

1

0

0

0

1

1

0

0

0

0

Фигура S5

Hex код фигуры : 0x3504e0

Двоичная форма : 110101 0000010011100000

Код цвета : 110101= 53

0

0

0

0

0

1

1

1

0

0

1

0

0

0

0

0

Фигура S6

Hex код фигуры : 0x170223

Двоичная форма : 010111 0000001000100011

Код цвета : 010111 = 23

1

1

0

0

0

1

0

0

0

1

0

0

0

0

0

0

Алгоритм

При инициализации :

{ ml.sf_tetris_gui("init",gridH,gridW);

x = gridW / 2;

y = -2;

delay = .1; // Задержку устанавливаем в 100 миллисекунд

clearedRows = 0;

tOld = 0;

t= 0;

s = shapes[0];

grid = 0; // 60x20 заполняем нулями

level = 0;

score = 0; }

Вызывается функция "init" расположенная в m файле sf_tetris_gui.m , закомментируем основные её действия

switch operation
case 'init',

data = zeros(varargin{1},varargin{2}); // Массив 60x20 заполняется нулями , игровое поле пусто

if ishandle(img) // Если переменная img уже связана и объектом "Image" то ( был Restart )
    set(img,'CData',data); //Свойству CDataобъекта Image присваиваем Массив 60x20
else
    fig = figure('Name','Tetris', ...
        'KeyPressFcn', 'sf_tetris_gui keypress;', ... 
        'DoubleBuffer', 'on'); 
       
     oldUnits = get(fig,'Units');
        
     set(fig,'Units','normalized');
     ratioXY = double(varargin{2})/double(varargin{1});
           
     height = 0.75;
     width = ratioXY * height;
     left = (1 - width) / 2;
     top = (1 - height)/ 2;
     set(fig,'Position',[left top width height]);
     set(fig,'Units',oldUnits);
   

     img = image(data);

     axis = get(img,'Parent');
        
     titleText = get(axis,'Title');
     set(titleText,'fontWeight','bold');
        
     set(axis,'DataAspectRatio',[1 1 1],...
         'XTick',[],'YTick',[]);        
 end
  
 if ~isempty(gameoverTxt) && ishandle(gameoverTxt)
     set(gameoverTxt,'Visible','off');
 end
  

Далее переменной S присваивается фигура под номером 1 .
После этого переходим в блок A
При входе в блок вызывается функция :
ml.sf_tetris_gui("paint",level,score);
Её задачи : обновить состояние счёта , уровня и для объекта image обновить свойство Cdata.

Её код :

case 'paint',  
    if ishandle(img)
        switch mod(varargin{1},3) 
            case 0, colorMap = jet;
            case 1, colorMap = hot;
            case 2, colorMap = pink;
        end
                
        set(fig,'colormap',colorMap);
        titleText = get(axis,'Title');
        titleString = sprintf('Level %2d Score %10d',double(varargin{1}),double(varargin{2}));
        set(titleText,'String',titleString);
        set(img,'Cdata',data);
    else
        error('Figure has been closed aborting.');
    end

При выходе из блока A в переменную t запишется текущее время . Зная t и tOld был организован таймер , выключение которого происходит при условии t-tOld>=delay или при вызове события Drop

Эта операция делает невидимой фигуру S на время её движения или вращения (очищает занимаемой фигурой клетки игрового поля)

{ offscreen=show(x,y,s,0); Записываем 1 если фигура вне экрана 0 в противном

nx = x; Сохраняем во временных переменных

ny = y;

ns = s; }

Следующий шаг это выбор между событиями

Drop,Left , Right , RotLeft , RotRight , Ticks

Ели игрок вызвал событие Drop То попадаем цикл , который не прекращается до тех пор пока функция Okay возвращает 1 В процессе цикла увеличиваем очки и Координату ny после цикла присваиваем y значение временной переменной ny.

Если было вызвано одно из событий Rotleft , RotRight или Left , Right

Выполняем соответствующие функции После переворота или перемещения вдоль Х проверяем свободно требуемое пространство игрового поля с помощью функции okay , если успех то значения временных переменных nx и ns записываем в текущие x и s

Если игрок не нажимал управляющих кнопок переход произойдёт по событию Ticks

{ny = y + 1} - перемещаем фигуру на клетку ниже {tOld = t} - присваиваем текущей ttOld - для организации задержки. Ели перемещение фигуры в новую координату функцией Okay было разрешено то {y=ny} ,

иначе это значит что фигура достигла препятствие и не может дальше продвигаться.

{ show(x,y,s,s>>16); отрисовываем фигуру на игровом поле

score +=5; прибовляем очки

clearedRows += clear_rows(); - проверяем есть ли полностью заполненные строки .

s = shapes[floor(ml.rand() * 6.0)]; - выбираем фигуру которая будет следующей , случайно

y = -2; - начальные координаты блока фигуры

x = gridW/2; } -//-

Далее если offset больше нуля то это означает что фигура находится вне зоны игрового поля тоесть достигнут предел , переходи в блок Q - остановка симуляции и обрисовка "Game over"

Иначе если число полностью заполненных строк превысило 10 - переходим на новый уровень

{clearedRows = 0; обнуляем достижения

delay *= .75; уменьшаем время задержки на 35 %

level++;} прибавляем уровень

Завершающей операцией итерации является вызов функции show которая отобразит на игровом поле

Фигуре S с координатами X,Y и цветом S>>16 (22-битное число смещённое на 16 разрядов вправо = 6 бит цвета )

Функции.

1. Num:=Clear_rows()

Основные задачи данной функции это :

1. Определить присутствует ли на игровом поле полностью закрашенные строки

2. При наличии закрашенной(ых) строки(к) (за количество отвечает - num) выполнить перерисовку всего игрового поля со смещение на num строк вниз

Алгоритм .

Присваиваем y номер самой нижней строки. Инициализируем num .

До тех пор пока недостигнута строка игрового поля с индексом 1 выполняем y-раз следующие действия. Устанавливаем x в начало строки . До тех пор пока x не превышает длину строки игрового поля проверяем наличие в <строке-кондидате> присутствие не заполненных клеток (нулевых).

Если таковых не найдено во всей строке то увеличиваем num на 1.

Переходим к строке y-1 , и выполняем выше описанную часть. Только на этот раз при условии что num больше нуля переходим не посредственно к перерисовке игрового поля со смещением на num строк в низ.

2. c = get(x,y)

Основная задача данной функции это :

По имеющимся координатам x,y определить число (цвет) хранящийся в ячейке массива Grid.

При выполнении условий : x находится в пределах игрового поля y находится в пределах игрового поля присваиваем "c" содержимое двумерного массива Grid[x][y]

3. r =okay(x,y,s)

Основные задачи данной функции это :

Определить наличие препятствий на пути движения фигуры будь то

А) Движение по вертикали вниз

Б) Движение в обе стороны по горизонтали

В) Вращение по и против часовой стрелки

Как видно из общей схемы данная функция вызывается после каждой операции над фигурой.

Переменные dx и dy это переменные которые передаются в описанную выше функцию get , которая определяет свободная ли ячейка с координатами (x+dx , x+dy) или нет , если место занято (ячейка содержит значение отличное от нуля) то покидаем функцию с нулевым значением.

4. ns =rot(s,right)

Основная задача данной функции это :

Переворот фигуры S по часовой или против часовой стрелки

Операция поворота реализуемая данной функции осуществляется с помощью операций побитного смещения , логических операций AND , все эти манипуляции осуществляются над 16 битным двоичным числом которое описывает геометрию фигуры.

Рассмотрение данных вопросов выходит за рамки данной работы.

5. e =Set(x,y,c)

Основные задачи данной функции это :

1. Определить находится какая-либо часть фигуры вне зоны игрового поля .

2. Установить в ячейку массива Grid с координатами x,y значение из переменной с (установить цвет)

При условиях что и X и Y находятся в пределах игрового поля , выполняем :

1 . Присваиваем Grid[x][y] значение переменной C

2 . Вызываем M-функцию ml.sf_tetris_gui("set",y,x,c)

её код :

case 'set',

data(varargin{1},varargin{2}) = varargin{3};

** data - это указатель на Cdata.

Это мы проводим для того чтобы обновить значение свойства <Cdata> компонента <Image> , который по сути дела является слепком локальной переменной <Grid>

Если же условия вхождения X,Y в зону видимости не выполняются, то в это случае покидаем функцию и переменной <e> присваиваем 1.

5. e =Show(x,y,s,c)

Основные задачи данной функции это :

1. Записать данную фигуры в массив Grid и свойство Cdata объекта image

2. Определить выходит ли как-либо часть фигуры S за пределы игрового поля

Если абстрактно представить себе фигуру , как она интерпретируется в программе то она будет иметь вид :

Координаты Блока фигуры (X,Y) располагается тут

 

 

0

0

0

0

0

0

1

1

0

0

1

0

0

0

1

0



Локальные координаты точки фигуры внутри блока фигуры :                          (dx,dy)

Рассмотрим более подробно эту функцию
В качестве параметра мы получаем x,y - координаты фигуры.

Глобальная координата точки фигуры получается из выражения (x+dx,y+dy)
Цикл продолжается пока верно условие i<16
В этом цикле мы перемещаемся по всем 16 клеткам блока фигуры сверху вниз , слева направо
Путём побитового смещения вправо [(s>>i) & 1] (равен ли младший бит смещённого на i-бит вправо слова s единице (операция логического AND) ).
И там где клетка содержит значение 1 выполняем функцию set(x+dx,y+dy,c)

StateFlow   ОКМ   ДМ   экономическая информатика   визуальные среды - 4GL   Теория и практика обработки информации

(время поиска примерно 20 секунд)


Знаете ли Вы, в чем фокус эксперимента Майкельсона?

Эксперимент А. Майкельсона, Майкельсона - Морли - действительно является цирковым фокусом, загипнотизировавшим физиков на 120 лет.

Дело в том, что в его постановке и выводах произведена подмена, аналогичная подмене в школьной шуточной задачке на сообразительность, в которой спрашивается:
- Cколько яблок на березе, если на одной ветке их 5, на другой ветке - 10 и так далее
При этом внимание учеников намеренно отвлекается от того основополагающего факта, что на березе яблоки не растут, в принципе.

В эксперименте Майкельсона ставится вопрос о движении эфира относительно покоящегося в лабораторной системе интерферометра. Однако, если мы ищем эфир, как базовую материю, из которой состоит всё вещество интерферометра, лаборатории, да и Земли в целом, то, естественно, эфир тоже будет неподвижен, так как земное вещество есть всего навсего определенным образом структурированный эфир, и никак не может двигаться относительно самого себя.

Удивительно, что этот цирковой трюк овладел на 120 лет умами физиков на полном серьезе, хотя его прототипы есть в сказках-небылицах всех народов всех времен, включая барона Мюнхаузена, вытащившего себя за волосы из болота, и призванных показать детям возможные жульничества и тем защитить их во взрослой жизни. Подробнее читайте в FAQ по эфирной физике.

НОВОСТИ ФОРУМА

Форум Рыцари теории эфира


Рыцари теории эфира
 09.08.2020 - 18:30: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Андрея Фурсова - Карим_Хайдаров.
09.08.2020 - 18:29: ЭКОНОМИКА И ФИНАНСЫ - Economy and Finances -> ПРОБЛЕМА КРИМИНАЛИЗАЦИИ ЭКОНОМИКИ - Карим_Хайдаров.
09.08.2020 - 14:05: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от схиигумена Сергия (Николая Романова) - Карим_Хайдаров.
09.08.2020 - 04:38: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ЗА НАМИ БЛЮДЯТ - Карим_Хайдаров.
08.08.2020 - 18:15: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ПРАВОСУДИЯ.НЕТ - Карим_Хайдаров.
08.08.2020 - 18:12: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Пламена Паскова - Карим_Хайдаров.
08.08.2020 - 17:06: ЭКОЛОГИЯ - Ecology -> Биологическая безопасность населения - Карим_Хайдаров.
08.08.2020 - 14:37: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> РАСЧЕЛОВЕЧИВАНИЕ ЧЕЛОВЕКА. КОМУ ЭТО НАДО? - Карим_Хайдаров.
08.08.2020 - 06:18: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
07.08.2020 - 17:15: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
07.08.2020 - 17:15: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Владимира Николаевича Боглаева - Карим_Хайдаров.
07.08.2020 - 13:57: ТЕОРЕТИЗИРОВАНИЕ И МАТЕМАТИЧЕСКОЕ МОДЕЛИРОВАНИЕ - Theorizing and Mathematical Design -> ФУТУРОЛОГИЯ - прогнозы на будущее - Карим_Хайдаров.

Боровское исследовательское учреждение - Bourabai Research Bourabai Research Institution