Index · Правила · Поиск· Группы · Регистрация · Личные сообщения· Вход

Список разделов Компьютерный раздел
 
 
 

Раздел: Компьютерный раздел Программирование приложений на android 

Создана: 31 Октября 2011 Пон 13:25:33.
Раздел: "Компьютерный раздел"
Сообщений в теме: 223, просмотров: 34914

На страницу: Назад  1,
, 3, ... 13, 14, 15  Вперёд
  1. 31 Октября 2011 Пон 13:25:33
    Набираю желающих в кружок
  2. 31 Октября 2011 Пон 15:53:56
    А Вы поставьте задачу. Если я Вас пойму может быть помогу.
  3. 01 Ноября 2011 Втр 7:28:47
    тема на телефоне - это фон главной страницы и других страниц, там где перечислены контакты, например, вот у меня тема чёрная, хотя с подсветом каким-то удалось скачать, но всё равно не понимаю как их ставить, хотелось бы что-то по ярче. Живые обои - это не то совсем, хотя написано, что с темой, а тем нет. Живые обои - это просто на рабочий стол, а странички по прежнему чёрные.
  4. 01 Ноября 2011 Втр 8:43:50
    я сдвинута на сумках, сегодня объясняла мужу, что они разделяются не только по цвету и размеру но еще и по сезону, то есть бывают зимние сумки, бывают летние, у него был шок, сказал знал бы не женился на мне, ответила что сумки не самое дорогое женское увлечение
  5. 01 Ноября 2011 Втр 9:16:54
    Игра "Судоку"

    Есть таблица 9*9. Задана некоторая расстановка цифр от 1 до 9. То есть некоторые ячейки таблицы заполнены. Надо заполнить остальные учитывая условие, что не должно быть повторов значений в строке, столбце и сегменте 3*3. То есть таблица разделена на блоки 3*3 и всего таких блоков девять.

    Существуют логические правила с помощью которых решается "Судоку". В частности методы "Одиночка" и "Скрытый одиночка"


    Некоторые рассуждения по поводу реализации алгоритма "Скрытый одиночка"

    Как игрок находит верные значения для ячеек таблицы ?
    Рассмотрим два наиболее простых метода заполнения ячеек: «Одиночка» и «Скрытый одиночка».

    Метод «Одиночка»

    Метод «Одиночка» основывается непосредственно на правилах судоку: любая цифра может встречаться только один раз в строке колонке и сегменте. То есть из списка девяти возможных цифр на заполнение ячейки надо вычеркнуть все цифры, которые уже проставлены в ячейках строки, столбца и сегмента.



    Рис.1

    Для демонстрации правил раскрасим выделенную ячейку в красный цвет, а связанные с нею в желтый.
    Например, для красной ячейки все ячейки принадлежащие второй строке или шестому столбцу или сегменту ячеек 3*3 будут связанными по содержанию, согласно правил Судоку. То есть в красной ячейке не может стоять цифра, которая уже использована в связанных ячейках – 2, 3, 4, 8.



    Рис.2

    Для ячейки окрашенной в серый цвет все цифры кроме девятки заняты и таким образом однозначно определяется ее значение.

    Метод «Скрытый одиночка»

    Мы сделали анализ для красной ячейки рис.1 и для желтой на рис.2 и выяснили что единственным возможным значением для желтой ячейки будет 9, а для красной ячейки существует несколько возможных значений, а именно 1, 5, 6, 7, 9. Точно так же можно составить списки возможных значений (кандидатов на заполнение ячеек) для каждой ячейки таблицы.

    Метод «Скрытый одиночка» использует правило: если среди возможных значений (кандидатов на заполнение) в строке/столбце/сегменте отдельная цифра встречается только в одной ячейке, то значение этой ячейки и будет равняться такой цифре.

    Этот метод используется когда уже вычислены списки кандидатов для ячеек. Для списков с числом элементов большим единицы определяем наличие уникального кандидата, который отсутствует в списках связанных ячеек.
  6. 01 Ноября 2011 Втр 9:22:32
    Собственно алгоритм "Одиночки"

    Наша задача создать список кандидатов на заполнение для каждой ячейки Судоку. Напомню что «список кандидатов» это те возможные значения, которые не противоречат правилам Судоку. А именно не должно быть повторов в строке, столбце, сегменте 3*3. Список кандидатов является инверсией списка использованных значений, то есть тех чисел, которые уже проставлены в других ячейках строки, столбца, сегмента которым принадлежит какая-то исследуемая в данный момент ячейка.

    Чтобы создать алгоритм нужны два списка.

    Один список, это массив (линейный) из девяти элементов. Сюда будем помещать значения уже занятые, для ячейки, которую исследуем.

    И второй массив из 81 элемента, тоже линейный. Отсюда будем брать информацию для анализа. Здесь будут храниться значения, которые в данный момент определенны для каждой из ячеек таблицы Судоку.


    Вот пример такого списка

    0090000000806050205010780000000007007060
    40102004000000000720903090301080000000600

    Из этого списка видно, в какой ячейке что стоит. Например, в первой ячейке стоит ноль, значит она пустая.


    Список заполняется по порядку строками, сначала первая строка, потом вторая и так далее. Для того чтобы выбрать значение из ячейки i-ой строки и j-го столбца нужно рассчитать номер элемента в списке следующим образом:

    k = i*9 + j

    Если исследуемая ячейка принадлежит i-ой строке , j-му столбцу то надо определить все числа уже в ячейках строки, столбца и сегмента.

    Например, ячейка принадлежит 5 столбцу и 4 строке. Цифры ячеек строки будут располагаться с номера 28 по 36. Цифры ячеек столбца будут располагаться по номерам 5, 14, 23, 32, 41, 50, 59, 68, 77.

    Для расчета адресов ячеек сегмента рассчитаем сначала адрес левой верхней ячейки сегмента.

    X = (i/3)*3

    Тут нами используется целочисленная операция деления чисел. То есть если разделить 4 на 3, то результат будет равен единице, дробная часть результата деления отбрасывается. Если разделить 2 на 3, то результат будет 0.

    Y=(j/3)*3

    Теперь осталось пройти по всем ячейкам Судоку и для каждой определить список занятых значений. Получится что-то вроде этого.

    Код для вызова процедуры расчета списка

    Код:

          for (int x = 0; x < 9; x++) {
             for (int y = 0; y < 9; y++)   {
                // Если длина списка кандидатов для текущей ячейки больше
                // единицы, то обращаемся к методу для поиска скрытого одиночки
                if (9-used[x][y].length > 1) calculateUsed_hsTilesErbol(x, y);
                
             }
          }


    Метод класса, который собственно осуществляет расчет списка

    Код:

       // Рассчитываем список уже использованных значений для ячейки
       // с координатами x, y
       private int[] calculateUsedTilesErbol(int x, int y) {
          // Определяем массив
          int c[] = new int[9];
          int c_hs[] = new int[9];
          // по горизонтали
          for (int i = 0; i < 9; i++) {
             // Исследуем содержание всех ячеек строки, в которой
             // находится вычисляемая ячейка, кроме нее самой
             if (i == y)
                continue;
             // Получаем содержание следующей ячейки строки
             int t = getTileErbol(x, i);
             // Если значение ячейки не нуль, то записываем ее в
             // элемент массива с[] с индексом равным полученному
             // значению минус 1
             if (t != 0)
                c[t - 1] = t;
          }
          // по вертикали
          for (int i = 0; i < 9; i++) {
             if (i == x)
                continue;
             int t = getTileErbol(i, y);
             if (t != 0)
                c[t - 1] = t;
          }
          // в блоке
          // Находим координаты левой верхней ячейки блока, которому
          // принадлежит исследуемая ячейка
          int startx = (x / 3) * 3;
          int starty = (y / 3) * 3;
          //  Исследуем содержание всех ячеек блока кроме той,
          // которую рассчитываем
          for (int i = startx; i < startx + 3; i++) {
             for (int j = starty; j < starty + 3; j++) {
                if (i == x && j == y)
                   continue;
                int t = getTileErbol(i, j);
                if (t != 0)
                   c[t - 1] = t;
             }
          }
          
          return c;
       }


    Метод, который осуществляет выборку нужного элемента списка из массива ячеек Судоку

    Код:

       // Возвращает как результат значение в ячейке таблицы с координатами x, y
       private int getTileErbol(int x, int y) {
          return puzzle[y * 9 + x];
       }
  7. 01 Ноября 2011 Втр 9:36:32
    А мы считаем что все знают яву? Или может для начала начнем с основ явы?
  8. 01 Ноября 2011 Втр 9:51:10
    Да трудно читать текст в котором расставлены неизвестные по смыслу слова.

    Я тоже не знаю java. Не помню чтобы что то писал на нем.

    Последняя программа которую я написал была на Basic. Года два назад , для жены. Написал макрос который обрабатывал текст и создавал форму нужную для тестирования студентов.

    По моему все языки одинаковые. Трудность в восприятии была с модификаторами. То есть встречаются в тексте слова типа private, final, static и т.д. А что они означают и зачем используются непонятно

    Про модификаторы

    Модификатор private делает элемент класса закрытым, им могут пользоваться только экземпляры того же самого класса
    В противоположность закрытости мы можем объявить некоторые члены класса открытыми, записав вместо слова private модификатор public. К таким членам может обратиться любой объект любого класса.

    Если у элемента вообще не указан модификатор уровня доступа, то такой элемент будет виден из подклассов и классов того же пакета. Именно такой уровень доступа используется в языке Java по умолчанию. Если же вы хотите, чтобы элемент был доступен извне пакета, но только подклассам того класса, которому он принадлежит, вам нужно объявить такой элемент protected. И наконец, если вы хотите, чтобы элемент был доступен только подклассам, причем независимо от того, находятся ли они в данном пакете или нет — используйте комбинацию private protected.
    Пометив метод модификатором final , можно запретить его переопределение в подклассах.

    Для переменных модификатор final имеет совершенно другой смысл. Если пометить модификатором final описание переменной, то ее значение (а оно должно быть обязательно задано или здесь же, или в блоке инициализации или в конструкторе) нельзя изменить ни в подклассах, ни в самом классе. Переменная превращается в константу. Именно так в языке Java определяются константы:

    public final int MIN_VALUE = -1, MAX_VALUE = 9999;

    По соглашению "Code Conventions" константы записываются прописными буквами, слова в них разделяются знаком подчеркивания.

    Иногда надо определить поле, общее для всего класса, изменение которого в одном экземпляре повлечет изменение того же поля во всех экземплярах. Такие поля называются переменными класса (class variables). Для переменных класса выделяется только одна ячейка памяти, общая для всех экземпляров. Переменные класса образуются в Java модификатором static .

    Операция new

    Пора подробнее описать операцию с одним операндом, обозначаемую словом new . Она применяется для выделения памяти массивам и объектам.

    В случае создания экземпляра класса операндом new служит конструктор класса. Если конструктора в классе нет, то вызывается конструктор по умолчанию.

    Числовые поля класса получают нулевые значения, логические поля — значение false , ссылки — значение null .
    Результатом операции new будет ссылка на созданный объект. Эта ссылка может быть присвоена переменной типа ссылка на данный тип:

    Dog k9 = new Dog () ;

    но может использоваться и непосредственно

    new Dog().voice();

    Здесь после создания безымянного объекта сразу выполняется его метод voice() . Такая странная запись встречается в программах, написанных на Java, на каждом шагу.

    Классы


    Идея классов в программировании основана на повторном использовании кода. Интересно. Прежде чем писать программу надо поспрашивать - решал ли кто нибудь подобную задачу. Тем более что есть форма определенная в которой хранится весь код готовый для использования. Эта форма состоит из полей , методов и обработчиков и называется класс.

    Описание класса начинается со слова class, после которого записывается имя класса. Имя класса рекомендуется писать с заглавной буквы. Перед словом class можно записать модификаторы класса (class modifiers). Это одно из слов public, abstract, final, strictfp. Тело класса, в котором в любом порядке перечисляются поля, методы, вложенные классы и интерфейсы, заключается в фигурные скобки. При описании поля указывается его тип, затем, через пробел, имя и, может быть, начальное значение после знака равенства, которое можно записать константным выражением. Описание поля может начинаться с одного или нескольких необязательных модификаторов public, protected, private, static, final, transient, volatile . При описании метода указывается тип возвращаемого им значения или слово void , затем, через пробел, имя метода, потом, в скобках, список параметров. После этого в фигурных скобках расписывается выполняемый метод. Описание метода может начинаться с модификаторов public, protected, private, abstract, static, final, synchronized, native, strictfp. В списке параметров через запятую перечисляются тип и имя каждого параметра. Перед типом какого-либо параметра может стоять модификатор final . Такой параметр нельзя изменять внутри метода. Список параметров может отсутствовать, но скобки сохраняются.

    Имя метода, число и типы параметров образуют сигнатуру (signature) метода. Компилятор различает методы не по их именам, а по сигнатурам. Это позволяет записывать разные методы с одинаковыми именами, различающиеся числом и/или типами параметров. Тип возвращаемого значения не входит в сигнатуру метода, значит, методы не могут различаться только типом результата их работы. Например компилятор будет различать между собой два метода erbol(int x,int y) и erbol(string destination) так у них разные входные параметры. Такое дублирование методов называется перегрузкой (overloading).
  9. 01 Ноября 2011 Втр 9:53:16
    Это все понятно. Я например пишу в С#. В яве принцип похожий, просто хотелось бы понять структуру простой программы на яве.
  10. 01 Ноября 2011 Втр 10:09:05
    Тот вариант java который используется для программирования android имеет несколько сущностей первого порядка

    Намерение (Intent) , окно (форма) в терминологии java - activity и ресурсы.

    Создав проект в eclipse Вы увидите папку корневую с названием проекта в которой лежит файл AndroidManifest.xml и вложенные папки.

    В AndroidManifest задается состав проекта (из каких активити он состоит) и первое запускаемое активити

    Папка src - для файлов с классами java.

    res - для файлов с расширением xml. То есть разметка всех окон приложения может быть выполнена с помощью инструкций XML

    Все советуют оформление окна, то есть расстановку элементов управления выполнять через xml - файлы.
  11. 01 Ноября 2011 Втр 10:25:59
    А где класс Main? Или где код пишется?
  12. 01 Ноября 2011 Втр 10:39:39
    Android запускает Activity которое указано в AndroidManifest.

    В AndroidManifest начальное activity определяется с помощью инструкции
    Код:

            <activity android:name=".Murat"
                      android:label="@string/app_name">
    <!—
    Имя начального activity
    —>                 
         
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>


    Каждое activity имеет жизненный цикл, то есть события которые обрабатываются методами этого класса

    Таким образом весь код который Вы хотите выполнить для инициализации приложения (создания логики и интерфейса) помещается в метод onCreate()

  13. 04 Ноября 2011 Птн 12:54:09
    Еще немного рассуждений

    Опять рассуждаем (а когда же программы будем писать ?)

    Для начала сформулируем наше видение ситуации с программой. Типа, что она должна уметь и как с ней общаться.

    Легкий вариант (программа-минимум). Представим что на входе программы есть данные о первоначальной расстановке цифр в таблице Судоку. В качестве такой информации мы «вшиваем» в программу строчку состоящую из цифр от 0 до 9. Эта строчка поможет нам начать. То есть расставить цифры в нужные ячейки. Номер позиции цифры в строке говорит нам о номере ячейки а сама цифра о значении которую нужно поместить в ячейку.

    Все таки строкой пользоваться не очень удобно поэтому надо поместить данные в линейный массив , его удобнее обрабатывать.

    Мы тут озаботились решаемостью Судоку, то есть хотим облегчить игроку жизнь и дать ему подсказку , типа куда какую цифру можно поставить. Делать это будем используя два метода решения Судоку – «одиночка» и «скрытый одиночка». Для того чтобы реализовать эти методы нам необходимо для каждой ячейки составить список «занятых» значений, которые нельзя использовать для заполнения. Получается 81 штука именованных списков. Имена списков составные, это номер строки и номер столбца, в которых находится ячейка. Формально это трехмерный массив.

    Кроме того для наших нужд удобно создать массив содержащий список разрешенных значений для каждой ячейки Судоку. Он будет инверсным по отношению к массиву «занятых» значений. То есть если для ячейки запрещены значения 1 и 2, то список разрешенных значений будет – 3, 4, 5, 6, 7, 8, 9. В общем понятно.
    Способ и логику создания подсказок для игрока мы еще обсудим по ходу дела.

    Хочу остановится на некоторых особенностях работы с андроидом. Изображение на экране андроида переворачивается когда мы вертим его в руках. Интересно.

    Что происходим в этом случае с данными введенными в Судоку ? Игрок увидит, что все значения которые он ввел в ячейки исчезли. Происходит это потому, что при перевороте андроида происходит перезапуск активного окна. Окно «умирает» а потом инициализируется. С этим надо бороться. План такой – у объекта View который мы используем как площадку для рисования есть хеш, называется он Bundle. При наступлении события «переворот андроида» мы будем сохранять все данные введенные пользователем в хеш. В момент инициализации эти данные будут выниматься из хеша и снова помещаться в таблицу Судоку. Отлично.

    Что такое хеш ? Хеш это таблица состоящая из двух столбцов и нескольких строчек. В первый столбец помещается имя величины, во второй ее значение.

    Что будем помещать в хеш? Первое это координаты активной ячейки Судоку (номер ячейки в строке и в столбце) и второе это значения которые помещены в ячейки Судоку. Если ячейка пустая ставим ноль. Значения в ячейках будем сохранять в виде строки состоящей из 81 символа. То есть нам необходимы процедуры, которые умеют преобразовывать данные из массива в строку и обратно.

    Хотя можно избежать разрушения activity если в файле AndroidManifest.xml использовать инструкцию

    android:configChanges="orientation"

    Тогда открывающий тег activity будет выглядеть так

    <activity android:name=".Murat"
    android:configChanges="orientation"
    android:label="@string/app_name">

    Или запретить изменение ориентации экрана. Вот ссылка на код
    [внешняя ссылка]

    Дальше надо каким то образом организовать ввод данных в ячейки таблицы. Экран у нас сенсорный поэтому будем использовать клавиши управления курсором или тыкать пальцем в нужную ячейку и вводить в нее нужное число. Ввод можно выполнять с клавиатуры и для более продвинутого интерефейса создать keypad c цифрами и выбирать нужную цифру с его помощью. Причем желательно чтобы на keypad отображались только те цифры которые не противоречат правилам Судоку для данной ячейки.

    Пусть еще во время игры музыка какая нибудь играет, типа – будь бодрым

    Далее. Нам надо нарисовать саму таблицу и цифры которые стоят в ячейках таблицы. В общих словах все.
  14. 09 Ноября 2011 Срд 16:50:10
    Установка ПО необходимого для создания приложений под android описана в статьях
    [внешняя ссылка]
    [внешняя ссылка]

    Устанавливаем и создаем новый проект.

    Выполняем команду File  New  Android Project. Заполняем форму
    Project Name : Ira
    Build Target : Ставим галочку Android 3.1
    Application Name : Ira
    Package Name : com.ira
    Create Activity : Ira
    В папке src видим файл Ira.java. Открываем
    Код:

    package com.ira;

    import android.app.Activity;
    import android.os.Bundle;

    public class Ira extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
    }



    У нас есть четыре структуры данных.
    1. Строка, назовем ее puz. В ней указанны значения ячеек по порядку, строка за строкой. Всего 81 символ
    2. Массив линейный из 81 элемента, назовем его puzzle[9*9]. Опять же значение ячеек Судоку располагаются в массиве строка за строкой. То есть сначала указаны 9 значений первой строки по порядку. Потом второй и так далее.
    3. Массив used[9][9][]. Трехмерный. Сюда будем писать списки занятых значений для каждой ячейки. Обозначение used[9][9][] определяет массив с 9 строками, 9 столбцами. Значение третьего индекса не определенно. То есть он может быть произвольной длины.
    4. Массив used[9][9][9]. Сюда будем писать значения которые можно использовать для заполнения ячеек Судоку.

    Инициализация массивов

    На входе программы вся информация о расположении цифр в Судоку находится в строке puz. Массивы пустые, т.е. все их элементы заполнены нулями. Надо создать механизмы переноса информации из строки в массивы
    Сначала заполняем массив puzzle[9*9]. Для этого считываем посимвольно строку puz и переносим значение в массив.

    Код:
       // Преобразуем строку в одномерный массив
       private int[] getPuzzle(String puz) {
          return fromPuzzleString(puz);
          }

       
       static protected int[] fromPuzzleString(String string) {
          // Создаем массив с числом элементов равным длине строки
          int[] puz = new int[string.length()];
          // Читаем строку слева направо с начала до конца
          for (int i = 0; i < puz.length; i++) {
             // http://programmersforum.ru/showthread.php?t=15034
             puz[i] = string.charAt(i) - '0';
          }
          return puz;
       }



    Смысл выражения «string.charAt(i) - '0'» в получении цифры из кода цифры. java хранит символы в Unicode кодировке, т.е. в виде 2 байтного числа.

    Как сделать из 2-х байтного кода числа само число ?

    Известно ASCII кодировка цифр '0' = 30h, '1' = 31h, '2'= 32h, ..., '9'=39h.
    Для того чтобы получить число достаточно вычесть из кода числа значение кода нуля. Например, так: 35h-30h=5h, короче получаем число 5 из кода числа 5.

    Обратный процесс превращения массива в строку нам тоже понадобится. Вот он

    Код:
        static private String toPuzzleStringErbol(int[] puz) {
                StringBuilder buf = new StringBuilder();
                for (int element : puz) {
                   buf.append(element);
                }
                return buf.toString();
        }


    Теперь определим массивы used[9][9][] и used_hs[9][9][9]. Надо заметить, что для обоих массивов расчет выполняется два раза – сначала по методу «одиночки», а потом по методу «скрытого одиночки».

    Код:
       private void calculateUsedTiles() {
          // Двойной цикл с одним оператором, который вызывает метод для расчета
          // списка уже использованных значений для каждой ячейки таблицы
          for (int x = 0; x < 9; x++) {
             for (int y = 0; y < 9; y++)   {
                used[x][y] = calculateUsedTiles(x, y);
             }
          }
          
          
          for (int x = 0; x < 9; x++) {
             for (int y = 0; y < 9; y++)   {
             // Если длина списка кандидатов для текущей ячейки больше
             // единицы, то обращаемся к методу для поиска скрытого одиночки
             if (9-used[x][y].length > 1) calculateUsed_hsTiles(x, y);
                
             }
          }

       }



    Расчет массивов по методу «одиночка»

    Код:
       private int[] calculateUsedTiles(int x, int y) {
          // Определяем массив
          int c[] = new int[9];
          int c_hs[] = new int[9];
          // по горизонтали
          for (int i = 0; i < 9; i++) {
             // Исследуем содержание всех ячеек строки, в которой
             // находится вычисляемая ячейка, кроме нее самой
             if (i == y)
                continue;
             // Получаем содержание следующей ячейки строки
             int t = getTile(x, i);
             // Если значение ячейки не нуль, то записываем ее в
             // элемент массива с[] с индексом равным полученному
             // значению минус 1
             if (t != 0)
                c[t - 1] = t;
          }
          // по вертикали
          for (int i = 0; i < 9; i++) {
             if (i == x)
                continue;
             int t = getTile(i, y);
             if (t != 0)
                c[t - 1] = t;
          }
          // в блоке
          // Находим координаты левой верхней ячейки блока, которому
          // принадлежит исследуемая ячейка
          int startx = (x / 3) * 3;
          int starty = (y / 3) * 3;
          //  Исследуем содержание всех ячеек блока кроме той,
          // которую рассчитываем
          for (int i = startx; i < startx + 3; i++) {
             for (int j = starty; j < starty + 3; j++) {
                if (i == x && j == y)
                   continue;
                int t = getTile(i, j);
                if (t != 0)
                   c[t - 1] = t;
             }
          }
          
          // Сохраняем список кандидатов в массив used_hs
          for (int i = 0; i < 9; i++) {
             if (c[i]==0)
                c_hs[i]=i+1;
             else
                c_hs[i]=0;
          }
          used_hs[x][y]=c_hs;
          

          
          
          
          // Сжатие массива состоит в том, что мы сначала подсчитываем число
          // ненулевых значений в массиве «с» и сохраняем это значение в
          // величине nused. Затем создаем новый массив «с1» с числом элементов
          // равным nused и заполняем его ненулевыми значениями из массива «c».
          int nused = 0;
          for (int t : c) {
             if (t != 0)
                nused++;
          }
          int c1[] = new int[nused];
          nused = 0;
          for (int t : c) {
             if (t != 0)
                c1[nused++] = t;
          }
          return c1;
       }


    Расчет массивов по методу «скрытый одиночка»

    Код:
       private void calculateUsed_hsTiles(int x, int y) {
          // x - Индекс ячейки в строке
          // y - Индекс ячейки в столбце
          
          int c[] = new int[8];
          int flag;

          
          // по горизонтали
          // Первый цикл перебирает значения в списке кандидатов
          // Выбираем ненулевое значение из списка и проходим по спискам
          // всех ячеек строки. Если находим совпадение увеличиваем счетчик
          for (int i = 0; i < 9; i++) {
             // Условие выполнения внутреннего цикла состоит в том,что
             // очередной элемент списка кандидатов не равен нулю
             if (used_hs[x][y][i]==0) continue;
             // Если элемент равен нулю то переходим к следующему шагу цикла
             
             flag=0;
             
             // Второй цикл перебирает списки кандидатов для ячеек строки
             for (int j = 0; j < 9; j++) {
                // Если значение переменной цикла равно номеру ячейки в строке
                // то ничего не делаем
                if (j == x)
                   continue;
                if (getTile(j, y)>0)
                   continue;
                // Если ячейка уже заполнена то ничего не делаем

                
                if (used_hs[x][y][i]==used_hs[j][y][i]) {
                   flag++;
                   break;
                }
                
             }
             
             int nused = 0;
             if (flag==0) {

                for (int k=0;k<9;k++){
                   if (k != i) c[nused++] = k + 1;
                }
                
                used[x][y] = c;
                // Заканчиваем поиск скрытого одиночки, потому что нашли
                return;
             }

          }
          
          
          // по вертикали
          // Первый цикл перебирает значения в списке кандидатов
          for (int i = 0; i < 9; i++) {
             // Условие выполнения внутреннего цикла состоит в том,что
             // очередной элемент списка кандидатов не равен нулю
             if (used_hs[x][y][i]==0) continue;
             // Если элемент равен нулю то переходим к следующему шагу цикла
             
             flag=0;
             
             // Второй цикл перебирает списки кандидатов для ячеек столбца
             for (int j = 0; j < 9; j++) {
                //
                if (j == y)
                   continue;
                if (getTile(x, j)>0)
                   continue;
                
             
                if (used_hs[x][y][i]==used_hs[x][j][i]) {
                   flag++;
                   break;
                }
                
             }
             int nused = 0;
             if (flag==0) {
                for (int k=0;k<9;k++){
                   if (k != i) c[nused++] = k + 1;
                }
                
                used[x][y] = c;
                // Заканчиваем поиск скрытого одиночки, потому что нашли
                return;
             }

          }

          // в блоке
          // Находим координаты левой верхней ячейки блока, которому
          // принадлежит исследуемая ячейка
          int startx = (x / 3) * 3;
          int starty = (y / 3) * 3;
          // Исследуем содержание всех ячеек блока кроме той,
          // которую рассчитываем
          for (int k = 0; k < 9; k++) {
             
             if (used_hs[x][y][k]==0) continue;
             flag=0;
             
             for (int i = startx; i < startx + 3; i++) {
                for (int j = starty; j < starty + 3; j++) {

                   if (i == x && j == y)
                      continue;
                   if (getTile(i, j)>0)
                      continue;
                   

                   
                   if (used_hs[x][y][k]==used_hs[i][j][k]) {
                      
                      flag++;
                      break;
                   }               
                }
                
                if (flag>0) break;
             }

             int nused = 0;
             if (flag==0) {

                for (int m=0;m<9;m++){
                   if (m != k) c[nused++] = m + 1;
                }
                
                used[x][y] = c;
                // Заканчиваем поиск скрытого одиночки, потому что нашли
                return;
             }
       
          }

       }


    Ну и код для процедуры private int getTile(int x, int y)

    Код:
       // Возвращает как результат значение в ячейке таблицы с координатами x, y
       private int getTile(int x, int y) {
          return puzzle[y * 9 + x];
       }


    Для того чтобы запустить приложение вставим в определение класса Ira.java объявления переменных

    Код:
       private final int used_hs[][][] = new int[9][9][9];
       
       private final int used[][][] = new int[9][9][];
       public int puzzle[] = new int[9 * 9];
       private final String puz = "046050107030400905000001000500000010004907500020000008000300000103005070408070320";


    В метод onCreate() класса помещаем вызовы методов, которые заполняют массивы. Они будут выполнены в момент инициализации окна

    Код:
            // Инициализация массива puzzle
          puzzle = getPuzzle(puz);
          // Инициализация массивов used и used_hs
          calculateUsedTiles();



    Запускаем приложение. Run Run

    В результате видим перед собой окно с именем приложения, пиктограммой и приветствием на английском языке.
  15. 11 Ноября 2011 Птн 16:51:18
    Рисуем Судоку

    Для этого нам понадобится еще один класс. Класс View.

    Он имеет метод onDraw(Canvas canvas) приспособленный для рисования. Этот метод запускается в момент создания объекта view. Также можно его запустить с помощью метода invalidate(). То есть если нужно перерисовать картинку, то просто пишем в программе invalidate() и картинка перерисовывается. Метод invalidate может иметь аргумент. Если нужно перерисовать не всю картинку, а только отдельную область то пишем invalidate(Rect). Где Rect - объект типа прямоугольник.

    Кроме метода onDraw(Canvas canvas) нам понадобится еще метод onSizeChanged(int w, int h, int oldw, int oldh). Как видно входными параметрами для него служат новые и старые размеры активного окна. Понятно что этот метод используется для масштабирования размеров всех визуальных элементов окна при изменении высоты и ширины окна. Вызывается он после того как android узнает размер активного окна при его запуске или изменении. onSizeChanged() используется в программе для вычисления размера каждой ячейки на экране (1/9-ая от полной ширины и высоты вьюера).

    Вроде бы все об используемых методах. Теперь оформление.

    Создаем в папке src новый файл IraView.java

    Чтобы рисовать надо
    1. Задать краски. Создаем файл colors.xml
    2. Задать размеры области рисунка и отдельной ячейки
    3. И, как это говорится - пофиксить класс Ira.java

    Вот текст IraView.java

    ------

    Замучился искать слова которые фильтр не пропускает. Вот ссылка на этот пост

    [внешняя ссылка]
  16. 13 Ноября 2011 Вск 11:50:23
    Немного информации про методы объектов Canvas и Paint (они используются нами для рисования Судоку)

    Для задания цветов создаются обьекты класса Paint. Цвет задается в формате ARGB, т.е. представлен 4 числами, по одному для альфа-канала, красному, зеленому, и синему (ARGB). Каждый компонент может иметь 256 возможных значений, или 8 бит, поэтому цвета обычно упакованы в трицатидвухразрядные целые. Для эффективности Android использует целые 32-х разрядные числа

    Альфа-канал – это измерение прозрачности. Самое низкое значение, 0, соответствует тому, что цвет полностью прозрачен. Если альфа-канал равен 0, цвет в RGB не имеет никакого значения. Самое высокое значение, 255 показывает цвет полностью. Значения в середине диапазона используются для просвечивания или полупрозрачности.

    Paint это не только класс для хранения информации о цвете. Например, при рисовании текста он содержит информацию о способе закрашивания, шрифте и выравнивании текста.

    Canvas содержит набор методов для рисования графики (drawRect, drawLine, drawPath, drawText и другие).
    Метод drawLine имеет пять аргументов – координаты x , y первой точки, координаты x, y второй точки и объект типа paint который задает цвет линии.

    Например, так

    canvas.drawLine(0, i * height, w_erbol, i * height, light);

    Метод drawRect тоже имеет пять аргументов. Координаты верхнего левого угла, нижнего правого и объект типа paint

    canvas.drawRect(0, 0, w_erbol, h_erbol, background);

    Метод drawText имеет четыре аргумента – текст типа строка, координаты x, y центра рисуемого текста, параметр типа paint который определяет цвет текста, размер, стиль, пропорции, выравнивание.

    canvas.drawText(getTileStringErbol(i, j), i* width + x, j * height + y, foreground);
На страницу: Назад  1,
, 3, ... 13, 14, 15  Вперёд