﻿<html>
<head>
</head>

<body>
<h1>
Програмиране на Android – практическо ръководство
</h1>

<h3>
инж. Тодор Балабанов
</h3>

<h2>
Институт по информационни и комуникационни технологии
</h2>

<h2>
Българската академия на науките
</h2>

<h2>
София - 2016
</h2>

<hr/>
<h1>
Съдържание
</h1>

<hr/>
<h1>
1. Въведение
</h1>

През първото десетилетие на 21 век, в ежедневния бит на хората масово навлезе използването на мобилни изчислителни устройства, основно под формата на умни телефони и таблети. Наличието на глобални свободни пазари се оказа ключов фактор за развитието на интензивна конкурентна среда. Първите масово разпространени „умни“ устройства бяха предложени от компанията Apple, с операционна система iOS и програмен език Objective-C. В кратки срокове след това бе предложена отворена платформа за развитие на мобилни устройства – Android, за развитието на която основна роля изигра компанията Google, залагайки като програмен език Java. Компанията Microsoft също предложи свое решение, базирано на операционната система Windows Phone, с основен програмен език C#. Трите водещи производителя се различават основно в степента на отвореност, който предлагат за своите системи. В случая на Apple платформата е напълно затворена. В случая на Android стремежът е платформата да бъде напълно отворена. Докато Microsoft заемат относително междинна позиция.

<p/>

В настоящото практическо ръководство ще бъде представен процесът за създаване на програмни продукти за платформата Android. Изборът на тази платформа е основан на идеята за свободен достъп до технологии, а също така и на факта, че производствените разходи за платформата Android са най-ниски. Практическото ръководство е предназначено за читатели със средно или напреднало ниво в областта на програмирането и софтуерното инженерство. Ръководството не е подходящо за читатели, които тепърва навлизат в областта на компютърните науки. 

<p/>

Поради своя практически характер, настоящото ръководство излага минимални теоретични знания и акцентира върху практическите стъпки за създаване и поддръжка на софтуер. Обект на разработката представлява логическа игра, която се играе на дъска. Софтуерният проект е под GPL3 отворен лиценз и може да се достъпи свободно в публичното пространство. 

<hr/>
<h1>
2. Логическата игра за дъска Ithaka
</h1>

Логическата игра Ithaka е публикувана официално през 2002 година от L. Lynn Smith. 

<p/>

<img src="0001.png" width="50%"/><br/>
<b>Фиг. 1</b> Официална страница на логическата игра Ithaka в уеб сайта BoardGameGeek.

<p/>

Играта се играе от двама играчи, на дъска, която е оформена в 4х4 клетки. Върху дъската за разположени пулове в четири различни цвята. Целта на играчите, за да победят, е да формират линия от три едноцветни пула (вертикално, хоризонтално или диагонално).

<p/>

<img src="0226.png" width="50%"/><br/>
<b>Фиг. 2</b> Начална конфигурация на игралното табло.

<p/>

Всеки от играчите може да мести пулове от четирите различни цвята. На всеки ход играчът мести само един пул, по права линия (хоризонтално, вертикално и диагонално) през произволен брой празни клетки. Първото ограничение, при местене на пул е, че не може да се мести последно преместеният пул. Второто ограничение е, че може да се местят само пулове, които имат в съседство пул от същия цвят. Основното условие за победа е да бъде формирана права линия от три пула, от един и същи цвят. Играчът побеждава опонента си и ако постигне конфигурация в която опонентът няма позволен за местене ход. Третото условие за победа е, ако противникът извърши един и същи ход три последователни пъти. 

<p/>

Играта Ithaka има достатъчно опростени правила и поради тази причина е много добър кандидат за реализиране под формата на приложение за мобилни устройства. Пространството на състоянията, в тази игра, е 16 и тя попада е със сложност сходна на популярната игра Connect Four. При логическите игри с развлекателен характер от съществено значение е сложността за създаването на компютърно управляван опонент (изкуствен интелект). За игри с относително малко пространство на състоянията (както е играта Tic-Tac-Тое) дори алгоритми с пълно изчерпване дават достатъчно добри резултати в приемливо време за изчисление. 

<hr/>
<h1>
3. Управление на проект с отворен код
</h1>

Управлението на софтуерни проекти се осъществява със софтуерни системи, създадени специално за тази цел. За нуждите на настоящото изложение разработваният софтуерен проект е с GPL3 лиценз, за софтуер с отворен код. Една от най-подходящите алтернативи да се управлява такъв проект е хранилището GitHub. GitHub представлява облачна услуга, която позволява да се публикуват софтуерни проекти. GitHub включва различни системи, които позволяват работата на програмисти в екип, като системата за проследяване на дефекти и системата за контрол на версиите (базирана на софтуерния инструмент Git). 

<p/>

Създаването на един софтуерен продукт започва с заделяне на хранилище в което ще се разполага програмния код.

<p/>

<img src="0004.png" width="50%"/><br/>
<b>Фиг. 3</b> Създаване на хранилище в GitHub.

<p/>

При първоначалното конфигуриране на отдалеченото хранилище в GitHub се избира име на проекта, определя се съдържанието на .gitignore файла (в конкретния случай Android конфигурация) и се избира подходящ лиценз (в конкретния случай GPL3).

<p/>

<img src="0005.png" width="50%"/><br/>
<b>Фиг. 4</b> Състояние на новосъздаденото хранилище в GitHub.

<p/>

При използването на езика за програмиране Java са възможни различни развойни инструменти. Един от най-популярните и най-широко използвани е Eclipse. Eclipse представлява интегрирана среда за разработка (IDE), която основно включва текстов редактор и механизъм за извикване на развойните инструменти, предоставени от компанията Oracle. За нуждите на Android програмирането, Eclipse поддържа допълнителна приставка наречена Android Developer Tools – Plugin. За разработка на Android приложения, Eclipse се използва в комбинация с Android Software Development Kit, който включва и емулатор на различни виртуални устройства. 

<p/>

<img src="0007.png" width="50%"/><br/>
<b>Фиг. 5</b> Начален работен екран в Eclipse.

<p/>

Eclipse е развойна среда, която организира работата на проектен принцип. За тази цел всяка разработка се оформя като Eclipse Project.

<p/>

<img src="0008.png" width="50%"/><br/>
<b>Фиг. 6</b> Създаване на нов Eclipse проект.

<p/>

Развойната среда позволява работата с множество различни проекти, но в случая на Android разработка най-удачният вариант е генерирането на Android Application Project. 

<p/>

<img src="0009.png" width="50%"/><br/>
<b>Фиг. 7</b> Основни параметри на новосъздадения Eclipse проект.

<p/>

В работното пространство на Eclipse всеки проект има уникално наименование. Също така, всеки проект представлява софтуерен продукт и поради тази причина се въвежда наименование на продукта. В езика Java софтуерът се организира под формата на пакети и поради тази причина е необходимо избирането на подходящо название за пакет. Названието на пакета трябва да е уникално и да не води до колизия с наименованията на други пакети, дори когато става въпрос за софтуери с глобален мащаб на разпространение. Названието на пакета има и друга ключова отговорност, а именно уникалност при публикуването на готовия продукт в Google Play Store. Точно на тази фаза от разработката се определят и Android версиите, които ще бъдат поддържани.

<p/>

<img src="0013.png" width="50%"/><br/>
<b>Фиг. 8</b> Структура на новосъздадено проект в Eclipse.

<p/>

Като икона за предложението се запазват подразбиращите се характеристики и в етапа за създаване на проект не се добавя първоначален прозорец (Activity).

<p/>

За да бъде добавен новосъздадения Eclipse проект в отдалеченото хранилище на GitHub е необходимо клониране на отдалеченото хранилище в директория на локалния компютър.

<p/>

<img src="0015.png" width="50%"/><br/>
<b>Фиг. 9</b> Команда за клониране от отдалеченото хранилище на GitHub.

<p/>

В резултат от командата за клониране на работният плот се появява папка с локално копие на GitHub хранилището. 

<p/>

<img src="0016.png" width="50%"/><br/>
<b>Фиг. 10</b> Резултат от командата за клониране.

<p/>

Файловете от двете папки (папката създадена от Eclipse и папката получена в следствие на процеса за клониране) се обединяват в една обща папка.

<p/>

<img src="0018.png" width="50%"/><br/>
<b>Фиг. 11</b> Обединяване на файловете за проекта.

<p/>

След обединяването на двете папки не е нужно повече да се използват командните инструменти на Git, а може да се използват вградените Git инструменти в средата Eclipse. 

<p/>

<img src="0021.png" width="50%"/><br/>
<b>Фиг. 12</b> Публикуване на промените в локалното Git хранилище.

<p/>

Git е система за контрол на версиите, която работи на две степени (локално и глобално хранилище). Локалното хранилище се ползва при липса на връзка към Глобалната мрежа, докато публикуването в глобалното хранилище прави файловете публично достъпни в Глобалната мрежа.

<p/>

<img src="0022.png" width="50%"/><br/>
<b>Фиг. 13</b> Публикуване на промените в глобалното Git хранилище.

<p/>

Започването на нов проект с отворен код приключва с публикуването на първоначалната версия в публичното пространство.

<p/>

<img src="0023.png" width="50%"/><br/>
<b>Фиг. 14</b> Първоначален изглед на новосъздадения Eclipse проект в GitHub.

<hr/>
<h1>
4. Генериране на печалба от проекти с отворен код
</h1>

Софтуерът, като продукт, дава множество възможности за извършването на търговска дейност. Класическият вариант е свързан с продажба на лицензи за употребата на конкретен софтуер. Съществено е да се отбележи, че обект на търговската сделка е лицензът (правото за ползване), а не самият софтуер. Тъй като по своята природа, софтуерът е малко по-различен продукт, от класически продаваните продукти, то той позволява и серия друг модели за генериране на финансови приходи. Един значителен дял от софтуерните продукти се разпространяват под свободен лиценз, което изключва заплащането, от страна на потребителя, за това че ползва софтуера. При продуктите с отворен код е заложена дълбока философия за това, че достъпа до знание, в съвременния свят, трябва да бъде безплатен. Въпреки това, създателите на софтуер с отворен код е необходимо да генерират по някакъв начин финансови приходи, защото в противен случай не биха могли да поддържат дейността по създаването и поддръжката на софтуера. Най-често срещания модел за генериране на приходи е на база дарения. Зад едни от най-мащабните софтуерни проекти с отворен код често стоят нетърговски организации, даренията към които позволяват дейността да бъде финансирана. Вторият много популярен модел е предлагането на поддръжка в замяна на абонамент. При този модел целта на производителите е да създадат софтуерен продукт, толкова масово наложен и решават определени бизнес потребности, че потребителите да са склонни, да си заплащат услугите по поддръжката. В света на мобилните приложения и двата модела са трудно постижими, особено, когато става дума за малък проект, с малък търговски потенциал. Точно в тази ситуация най-подходящ е се оказва третият модел, който залага на реклами, визуализирани пред потребителите. Приходи от реклама биха били най-подходящи за продукта, който е представен в тази разработка. 

<p/>

Съществуват различни възможности за вграждане на рекламни материали в мобилните приложения, под формата на външни услуги. При тези външни услуги производителят на софтуера добавя конкретен модул в приложението си, който осъществява интеграцията със системата за обмен на реклами. Негативният ефект при този вариант е, че производителят става зависим от доставчика на услугата за обмен на реклами. Поради тази причина много по-удачен вариант е използването на собствена система за обмен на визуални реклами.


<p/>

<img src="0025.png" width="50%"/><br/>
<b>Фиг. 15</b> Revive Ad Server система за обмен на реклами.

<p/>

Една от най-разпространените платформи за обмен на реклами е Revive Ad Server. Представлява PHP/MySQL сървър скрипт приложение, което се разпространява под свободен лиценз и може да се използва без да се заплаща.  Revive Ad Server е предназначен за визуализация на реклами в уеб страници. Съществува и приложение за доставка на реклами в мобилни приложения, но то се разпространява срещу лицензна такса и не би било икономически изгодно при разработването на платформа от софтуер с отворен код. За нуждите на настоящата разработка ще бъдат използвани възможностите на Android платформата за визуализация на цялостни уеб страници.

<p/>

<img src="0027.png" width="50%"/><br/>
<b>Фиг. 16</b> Revive Ad Server организация на уеб сайтове.

<p/>

Организацията на рекламния сървър е основана на поддръжката, на множество уеб сайтове. В случая на мобилните приложения, за всяко мобилно приложение съществува профил в рекламния сървър. 

<p/>

<img src="0029.png" width="50%"/><br/>
<b>Фиг. 17</b> Revive Ad Server профил на мобилното приложение Ithaka.

<p/>

В профила за мобилното приложение се въвежда името (в случая Ithaka), лицето за контакти, което е отговорно за изпълнението на рекламни кампании в това приложение и URL адрес. При използването на безплатната версия, на  Revive Ad Server могат да се обработват само уеб сайтове, които от своя страна се характеризират с URL адрес. Тъй като мобилните приложения не притежават URL адрес, а тази характеристика е задължителна, то най-логично е да се въведе URL адрес характеризиращ по някакъв начин мобилното приложение. Такъм URL адрес е точно адресът на който ще бъде публикувано приложението в Google Play Store. 

<p/>

<img src="0030.png" width="50%"/><br/>
<b>Фиг. 18</b> Профил на мобилното приложение Ithaka, след създаванто му.

<p/>

Разделянето на уеб сайтове е на първично ниво в рамките на рекламния сървър. На вторично ниво всеки уеб сайт се характеризира с конкретни зони за визуализация на реклами. 

<p/>

<img src="0032.png" width="50%"/><br/>
<b>Фиг. 19</b> Основна зона за реклама в стартовия прозорец на играта Ithaka.

<p/>

Различните уеб сайтове могат да имат различни петна в които да се показват изображенията на рекламата. Това важи и за мобилните приложения. В различни екрани на мобилното приложение могат да се показват различни по размер и вид рекламни изображения. 

<p/>

<img src="0033.png" width="50%"/><br/>
<b>Фиг. 20</b> Единствена зона за реклами в играта Ithaka.

<p/>

В играта Ithaka ще има само една зона за реклама и това ще е първоначалният екран, при зареждане на приложението. Поради наличието на различни по размер и вид екрани на мобилни устройства един от най-удачните размери за реклами е 320х320 пискела. 

<p/>

<img src="0035.png" width="50%"/><br/>
<b>Фиг. 21</b> Празна зона, без закачени рекламни банери.

<p/>

Към всяка обособена зона трябва да се асоциират определени визуални реклами (банери). 

<p/>

<img src="0036.png" width="50%"/><br/>
<b>Фиг. 22</b> Множество от асоциирани банери.

<p/>

Чрез възможността към зоната да се асоциират конкретни банери се дава възможност за контрол на съдържанието и подбиране на тематична реклама, според вида на аудиторията, която използва конкретното приложение. 

<p/>

<img src="0039.png" width="50%"/><br/>
<b>Фиг. 23</b> HTML код за вграждане в уеб страница.

<p/>

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

<p/>

<img src="0041.png" width="50%"/><br/>
<b>Фиг. 24</b> Локална HTML страница в пакета на Android приложението.

<p/>

Android платформата позволява да се съхраняват локални ресурси (в това число и локални HTML страници) в специално предназначена за този случай директория – assets. За име на локалният файл е избрано banner.html.

<p/>

<img src="0044.png" width="50%"/><br/>
<b>Фиг. 25</b> Програмен текст на локалната HTML страница.

<p/>

Съдържанието на локалната уеб страница е изключително тривиално и се състои от шаблон на HTML5 документ в тялото на който е разположен генерираният от Revive Ad Server програмен код.

<p/>

<img src="0046.png" width="50%"/><br/>
<b>Фиг. 26</b> Създаване на начален екран за визуализиране на рекламни изображения.

<p/>

Android приложенията са организирани на работни екрани наречени Activity. Идеологията е такава, че всеки работен екран може да се активира по всяко време, без да се използва една единствена точка за стартиране (single entry point). Операционната система активира избран прозорец при начално стартиране, като тази задача се изпълнява от процес наречен Launcher. 

<p/>

<img src="0047.png" width="50%"/><br/>
<b>Фиг. 27</b> Задаване на празен екран.

<p/>

Най-подходящия шаблон, от списъка с възможни екрани, е празният. В този празен екран ще бъде поместен само един визуален компонент, изпълняващ ролата на уеб браузър.

<p/>

<img src="0048.png" width="50%"/><br/>
<b>Фиг. 28</b> Маркиране на прозореца като стартов.

<p/>

Всяко Activity в Android се описва от файл за графичния интерфейс (XML формат) и Java файл с програмен код. 

<p/>

<img src="0051.png" width="50%"/><br/>
<b>Фиг. 29</b> Вграждане на уеб браузър компонент в началния прозорец.

<p/>

WebView е стандартен визуален компонент от палитрата с компоненти за изграждането на графичен потребителски интерфейс в Android. 

<p/>

<img src="0055.png" width="50%"/><br/>
<b>Фиг. 30</b> Връзка за програмно управление на вградения браузър.

<p/>

За да се използва уеб браузър компонента в програмния файл на Java е необходимо да се получи референция към обекта, който операционната система ще създаде, в процеса на стартиране, на приложението. Още при зареждането се указва използване на JavaScript, тъй като рекламното съдържание се изтегля от сървъра с помощта на JavaScript код. Също така се подава и URL адресът на локално съхранената уеб страница. 

<p/>

<img src="0058.png" width="50%"/><br/>
<b>Фиг. 31</b> Времетраене на визуализацията.

<p/>

Екранът, показващ рекламните изображения, получава две характеристики от външната среда (в случая, манифест файла). Първата характеристика определя колко милисекунди да се визуализира рекламата, а втората характеристика определя кой екран да бъде визуализиран в последствие. 

<p/>

<img src="0061.png" width="50%"/><br/>
<b>Фиг. 32</b> Пренасочване към следващ прозорец.

<p/>

След изтичането на определеното време за визуализация се изпълнява код за пренасочване към основния екран на играта.

<p/>

<img src="0065.png" width="50%"/><br/>
<b>Фиг. 33</b> Разрешение за използване на Интернет връзка.

<p/>

Моделът за сигурност на Android изисква потребителят да се съгласи с всички правила за достъп до устройството, при първоначално инсталиране на приложението. За да се получават и визуализират рекламните изображения е необходимо приложението да използва Интернет свързаност. 

<p/>

<img src="0067.png" width="50%"/><br/>
<b>Фиг. 34</b> Параметри при извикване на прозорец.

<p/>

Прозорците в Android могат да получават определени параметри (без да се налага прекомпилиране на Java кода), чрез въвеждане на параметрите в описателната част за прозореца, в манифест файла на приложението. 

<p/>

<img src="0069.png" width="50%"/><br/>
<b>Фиг. 35</b> Поведение при затваряне на прозореца.

<p/>

Последната стъпка от създаването на рекламния прозорец е да се укаже, че той няма да попада в стека от активирани прозорци. Операционната система поддържа стек с всички активирани прозорци. Когато потребителят се връща (често има хардуерен бутон за връщане назад) предходните прозорци се вадят от стека. Целта при показването на реклами в настоящия проект е реклата да се визуализира само един път и да не се активира, когато потребителя прелиства прозорците назад. 

<hr/>
<h1>
5. Визуализиране на помощна информация
</h1>

По отношение на информацията, един от най-важните компоненти в софтуерните продукти са названието на продукта, носителите на авторските права и разпространителите. Почти всеки софтуерен продукт притежава под някаква форма (диалогов прозорец или текстово съобщение) тази информация. Също така от голямо значение е предоставянето на някаква помощна информация. При софтуерни продукти, които се разпространяват с отворен код, наличието на изчерпателна помощна информация далеч не е толкова важно, тъй като целият код на приложението е публично достъпен и всеки възникнал въпрос може да се разследва директно в оригиналните програмни кодове. При софтуерните продукти със затворен (комерсиален) лиценз, това далеч не е така и там се налага предоставянето на изчерпателна потребителска документация за експлоатацията на продукта. 

<p/>

<img src="0081.png" width="50%"/><br/>
<b>Фиг. 36</b> Създаване на информационен прозорец за продукта.

<p/>

В настоящия програмен продукт ще бъдат създадени два отделни прозореца (Activity), като единият ще съдържа информацията за продукта, а другият минимално количество помощна информация (правилата на играта).

<p/>

<img src="0085.png" width="50%"/><br/>
<b>Фиг. 37</b> Създаване на прозорец с помощна информация.

<p/>

Двата помощни прозореца биват визуализирани от основният екран на играта, за който също се създава отделно Activity.

<p/>

<img src="0077.png" width="50%"/><br/>
<b>Фиг. 38</b> Създаване на основен прозорец за играта.

<p/>

Най-бързият и лесен начин да се създадат информационните прозорци е като в XML файла описващ ги се добави EditText визуален контрол, който е забранен за писане.

<p/>

<img src="0088.png" width="50%"/><br/>
<b>Фиг. 39</b> Текстов компонент, който визуализира информацията за продукта.

<p/>

Единствената разлика между двата текстови контрола е референцията към предварително зададен текст в XML файла за текстови ресурси.

<p/>

<img src="0089.png" width="50%"/><br/>
<b>Фиг. 40</b> Текстов компонент, който визуализира помощната информация.

<p/>

Платформата Android организира текстовите ресурси в специално отреден за тази цел XML файл. Тази организация е въведена с цел максимално лесно превеждане на текстовете в приложението към множество други говорими езици.

<p/>

<img src="0091.png" width="50%"/><br/>
<b>Фиг. 41</b> Текстови ресурси за продукта и помощна информация.

<p/>

Тъй като разработваният софтуерен продукт е изключително елементарен, то е достатъчно в помощната информация да се публикуват правилата на играта.

<p/>

<img src="0096.png" width="50%"/><br/>
<b>Фиг. 42</b> Правилата на играта и информация за продукта, под формата на текстови ресурси.

<p/>

От съществено значение е да се отбележи, че представянето на текстовата информация в ресурсен файл води до някои особености, а именно използване на специални символи за нов ред (\n – както е в програмния език Java) и символа апостроф (\' - както е в програмния език Java). Използването на специалните символи за изписване в Java се налагат, тъй като XML ресурсите биват компилирани до Java низове и там от значение са правилата за представяне на текстова информация в Java символни низове.

<p/>

<img src="0107.png" width="50%"/><br/>
<b>Фиг. 43</b> Създаване на XML ресурс за менюта.

<p/>

За да бъде възможно извикването на прозорците с помощна информация е необходимо да се създаде меню XML ресурс и това меню да бъде заредено в основния екран на играта.

<p/>

<img src="0108.png" width="50%"/><br/>
<b>Фиг. 44</b> Избор на име за меню ресурса.

<p/>

Тъй като играта е изключително елементарна, то е достатъчно да има три опции в менюто – нова игра, помощ и за продукта. При Android платформата не е прието потребителя да затваря прозорците, които е отворил и поради тази причина в менюто не е добавена опция за изход от играта.

<p/>

<img src="0111.png" width="50%"/><br/>
<b>Фиг. 45</b> Описание на опциите в менюто.

<p/>

За да бъде достъпно менюто в основния екран на играта то описателният файл трябва да бъде зареден, при създаването на прозореца, и към менюто трябва да се получат програмни референции.

<p/>

<img src="0113.png" width="50%"/><br/>
<b>Фиг. 46</b> Програмно конструиране на менюто на база описателния файл.

<p/>

Освен конструиране на менюто е необходимо да се пренапише събитието, което отговаря за избиране на опции в менюто. Коя от всичките опции е избрана се определя от идентификаторите (id-тата), вписани в за всяка опция в XML описателния файл.

<p/>

<img src="0117.png" width="50%"/><br/>
<b>Фиг. 47</b> Определяне на опция от менюто, която да бъде изпълнена.

<p/>

В резултат на направените модификации основният прозорец на играта разполага с меню, което се активира от хардуерен бутон на устройството (или специално предназначен софтуерен бутон, когато устройството е без бутони).

<p/>

<img src="0119.png" width="50%"/><br/>
<b>Фиг. 48</b> Изглед на менюто.

<p/>

Помощната информация се появява под формата на текст в текстово поле.

<p/>

<img src="0121.png" width="50%"/><br/>
<b>Фиг. 49</b> Екран с помощна информация.

<p/>

По аналогичен начин изглежда и информацията за продукта.

<p/>

<img src="0122.png" width="50%"/><br/>
<b>Фиг. 50</b> Екран с информация за продукта.

<p/>

<hr/>
<h1>
6. Потребителски интерфейс
</h1>

Разработваното приложение е достатъчно просто за да бъде поместено в един програмен екран. Правилото при разработка на Android приложения е информацията да се разбива в повече на брой, но с по-малко визуални компоненти, екрани. Изключително популярен подход е софтуерните приложения да се разделят в три слоя – визуализация, обектен модел и съхранение. Визуализацията в Android се описва под формата на XML файлове, за графичния интерфейс. Обектният модел се създава под формата на Java обекти с програмен код в методите на класовете. Слоят за съхранението се реализира под формата на SQLite релационна база данни. Според това от кой слой ще започне разработката има два основни подхода – top-down и bottom-up. При top-down, първо се създава графичният интерфейс, с всичките работни екрани, който той ще съдържа, след това се описват обектите в междинния слой и най-накрая се изработва релационната база данни. Между обектния модел и релационния модел се извърша операция наречена обектно релационен мапинг. При bottom-up подхода, първо се анализират данните и се създава релационен модел, след това, от релациите, се оформя обектния модел и накрая се изработва графичен интерфейс, който да отразява моментното състояние на обектния модел. Изборът между двата подхода зависи от обемът на проекта и от наличната документация за решавания проблем. Тъй като играта Ithaka е изключително елементарна и действието й ще се развива само в един екран, то може да се приложи подход top-down. В първоначалната версия няма да бъде представена релационна база данни, но в последствие е възможно да се добави и този слой, като в него се натрупва статистика за изиграните игри и най-добрите постигнати резултати. 

<p/>

<img src="0128.png" width="50%"/><br/>
<b>Фиг. 51</b> Изображение използвано за празен пул.

<p/>

Интерфейсът в основния екран на играта може да се реализира под формата на решетка, върху който да се поставят изображенията на пуловете. В случая, много по-удачен вариант е да се маркират 16 полета, във формата на решетка, с размери 4х4, така че да създават илюзията за решетка.

<p/>

<img src="0124.png" width="50%"/><br/>
<b>Фиг. 52</b>  Изображение използвано за син пул.

<p/>

<p/>

<img src="0125.png" width="50%"/><br/>
<b>Фиг. 53</b> Изображение използвано за розов пул.

<p/>

<p/>

<img src="0126.png" width="50%"/><br/>
<b>Фиг. 54</b> Изображение използвано за зелен пул.

<p/>

<p/>

<img src="0127.png" width="50%"/><br/>
<b>Фиг. 55</b> Изображение използвано за оранжев пул.

<p/>

Тези пет графични артефакти са напълно достатъчни да се реализира целия графичен потребителски интерфейс, в основния екран на играта. На практика е използвано едно и също базово изображение, за което са изработени четири варианта в различен цвят. Важно е да се забележи използването на слой за прозрачност. Слоят за прозрачност се нарича алфа канал и служи за определяне каква част от изображението да бъде визуализирана и каква част да бъде заместена от фона върху който се визуализира изображението. По този начин с правоъгълни изображения могат да се пресъздадат обекти с неправилна форма, като се наслагват едни върху други.


<p/>

<img src="0197.png" width="50%"/><br/>
<b>Фиг. 56</b> Основен екран описан като XML ресурс.

<p/>

За нуждите на основния екран в играта е достатъчно да се подредят 16 компонента от тип ImageView. Визуалните компоненти биват оразмерени, така че максимално ефективно да запълват визуалното пространство. Също така, всеки визуален компонент получава подходящи координати, спрямо горния ляв ъгъл. При тази подредба се получава своеобразна матрица. Най-съществената част в описанието на визуалните компоненти са техните идентификатори (свойството id). Идентификаторите служат за получаване на програмен достъп до визуалните компоненти, описани в XML ресурсните файлове. При настоящата реализация идентификаторите са така подбрани, че да символизират индексите в двумерен масив на Java.

<p/>

<img src="0198.png" width="50%"/><br/>
<b>Фиг. 57</b> Първоначален изглед на празно игрално табло.

<p/>

Така подредени, визуалните компоненти биха отразявали вътрешното състояние на обектния модел. Единствената задача на визуалният потребителски интерфейс е да представя пред потребителя моментното състояние на обектния модел.

<p/>

<img src="0204.png" width="50%"/><br/>
<b>Фиг. 58</b> Референции за достъп до компонентите описани в XML файла.

<p/>

След като графичният интерфейс е описан под формата на XML код, то в програмния код трябва да се осигури достъп до визуалните компоненти, с помощта на Java референции. Най-удачният вариант за съхраняване на референциите е в двумерен масив, който да повтаря организацията на ImageView компонентите, описани под формата на XML.

<p/>

<img src="0211.png" width="50%"/><br/>
<b>Фиг. 59</b> Съхраняване на референции с помощта на фактори функция.

<p/>

Най-съществено е да се забележи начинът по който се съпоставят идентификаторите от XML описанието към съответните клетки на двумерния масив. Използва се съответствие при което pieces[X][Y] се съпоставя на XML компонент R.id.pieceXY.

<hr/>
<h1>
7. Обектно-ориентиран модел
</h1>

В средния слой е поместен обектно-ориентираният модел, който по своето същество представлява група от обекти, взаимно свързани по между си. Графичният интерфейс служи като моментна снимка, на вътрешното състояние, в което се намират обектите. В клас ориентирани езици, какъвто е и езикът Java, обектите се описват със своите класове. За успешно ОО моделиране е от съществено значение правилно да се идентифицират съществителните имена в заданието и част от тях да бъдат избрани за класове в системата. В играта Ithaka основно съществува игрално поле, върху което са разположение игрални пулове. На практика игралното поле е в has релация спрямо пуловете. По отношение на това, кои обекти притежават други обекти се прилагат два основни подхода за моделиране – композиция или агрегация. 

<p/>

<img src="0136.png" width="50%"/><br/>
<b>Фиг. 60</b> Моделиране на пуловете.

<p/>

За моделирането на пуловете има различни възможности, но една от най-удачните е използването на изброените типове в Java. В процеса на компилация, изброените типове се трансформират до стандартни Java класове, но по време на самото моделиране изброените типове налагат серия ограничения за начина по който вътрешните им член-променливи и методи могат да се използват. В оригиналния вариант на играта пуловете са само с четири цвята, но в последствие е възможно да се добавят и други цветове. Моделиране с изброени константи ще позволи софтуера с лекота да бъде разширен в тази посока. Неестествено е в изброените пулове да се включи и понятието за празна клетка, но от програмна гледна точка е изключително рационално, най-малкото защото в графичния програмен интерфейс артефактите съответстват на пет различни елемента, а не на четири. От друга страна, чисто условно, може да се смята, че действително има бели пулове, които се разменят с цветните, така че да се формират съответните комбинации върху игралното табло.

<p/>

<img src="0148.png" width="50%"/><br/>
<b>Фиг. 61</b> Модел на игралното табло.

<p/>

Най-важният обект в разработвания софтуерен продукт е игралното табло. За да бъде представено в Java ОО модел игралното табло се описва под формата на самостоятелен клас Board. Обект от класа Board ще бъде вграден в програмния интерфейс, така че да се осъществява комуникация между визуалния слой и слоя на обектния модел. Традиционно, класовете в обектно-ориентираните езици имат група от характеристики (представени под формата на член променливи и/или свойства). Най-важната характеристика на игралното табло е неговият размер. В оригиналните условия на играта игралното табло е с размери 4х4, но не е изключено, в бъдещи версии на софтуерната реализация, размерите да бъдат променени (както и броят на цветовете пулове). Поради тази причина и за да се избегне феноменът познат под названието „магически числа“, най-удачно е размерите на игралното табло да бъдат представени под формата на статични константи. Друга важна характеристика на игралното табло е дължината на линията, която формира печеливша комбинация (в оригиналния вариант това е 3). Тъй като играта се играе на ходове, важно е да се съхранява информация кой по ред е текущия ход. Това може да се постигне с целочислена променлива (в случая променливата turn), която да служи като брояч. Полезно би било да се знае в кой момент играта е приключила и това се постига с допълнителен булев флаг (в случая променливата gameOver). Повечето компютърни игри се описват с група обекти, които изпадат в различни състояния, поради тази причина много често се прилагат способите от теория на крайните автомати. От първоначалния ОО анализ най-съществена е характеристиката на класа определяща пуловете. Най-удачно е пуловете да бъдат моделирани с двумерен масив от типа Piece. Състоянието на този двумерен масив ще бъде отразявано в графичния потребителски интерфейс, където вече е предвиден друг двумерен масив от тип ImageView. Практически, всички изчисления ще се извършват в обектния модел, но резултата от тях ще става видим в потребителския интерфейс. Също така, потребителя ще взаимодейства с елементите на графичния интерфейс, а информацията ще бъде предавана към по-долния слой на обектния модел. 

<p/>

<img src="0157.png" width="50%"/><br/>
<b>Фиг. 62</b> Изходно състояние на игралното табло.

<p/>

В изходно състояние игралното табло е подредено според указанията в правилата на играта. Точно поради тези причина, в обектния модел, двумерния масив, съдържащ пуловете, бива инициализиран подходящо от в момента, в който бива конструиран обект от класа Board.

<p/>

<img src="0168.png" width="50%"/><br/>
<b>Фиг. 63</b> Запазване на история с изиграните ходове.

<p/>

Едно от правилата на играта изисква да се следят трите последни хода. При наличие на три идентични хора, играчът губи играта. Поради тази причина възниква необходимостта да се съхранява историята на изиграните ходове. Тъй като едно разиграване може да продължи много ходове, то най-удачно е използването на контейнер от тип Vector, в който да се записват обекти от клас Move. 

<p/>

<img src="0167.png" width="50%"/><br/>
<b>Фиг. 64</b> Моделиране на отделен ход в играта.

<p/>

За да се моделират ходовете в играта удачен вариант е използването на отделен клас, наречен Move. Всеки ход в играта се описва с начални координати (пул, който предстои да бъде местен) и крайни координати (клетка в която пула трябва да попадне). Същественото за ходовете в играта е че те може да са два основни типа – валидни и невалидни. При настоящия модел валидността на ходовете е изнесена извън класа Move. Добрите практики за ОО моделиране изискват всички вътрешни променливи на класовете да бъдат скрити (частно ниво на достъп), но в случая е очевидно, че полетата са с пакетното ниво на достъп, което езикът Java позволява. Нарушаването на концепциите за капсулиране са допустими, когато класът е с пакетно ниво на достъп и инстанции от него няма да се ползват извън рамките на пакета. В настоящата разработка класовете на обектния модел и на графичния интерфейс се намират в един пакет (тъй като приложението е твърде елементарно), но добрата практика за писане на модулен софтуер изисква класовете с различно предназначение да бъдат оформени в тематични пакети. Също така, може да се забележи, че всички класове от групата на обектния модел са с пакетно ниво на достъп, докато всички класове (предимно наследници на Activity) са с публично ниво на достъп. Причината за това е, че операционната система трябва да има достъп до интерфейсните класове и да има възможност за създаване на обекти от тях. Това съвсем не е така с класовете от обектния модел, които трябва да служат, като вътрешна анатомия на софтуерния продукт. Макар и малко на брой трите класа (Pice, Board и Move) напълно покриват първоначалните нужди за моделиране на играта Ithaka. След определяне на структурите от данни следва стъпката за изготвяне на алгоритмите, които ще обработват данните. 

<hr/>
<h1>
8. Извършване на пресмятания
</h1>

Java е изцяло обектно-ориентиран език и позволява писане на програмен код само в рамките на методи (тоест не съществуват самостоятелни функции, както е примерно в езика C). Най-същественият елемент на тази фаза от софтуерния дизайн е коя функция в кой клас ще бъде реализирана. Най-разумния подход при реализирането на програмен текст е първо да се изработят тези функции, които са най-ясни и най-лесни за реализация. Този подход не винаги е приложим, особено ако се използва работен процес базиран на FDD (Feature Driven Development), при който възложите#лят определя коя функционалност да бъде реализирана с приоритет. Тъй като в настоящата разработка чисто формално не съществува ролята на възложи#теля, то без проблем може да се започне с най-лесните функции.

<p/>

<img src="0150.png" width="50%"/><br/>
<b>Фиг. 65</b> Намиране на хоризонтална печеливша комбинация.

<p/>

Едно от най-значимите събития в играта е намирането на ситуациите в които единият играч побеждава другия играч. 

<p/>

<img src="0151.png" width="50%"/><br/>
<b>Фиг. 66</b> Намиране на вертикална печеливша комбинация.

<p/>

Най-често срещаната ситуация за формиране на печеливша комбинация е подреждането на три пула, от един цвят, в права линия. 

<p/>

<img src="0152.png" width="50%"/><br/>
<b>Фиг. 67</b> Намиране на печеливша комбинация по главния диагонал.

<p/>

Печелившите комбинации могат да са по хоризонтала, вертикала или един от двата диагонала.

<p/>

<img src="0153.png" width="50%"/><br/>
<b>Фиг. 68</b> Намиране на печеливша комбинация по вторичния диагонал.

<p/>

При избора как да бъдат проектирани отделните функции най-важен е принципът използван още от средновековието средновековието – разделяй и владей. Поради тази причина намирането на печеливша комбинация е разбито в четири помощни функции, като всяка една търси в определена посока. Това, което трябва да се съобрази е, че игралното табло има размери 4х4, докато печелившата комбинация е с дължина 3. Поради тази причина печелившата комбинация може да започва от различни клетки и да завършва на различни клетки, без значение, че направлението е едно и също. 

<p/>

<img src="0155.png" width="50%"/><br/>
<b>Фиг. 69</b> Обединение на четирите помощни функции.

<p/>

След разбиването на четири помощни функции следва резултатът от всичките тях да бъде обработен в една, по-главна, функция (тоест овладяването на проблема).

<p/>

<img src="0159.png" width="50%"/><br/>
<b>Фиг. 70</b> Установяване на изходно състояние за обекта на игралното табло.

<p/>

При проектирането на класове има два основни подхода – обектите им да бъдат непроменяеми (immutable objects) или променяеми (mutable objects). Смята се, че непроменяемите обекти са значително по-безопасни за работа, но те са свързани с множество заделяния на инстанции и последващото им освобождаване от модула за управление на паметта (garbage collector). За обекта на игралното табло е използват принципа за променяем обект, което налага съществуването на функция, която да установява обекта в изходно състояние. 

<p/>

<img src="0161.png" width="50%"/><br/>
<b>Фиг. 71</b> Броене на ходовете.

<p/>

Броенето на изиграните ходове се осъществява с променлива брояч. 

<p/>

<img src="0163.png" width="50%"/><br/>
<b>Фиг. 72</b> Достъп до скритите полета на обекта.

<p/>

Достъпа до скритите полета на обекта се осъществява с функции наречени аксесори. Тяхната единствена задача е да предоставят контролиран достъп до скритите променливи на обекта.

<p/>

<img src="0173.png" width="50%"/><br/>
<b>Фиг. 73</b> Служебни функции за сравняване на обекти от тип Move.

<p/>

Тъй като едното условие за край на играта изисква да се следи тройното повтаряне на един ход, то най-разумната реализация на тази проверка е във Vector контейнер, който да съхранява всички изиграни ходове. Също така е важно ходовете да могат, да се сравняват два по два. В езика Java, за тази цел, са предвидени два служебни метода hashCode и equals. 

<p/>

<img src="0175.png" width="50%"/><br/>
<b>Фиг. 74</b> Проверка за три повторения на ход.

<p/>

При наличието на обекти, описващи един ход и хронология на играта е достатъчно да се проверят трите последни хода изиграни от конкретния играч. 

<p/>

<img src="0177.png" width="50%"/><br/>
<b>Фиг. 75</b> Валидност на ходовете.

<p/>

Когато бъде избран определен ход (независимо дали от човека или от компютърния опонент) има две възможности – ходът да е валиден или ходът да не е валиден. 

<p/>

<img src="0178.png" width="50%"/><br/>
<b>Фиг. 76</b> Проверка за съседен пул от същия цвят.

<p/>

Според правилата на играта валиден е само ход при който се мести пул, имащ за съсед поне още един пул от същия цвят. 

<p/>

<img src="0180.png" width="50%"/><br/>
<b>Фиг. 77</b> Наличие на пряк път от пула до клетката на която трябва да бъде поставен.

<p/>

Второто условие за валидност на хода, според правилата, е наличието на път по права линия до клетката върху която пулът трябва да бъде поставен. Това условие включва и изискването клетката, върху която трябва да бъде поставен, да бъде празна клетка. 

<p/>

<img src="0181.png" width="50%"/><br/>
<b>Фиг. 78</b> Помощна функция за търсене на директен път.

<p/>

Търсене на път от пула до същата клетка върху която вече се намира се смята за невалиден път. По условията на играта пътят може да бъде по права линия – хоризонтално, вертикално или диагонално. 

<p/>

<img src="0216.png" width="50%"/><br/>
<b>Фиг. 79</b> Обновяване на визуалните контроли.

<p/>

Използването на многослойна софтуерна архитектура (в случая трислоен модел) налага изграждане на връзки между слоевете. Връзката между слоя на графичния потребителски интерфейс и обектния модел се осъществява с променлива board от клас Board, която е вътрешно поле за класа GameActivity. На практика, компонент от графичния интерфейс съдържа компонент от обектния модел. 

<p/>

<img src="0224.png" width="50%"/><br/>
<b>Фиг. 80</b> Отразяване на вътрешното състояние върху екрана.

<p/>

Основната задача на графичния интерфейс е да изобрази моментна снимка на вътрешното състояние (в случая обекта board). За тази цел се получава матрица с информация за състоянието на игралното табло. След това матрицата се обхожда и във всяка клетка се изрисува изображение, според инструкциите в матрицата. Възможностите за програмно настройване на канала за прозрачност ще се използват за онагледяване на избран от потребителя пул. 

<p/>

<img src="0226.png" width="50%"/><br/>
<b>Фиг. 81</b> Основен екран на играта, визуализиращ информация взета от обектния модел.

<p/>

Двете основни сетива, с които хората възприемат света, са зрението и слухът. Визуализирането на игралното табло дава добра представа на потребителя как протича процесът на игра, но усещането може да се подсили с подходящо избрани звуци.

<p/>

<img src="0232.png" width="50%"/><br/>
<b>Фиг. 82</b> Структури от данни за използване на звуци.

<p/>

Платформата Android предоставя възможност за работа със звуци, под формата на пул от звукови ресурси. Две са основните събития, които си заслужава да бъдат допълнително подсилени със звуково оформление – изборът на клетка за игра и край на разиграването. 

<p/>

<img src="0228.png" width="50%"/><br/>
<b>Фиг. 83</b> Звукови файлове.

<p/>

По подобие на графичните ресурси, проектът на Eclipse позволява включването на звукови ресурси. Един от най-подходящите файлови формати е форматът WAVE. Този формат няма компресия и дава достатъчно добро качество на звука. Подходящ е за малки по размер звукови ресурси.

<p/>

<img src="0234.png" width="50%"/><br/>
<b>Фиг. 84</b> Програмен достъп до звуковите ресурси.

<p/>

Звуковите ресурси се използват програмно чрез зареждане от фактори функция. Веднъж заредени, звуците се използват с техните идентификатори в пула от звуци. 

<p/>

<img src="0238.png" width="50%"/><br/>
<b>Фиг. 85</b> Обработка на потребителския вход.

<p/>

Java е език разчитащ на събити#йно ориентирано написан програмен код. Тази философия е спазена и в платформата Android. Приложните програмисти вписват кодът, който приложението им трябва да изпълнява във функции наречени event handlers. За да бъде възможна тази обработка, всеки визуален контрол трябва да се абонира за обработка на възникнало в него събитие към обект-слушател (listener object). Възможни са различни конфигурации между визуалните компоненти и обектите-слушатели. Най-често използвания подход е към всеки визуален контрол да бъде закачен само един отделен обект-слушател. Програмно е позволено да се закачат множество обекти-слушатели към един визуален контрол, но това създава проблем за начина по който ще бъдат уведомени различните обекти, при настъпване на събитие. Друг много популярен подход е един и същи обект-слушател да бъде прикачен към множество визуални компоненти. При тази стратегия възниква допълнително усложнение да се идентифицира кой визуален компонент е предизвикал възникването на съответното събитие. Това, разбира се, е напълно възможно, тъй като функцията, обработваща събитието, получава входящ параметър с референса на визуалния компонент, който е отговорен за възникване на събитието. 

<p/>

<img src="0239.png" width="50%"/><br/>
<b>Фиг. 86</b> Определяне на визуалния компонент, предизвикал събитието.

<p/>

При наличие на референция към визуалния компонент, който е предизвикал събитието, е достатъчно да се проверят всички визуални компоненти и референциите им да бъдат сравнение, за да се установи кой елемент точно е натиснал потребителят. 

<p/>

<img src="0241.png" width="50%"/><br/>
<b>Фиг. 87</b> Ако играта е приключила потребителят няма контрол над игралното табло.

<p/>

Когато играта приключи следва потребителят да не може по никакъв начин да модифицира игралното табло. Той би могъл да започне нова игра, като избере съответстващата опция в менюто на екран. 

<p/>

<img src="0245.png" width="50%"/><br/>
<b>Фиг. 88</b> Прикачане на обекта-слушател към визуалните компоненти.

<p/>

За обектите-слушатели има няколко различни стратегии. Те могат да бъдат анонимни обекти, от анонимни класове или пък обекти с имена, но от анонимни класове (използваният в конкретния случай), а също така могат да бъдат обекти с имена от класове с имена. Въпрос на експертен избор е дали класът на обекта-слушател да бъде анонимен, вътрешен скрит или пакетен външен. В настоящата разработка е създаден само един обект с име от анонимен слушателски клас. Този обект се закача за всичките 16 визуални компонента от ImageVeiew тип, които формират решетката на игралното табло. 

<p/>

<img src="0247.png" width="50%"/><br/>
<b>Фиг. 89</b> Предаване на потребителския вход към обектния модел.

<p/>

Втората основна задача на потребителския интерфейс е да предава действията избрани от потребителя към обектния модел на приложението. За тази цел обектът-слушател определя коя клетка в решетката е била избрана и извиква, с подходящи параметри, функция в обектния модел, която да обработи възникналата промяна, в следствие на действие от външния свят. 

<p/>

<img src="0250.png" width="50%"/><br/>
<b>Фиг. 90</b> Структура данни отчитаща избора на клетки върху игралното поле.

<p/>

Появата на възможност за избор на клетка от игралното поле налага допълнително разширяване на възможностите заложени в обектния модел. Има различни начини по които да се съхранява информацията за избора на клетка в матрицата. Възможен вариант е две цели числа да съхраняват координатите на избраната клетка. Един такъв подход за моделиране на ситуацията с избрана клетка би бил удачен за първоначалната постановка на играта, но ще се окаже неудачен, ако в последствие се появи възможност повече от една клетка на игралното табло да бъде в състояние избрана. Точно поради тази причина, най-разумно е всички клетки бъдат онагледени със състояние избрана/неизбрана. При такъв избор на структура от данни, масивите pieces и selection се наричат паралелни масиви. На по-следващ етап от развитието на проекта е разумно вместо два паралелни масива да бъде направен един масив от тип Cell, като класът Cell би съдържал две вътрешни плета – пул и състояние на избиране. Новият двумерен масив също подлежи на първоначално установяване при рестартиране на играта, а също така се съпровожда от getter функция, която да го връща на обкръжаващата го среда.

<p/>

<img src="0256.png" width="50%"/><br/>
<b>Фиг. 91</b> Визуално представяне на избраните клетки.

<p/>

Един то най-елегантните начини да се визуализира състоянието на избраните клетки е като се модифицира каналът за прозрачност на съответните визуални контроли.

<p/>

<img src="0258.png" width="50%"/><br/>
<b>Фиг. 92</b> Проверка за наличие на избрана клетка.

<p/>

Потребителят избира клетка от решетката на играта, когато иска да определи кой пул да бъде преместен. Поради тази причина е важно в обектния модел да се знае дали клетката вече е избрана или все още предстои да бъде избран. 

<p/>

<img src="0260.png" width="50%"/><br/>
<b>Фиг. 93</b> Избор на действие, според това дали е избрана клетка.

<p/>

Според това дали е избрана клетка от игралното табло, в обектния модел се извършват различни действия. При неизбрана клетка се прави опит за избиране на клетка. При избран клетка се прави опит за преместване на пула. 

<p/>

<img src="0264.png" width="50%"/><br/>
<b>Фиг. 94</b> Премахване на избраните клетки.

<p/>

След като ходът на съответния играч приключи е важно маркировката на клетките да бъде премахната. 

<p/>

<img src="0266.png" width="50%"/><br/>
<b>Фиг. 95</b> Обновяване на визуалните компоненти, след взаимодействие на потребителя с устройството.

<p/>

Когато потребителят извърши определено действие на екрана, то се отразява в обектния модел, но това трябва да доведе и до обновяване на визуалните компоненти. Един от класическите подходи при реализиране на тези процедури е използването на дизайн шаблона Model-View-Controller (MVC). Тъй като разработваната игра е твърде елементарна, то MVC шаблонът би бил едно ненужно усложнение, тъй като той е подходящ за по-мащабни софтуерни решения. 

<p/>

<img src="0267.png" width="50%"/><br/>
<b>Фиг. 96</b> Пул в избрано състояние.

<p/>

След като бъде избран пул, то трябва да се случат серия изчислителни стъпки.

<p/>

<img src="0273.png" width="50%"/><br/>
<b>Фиг. 97</b> Действия за осъществяването на ход.

<p/>

На първо място трябва да се генерира обект от тип Move. Ако генерираният ход е валиден, то той трябва да бъде изпълнен и съответния играч да приключи хода си. Ако генерираният ход е невалиден, то изиграването на ход трябва да се рестартира, като се премахне направената селекция и се даде следващ шанс на играча да избира. 

<p/>

<img src="0275.png" width="50%"/><br/>
<b>Фиг. 98</b> Изработване на обект от тип Move.

<p/>

Изработването на обект от тип Move се извърша на база предходната селекция на пул и текущият избор на празна клетка, където пулът трябва да се премести. 

<p/>

<img src="0279.png" width="50%"/><br/>
<b>Фиг. 99</b> Проверка за валидността на хода.

<p/>

След формирането на хода следва проверка за неговата валидност. 

<p/>

<img src="0280.png" width="50%"/><br/>
<b>Фиг. 100</b> Проверка за неуспешно генериране на ход.

<p/>

Ако поради някаква причина генерирането на ход не е било успешно, то процедурата по изиграване на ход отново трябва да се рестартира.

<p/>

<img src="0294.png" width="50%"/><br/>
<b>Фиг. 101</b> Определяне на победителя.

<p/>

При определянето на победителя най-рационално е да се маркират точните пулове, които формират печелившата комбинация. 

<p/>

<img src="0295.png" width="50%"/><br/>
<b>Фиг. 102</b> Определяне на победителя.

<p/>

Разполагайки с нужната информация за пуловете участващи във формирането на печелившата линия, тази информация може подходящо да бъде отразена в графичния потребителски интерфейс. За тази цел, всички печеливши пулове се изобразяват с пълна стойност на канала за прозрачност, а пуловете, които не участват в печелившата комбинация, се затъмняват. 

<p/>

<img src="0302.png" width="50%"/><br/>
<b>Фиг. 103</b> Използване на нишка за компютърния опонент.

<p/>

Човекът, играещ на мобилното устройство, предизвиква събитията, свързани с неговите решения за игра. Това няма как да се случи по отношение на компютърния опонент. Поради тази причина един от най-удачните подходи за генериране на събития от компютърния опонент е чрез постоянно работеща Java нишка. 

<p/>

<img src="0305.png" width="50%"/><br/>
<b>Фиг. 104</b> Използване на нишка за компютърния опонент.

<p/>

Ако играта вече е приключила, то няма причина изкуственият интелект да бъде активиран. 

<p/>

<img src="0307.png" width="50%"/><br/>
<b>Фиг. 105</b> Следене на ходовете в нишката за компютърния опонент.

<p/>

Ако на ход е играчът човек, също няма причина изкуственият интелект да бъде активиран.

<p/>

<img src="0309.png" width="50%"/><br/>
<b>Фиг. 106</b> Маркиране за приключване на хода и обновяване на графичния интерфейс.

<p/>

Тъй като създаването на изкуствен интелект, за подобен вид игри, има сложност надминаваща нивото на настоящото изложение в разработката ще бъде избран най-елементарният вариант, а именно изборна случаен валиден ход. 

<p/>

<img src="0316.png" width="50%"/><br/>
<b>Фиг. 107</b> Избор на случаен валиден ход.

<p/>

Избирането на случаен валиден ход става с генериране на двойки координати, върху игралното табло, докато не се уцели такава двойка, която да е валидна. След което следва двойно избиране, аналогично на начина по който избира човекът играч.

<p/>

<img src="0322.png" width="50%"/><br/>
<b>Фиг. 108</b> Залагане на отложено събитие за активиране на компютърния опонент.

<p/>

След като човекът приключи своя ход трябва да заложи отложен старт на събитието, което ще предизвика активиране на компютърния опонент. 

<p/>

<img src="0330.png" width="50%"/><br/>
<b>Фиг. 109</b> Забавяне на компютърния опонент.

<p/>

Тъй като компютърният опонент изпълнява твърде бързо избора на пул и клетка за преместване, то е удачно да се сложи известно забавяне, за да може човекът играч да види кой пул избира компютъра и да проследи на коя клетка го мести. 

<p/>

<img src="0342.png" width="50%"/><br/>
<b>Фиг. 110</b> При липса на валиден ход от страна на компютърния опонент.

<p/>

Възможно е да не съществува валиден ход, когато е ред за игра на компютърният опонент. Тази възможност трябва да се проверя, защото в противен случай цикълът за търсене на случаен валиден ход би се превърнал в безкраен цикъл, а това е сериозна логическа програмна грешка. 

<p/>

<img src="0340.png" width="50%"/><br/>
<b>Фиг. 111</b> Проверка за край на играта.

<p/>

След всеки направен ход (независимо дали е от човека или от компютърния опонент) е възможно да настъпят условията определящи края на играта. Точно поради тази причина след всеки ход трябва да се прави проверка за край на играта. 

<p/>

<img src="0341.png" width="50%"/><br/>
<b>Фиг. 112</b> Проверка за наличие на валиден ход.

<p/>

Едно от условията за край на играта е опонентът да няма валиден ход. Един от най-лесните начини това условие да бъде проверено е на принципа, на пълното изчерпване. Изпробва се всяка клетка в двойка с всяка друга и ако нито една не позволява валиден ход, то тогава се маркира краят на играта, поради липса на валиден ход. Алгоритъмът е бавен, защото се състои от четири вложени цикъла, но пък размера на игралното пространство е 16, което позволява прилагане на принципа, на грубата сила. 

<p/>

<img src="0348.png" width="50%"/><br/>
<b>Фиг. 113</b> Ситуация при която играта е приключена.

<p/>

С това базовата разработка на играта е приключена. При този род игри е от голямо значение да се създаде достатъчно силен компютърен опонент, така че интересът на играещият да се задържи по-дълго и той да намира мотивация за изиграването на повече игри. Android е платформа, която дава много възможности за реализацията на мрежова комуникация. Игра, като играта Ithaka, е идеален кандидат за добавяне на възможности за игра в мрежа, по Wi-Fi и/или по Bluetooth. И двете направления изискват значително повече познания и умения, спрямо нивото на текущото изложение. Поради тази причина, разработката на изкуствения интелект и играта в мрежа ще бъдат представени в изложение за по-напреднали потребители. 

<hr/>
<h1>
8. Разпространение на продукта
</h1>

След като бъде създаден един софтуерен продукт, то той трябва да достигне до своите потребители. В случая на Android най-достъпният канал за разпространение на приложения е Google Play Store. Когато приложението е с отворен код може да се използва и услуга за разпространение, каквато е F-Droid. 

<p/>

<img src="0353.png" width="50%"/><br/>
<b>Фиг. 114</b> Начален екран при публикуване на ново приложение.

<p/>

Публикуването започва с избор на заглавие и език за разпространение.

<p/>

<img src="0355.png" width="50%"/><br/>
<b>Фиг. 115</b> Название на приложението.

<p/>

Към заглавието на продукта се добавя кратко и детайлно описание.

<p/>

<img src="0359.png" width="50%"/><br/>
<b>Фиг. 116</b> Описание на продукта.

<p/>

Най-важната част от публикуването е създаването на дигитално подписан изпълним файл.

<p/>

<img src="0361.png" width="50%"/><br/>
<b>Фиг. 117</b> Избор на проект за експортиране.

<p/>

Дигиталното подписване става от контекстно зависимо меню на папката с проекта в Eclipse. 

<p/>

<img src="0363.png" width="50%"/><br/>
<b>Фиг. 118</b> Хранилище за дигиталния ключ.

<p/>

Подписването се извършва с дигитален ключ, който се съхранява с специално създадено за тази цел хранилище. 

<p/>

<img src="0367.png" width="50%"/><br/>
<b>Фиг. 119</b> Информация за дигиталния ключ.

<p/>

Добрата практика за поддръжка на Android приложения е всяко приложение да бъде подписано с отделен дигитален ключ.

<p/>

<img src="0372.png" width="50%"/><br/>
<b>Фиг. 120</b> Дигитално подписаният изпълним файл, след публикуване.

<p/>

Google Play Store публикува единствено файлове, които са дигитално подписани от създателя им. Това се налага от съображения за сигурност и да бъде напълно известно кой точно е отговорен за съдържанието в изпълнимия файл.

<p/>

<img src="0375.png" width="50%"/><br/>
<b>Фиг. 121</b> Категоризиране на приложението.

<p/>

Освен име и описание, приложението трябва да бъде определено по категория и зрялост на аудиторията, която има право да го използва.

<p/>

<img src="0379.png" width="50%"/><br/>
<b>Фиг. 122</b> Компоненти за зрялост на аудиторията – насилие, сексуалност.

<p/>

Различните компоненти за зрялост на аудиторията са по по отношение на насилие, сексуално съдържание, вулгарен език и т.н.

<p/>

<img src="0380.png" width="50%"/><br/>
<b>Фиг. 123</b> Компоненти за зрялост на аудиторията – вулгарен език или хумор.

<p/>

Детайлността на категоризирането засяга дори актуални теми, като тероризма.
<p/>

<img src="0381.png" width="50%"/><br/>
<b>Фиг. 124</b> Компоненти за зрялост на аудиторията – локализиране и проследяване.

<p/>

Не всяко приложение е подходящо за разпространение в цял свят, за това има отделна секция в която се определя цената и териториите на които приложението може да се използва. 

<p/>

<img src="0388.png" width="50%"/><br/>
<b>Фиг. 125</b> Цена и територия на разпространение.

<p/>

За територията на САЩ е необходимо допълнително деклариране на обстоятелствата около публикуването на приложението.

<p/>

<img src="0391.png" width="50%"/><br/>
<b>Фиг. 126</b> Съгласуване с експортните закони на САЩ.

<p/>

За да се увеличат максимално шансовете потребителите да изберат точно това приложение, когато търсят какво да използват,  е необходимо да се направи добро графично представяне.

<p/>

<img src="0403.png" width="50%"/><br/>
<b>Фиг. 127</b> Рекламни банери и работни екрани.

<p/>

След приключване на процеса за публикуване са нужни няколко дни приложението да бъде одобрено от рецензентите в Google Play Store.

<p/>

<img src="0407.png" width="50%"/><br/>
<b>Фиг. 128</b> Изчакване на одобрение за публикуване.

<p/>

Втората възможност за публикуване е в най-голямото хранилище за Android продукти с отворен код, наречено F-Droid.

<p/>

<img src="0351.png" width="50%"/><br/>
<b>Фиг. 129</b> F-Droid.

<p/>

Процесът за публикуване в F-Droid е коренно различен, спрямо този в Google Play Store. Основната разлика се състои в това, че продуктът трябва да е с отворен код и да е публично достъпен в хранилище като GitHub. Това изискване е задължително, тъй като в F-Droid не се публикува изпълним файл. Системата на F-Droid автоматично изтегля програмния код и ресурсите, извършва компилацията и изготвя изпълним файл, който е дигитално подписан с ключове управлявани от инфраструктурата на F-Droid платформата. 

<p/>

<img src="0414.png" width="50%"/><br/>
<b>Фиг. 130</b> Клониране на проекта с описателните данни на F-Droid.

<p/>

Процеса за публикуване във F-Droid започва с клониране на проекта, съдържащ описателните данни на платформата F-Droid. По настояще, този проект се съхранява в GitLab хранилище.

<p/>

<img src="0418.png" width="50%"/><br/>
<b>Фиг. 131</b> Локален клонинг на проекта с описателните данни за F-Droid.

<p/>

От разклоненото хранилище в GitLab се прави издърпва локално копие. 

<p/>

<img src="0424.png" width="50%"/><br/>
<b>Фиг. 132</b> Допълнителен клон в локалното копие на проекта.

<p/>

За да протече гладко синхронизирането с основния проект в GitLab, в локалното копие се създава специално отделен клон, където ще бъде поместен описателния файл на приложението.

<p/>

<img src="0426.png" width="50%"/><br/>
<b>Фиг. 133</b> Описателен файл на приложението.

<p/>

За да се извърши публикуването е необходимо да се създаде описателен текстов файл, в папката metadata. 

<p/>

<img src="0428.png" width="50%"/><br/>
<b>Фиг. 134</b> Описание на приложението.

<p/>

В описателният файл най-важни са следните атрибути – кратко описание на приложението, адрес на хранилището от което да бъде изтеглен кодът, категория на приложението, дали има негативни за потребителя елементи (в случая има реклами), код на версия и най-важното хеш кода на публикацията в хранилището, която да бъде използвана за изграждане на изпълнимия файл. 

<p/>

<img src="0449.png" width="50%"/><br/>
<b>Фиг. 135</b> Публикуване на описателния файл в локалното хранилище.

<p/>

След като бъде изготвен описателният файл, то той трябва да бъде публикуван в хранилището на GitLab. 

<p/>

<img src="0450.png" width="50%"/><br/>
<b>Фиг. 136</b> Публикуване от локалното копие към глобалното хранилище на GitLab.

<p/>

Git е двустепенна система за контрол на версиите. Първоначално кодът се синхронизира в локално хранилище, а на втора фаза кодът се синхронизира с глобалното хранилище.

<p/>

<img src="0455.png" width="50%"/><br/>
<b>Фиг. 137</b> Създаване на merge request.

<p/>

Процесът на публикуване завършва със създаването на заявка за сливане на описателния файл към основния проект с описателни данни за платформата F-Droid.

<hr/>
<h1>
9. Заключение
</h1>

Разработването на софтуерни приложения за мобилни устройства е една от най-динамично развиващите се сфери на съвременния софтуер. Популярността и все по-снижаващата се цена на мобилните технологии правят този пазар все по-голям и все по-перспективен. В същото време, развитието на развойните инструменти дава възможност дори на хора с малък опит да се включат в глобалната икономика на софтуерните продукти. В настоящото изложение, макар и ограничено по обем, бе демонстрирано какви са стъпките за преминаване от идея за софтуерен продукт, до реално изработено и публикувано в Глобалната мрежа приложение. Макар и с минимална функционалност, представеното приложение е завършен продукт, кодът на който е публично достъпен и може да бъде доразвиван от всеки имащ желание да се включи в процеса. Двете основни неща, които значително биха подобрили предложеното софтуерно решения са модул за изкуствен интелект и възможности за мрежова игра.

</body>
</html>

