Крестики нолики для android studio

Игры на Android: Крестики-нолики (Custom View)

Напишем ещё один вариант игры на основе собственного компонента. Наткнулся на руководство из трёх частей (ссылки внизу). Решил частично перевести материал, чтобы посмотреть на ещё одну реализацию игры.

Создадим класс TicTacToeView. Для игрового поля нам понадобятся две вертикальные и две горизонтальные линии, которые должны разделить экран на три равные части по вертикали и горизонтали. Соответственно, чтобы получить нужные координаты для линий, нужно вспомнить немного математики. Для первой вертикальной линии начальную координату X можно вычислить, если ширину доступной области разделить на 3 и умножить на 1. Для второй линии ширину следует разделить на 3 и умножить на 2. По такому же принципу вычисляем координаты для горизонтальных линий.

Разделив линиями экран, мы получили девять прямоугольников. Нам нужно вычислить координаты этих прямоугольников, чтобы иметь возможность определять область нажатия и вывода текста(X или О). Создадим два массива, первый массив для хранения прямоугольников (объекты Rect), второй — для текста, который будет выводиться в центре прямоугольников.

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

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

Текст выводится не по центру, что очень некрасиво. Опять понадобятся знания по математике. Нам нужно вычислить размеры текста (отдельные методы для ширины и высоты) и затем найти нужную позицию на основании полученных данных.

Добавим код в метод drawTextInsideRectangle().

Запустите пример и убедитесь сами, что теперь текст выводится по центру.

Определение касания экрана

Метод onTouchEvent() позволяет определить точку касания через параметры event.x и event.y. У Rect есть метод contains() позволяющий узнать, является ли точка частью прямоугольника. Мы можем пройтись по всем прямоугольникам игровой площадки в массиве и вычислить, к какому прямоугольнику относится точка касания. Таким образом мы получим индекс прямоугольника.

Если запустить пример и касаться в разных местах экрана, то получим значения (0, 1), (2, 2) и т.д. На основе этой информации мы можем что-то делать с выбранным прямоугольником, например, подсветить его другим цветом.

Добавим глобальную переменную, чтобы понимать, когда можно отрисовывать прямоугольник и вызовем invalidate() для перерисовки. В методе onDraw() добавим новую функцию.

Настало время вывести X или O на месте выбранного прямоугольника. Два новых метода заполняют массив нужными значениями и вызывают перерисовку.

В третьей части рассказывает об анимации. Все ссылки ниже.

Источник

Крестики-нолики

Вместо предисловия

Однажды я написал статью на Хабре. Один из читателей сказал, что тоже написал одну статью про создание игры «Крестики-нолики», но боится её выкладывать на всеобщее обозрение. Я и несколько других комментаторов сумели убедить его опубликовать свой материал, который вы можете прочитать здесь. В статье речь шла о создании игры в IntelliJ IDEA Community Edition. Если кому-то интересно, то ознакомьтесь с оригиналом статьи, а также почитайте комментарии. Я в свою очередь немного отредактировал статью и сам код игры.

Статья затронет весь цикл разработки приложения. Вместе мы напишем простенькую игру “Крестики-Нолики” с одним экраном.

Для нашего приложения идеально подойдёт макет TableLayout с идентификатором android:id=»@+id/tableLayout».

Программный доступ к TableLayout:

Теперь необходимо реализовать метод buildGameField(). Для этого требуется создать поле в виде матрицы. Этим будет заниматься класс Game. Сначала нужно создать класс Player, объекты которого будут заполнять ячейки игрового поля и класс Square для самих ячеек.

Player.java

Square.java

Game.java

Метод buildGameField() динамически добавляет строки и колонки в таблицу (игровое поле):

В коде создаётся объект, реализующий интерфейс View.OnClickListener. Создадим вложенный класс Listener. Он будет виден только из активности.

Осталось реализовать логику игры. Возвращаемся к Game.java:

Определение победителя

Очевидно, что в крестики-нолики выигрывает тот, кто построит X или O в линию длиной, равной длине поля по вертикали, по горизонтали или по диагонали. Первая мысль, которая приходит в голову — это написать методы для каждого случая. Думаю, в этом случае хорошо подойдёт паттерн Chain of Responsobility. Определим интерфейс:

Так как Game наделён обязанностью выявлять победителя, он реализует этот интерфейс. Настало время создать виртуальных «лайнсменов», каждый из которых будет проверять свою сторону. Все они реализует интерфейс WinnerCheckerInterface.

WinnerCheckerHorizontal.java

WinnerCheckerVertical.java

WinnerCheckerDiagonalLeft.java

WinnerCheckerDiagonalRight.java

Проинициализируем их в конструкторе Game:

Возвращаемся в класс активности. Победителя проверяем после каждого хода. Добавим код в метод onClick() класса Listener

Метод gameOver() реализован в 2-х вариантах.

Метод makeTurn() проверяет очерёдность хода игрока, а метод refresh() обновляет состояние поля:

Весь код активности.

Видео готового приложения

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

Дополнительное чтение

SavvaVyatkin/CatDogToe — правильный вариант игры с участием котов. Картинка для статьи взята из этого проекта.

Источник

Крестики нолики для android studio

Эта статья покажет нам, как сделать Крестики-нолики (англ. Tic-tac-toe) для операционной системы Android. Игра будет обладать тремя уровнями сложности, режимом Битвы, возможностью продолжить игру после закрытия приложения и уметь переключаться между английской и русской локализацией в зависимости от настроек телефона. Также мы нарисуем нестандартные красивые кнопки, используя элементы и .

Читайте также:  Копировать все сообщения с андроида

Для успешной работы нам будут нужны установленные Eclipse, JDK, Android SDK, ADT плагин и начальные знания Java и Android. Полная версия исходного кода лежит в SVN репозитории здесь. Загрузить можно с помощью командной строки «svn checkout http://tic-tac-toe-app.googlecode.com/svn/trunk/ tic-tac-toe-app-read-only». Там же можно скачать приложение Tic Tac Toe 1.1.apk во вкладке download и установить его на телефон.

Внешний вид и selector’ы

Стандартные контролы вызывают у пользователей скуку, поэтому, практически все приложения в android market’e, обладают своими дизайнерскими решениями. Корпорация Google создала для этого мощный описательный инструмент стилей и элементов, основанный на xml. С его помощью можно задавать общий стиль групп элементов и рисовать свои новые контролы.

Для начала создадим в среде Eclipse новое приложение и назовем его Tic Tac Toe, установим в качестве Build Target — Android 1.6 и Create activity: TicTacToe.

Автоматически будет создан файл TicTacToe.java. Это activity, она будет вызываться при запуске приложения. Среда Android узнает об этом из файла AndroidManifest.xml, где для нашей activity задан :

Перейдем непосредственно к созданию интерфейса. В качестве корневого элемента main.xml мы положим ScrollView , этот элемент позволит нам прокручивать нашу activity, если контролы в горизонтальном положении телефона выйдут за пределы формы. Следующим элементом идет LinearLayout , благодаря ему мы разместим наши кнопки стройно в ряд, задав все необходимые отступы.

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

Наш selector содержит описание нажатого состояния и состояния покоя. Во втором случае мы заливаем кнопку градиентом, задавая startColor и endColor . Сorners указывает на углы нашей кнопки. Для эффекта нажатого состояния мы уменьшаем угол скругления и заменяем градиент монотонным цветом. Все имена атрибутов легко читаемы, их полный список можно посмотреть на официальном сайте Shape Drawable.

Чтобы не описывать, каким будет размер шрифта и стиль текста в каждой кнопке, мы зададим один общий для всех, создав в папке values файл styles.xml.

Тогда xml текст кнопки будет простой:

В итоге у нас получается интересная первая activity:

Стратегия игры

Классические «крестики-нолики» на поле 3×3 имеют достаточно короткое описание всех вариантов состояний. При совершенной игре результат всегда будет сведен к ничьей, если один из соперников не совершит ошибку. Для игры за компьютер (нолики) мы будем использовать простой принцип приоритета клеток. Максимальным приоритетом будет обладать центральное поле. Вторыми по очереди будут поля в углах, и самые нежеланные будут оставшиеся поля в середине.

Весь алгоритм можно описать так:

  • Если можно сделать шаг ведущий к выигрышу — делаем. Иначе,
  • Если нужно блокировать возможность выигрыша соперника — блокируем. Иначе
  • Делаем ход в ячейку с максимальным приоритетом.

Три уровня сложности будут такими, для Hard придерживаемся вышеописанного алгоритма, к слову, он упрощен и обыграть его имеются возможности. Для Easy будем ставить нолик в случайную ячейку, а для Medium мы будем делать в такой пропорции: один из трех будет глупый ход, два из трех — умные.

Tic-tac-toe layout

Создадим game.xml layout для отображения процесса игры. Мы будем использовать TableLayout с тремя строками и столбцами для поля 3×3. В каждой ячейке будет лежать кнопка с пустой или заполненной картинкой.

TableRow обеспечивает горизонтальное распределение всех принадлежащих ему контролов. Чтобы наша сетка не сливалось в единое целое, зададим необходимые отступы для каждой ячейке layout_margin Right, Left, Top или Bottom. При нажатии на пустую кнопку, мы будет рисовать в ней «крестик». Ход компьютера будет рисовать ответный «нолик».

Model-view-controller

Теперь немного об архитектуре нашей игры. Для реализации режима битвы и возможности продолжить играть после закрытия activity, нам нужно будет хранить текущее состояние (счет, заполненные ячейки). В этом нам помогут такие шаблоны проектирования как model-view-controller для разделения логики и singleton для хранения состояния. Шаблон MVC позволит разделить данные, представление и обработку действий пользователя на три отдельных компонента, что облегчит реализацию алгоритма игры и дальнейшее сопровождение программы.

В модели (см. TicTacToeModel.java) мы реализуем два метода, doSmartMove() для хорошего хода и doStupidMove() для случайного. В случае, когда уровень сложности выбран Medium, мы будем делать два умных и один глупый ходы. Модель также будет хранить счет выигранных и проигранных боев.

Задача controller’а обновлять ход игры по запросу, а в роли view выступает сама Activity.

Локализация

География Android устройств обширна, поэтому вопрос локализации занимает ключевое место при разработке приложений под эту платформу. К счастью, нам не прийдется изобретать велосипед, Google позаботился о разработчиках в этом вопросе.

Правила локализации приложений таковы — мы создаем несколько наборов ресурсов, первый — по умолчанию res/values/strings.xml , остальные для нужной нам локали res/values- /strings.xml , например, values-en для английского или values-ja для японского. При запуске activity Android выбирает какие ресурсы загрузить, основываясь на локали самого устройства. К слову, под ресурсами в Android подразумеваются не только текстовые строки, а также layout’ы, звуковые файлы, графика и другие статические данные.

Для нашего приложения мы создадим папки res/values , res/values-en и res/values-ru , в них будут лежать файлы strings.xml. Эти файлы содержат название приложения, сообщения и вопросы. Английский файл выглядит так:

Еще нюанс, android developer’s guide предупреждает нас о необходимости иметь точную копию какой-нибудь локализации в качестве ресурса по умолчанию, чаще всего — английскую. И приводит пример, что если не будет хватать строки в файле res/values/strings.xml , которая есть в res/values-en/strings.xml и используется в приложении, то возможно все будет компилироваться без проблем, но в локали отличной от английской пользователь увидит сообщение об ошибке и кнопку о закрытии приложения.

Читайте также:  Айфон 11 переход с андроид

Заключение

Весь java код приложения можно изучить, скачав его из SVN репозитория здесь. В итоге у нас получились вот такие локализованные крестики-нолики:

Источник

Крестики-нолики

В этой статье, приуроченной к онлайн-курсу Android Developer. Basic, мы напишем свою собственную небольшую игру «Крестики-нолики». Для работы потребуется установить Android Studio. Какая у вас ОС — не имеет значения, т.к. эта IDE работает на Windows, Ubuntu или Mac. Язык программирования будет Kotlin, т.к. сейчас он является официальным языком для программирования на Android. Во время написания статьи использовалась версия Android Studio 4.1.3

Создание проекта

Для начала необходимо создать новый проект. В нашем случае необходимо выбрать Fragment + ViewModel и нажать Next.

Далее в поле Name вводите название приложения, в Package name можете внести свое имя или ник как доменное имя, но с зада на перед. Это нужно для уникальности вашего приложения в маркете и на телефоне. Все остальное можно оставить по умолчанию как на картинке. Далее нажимаем Finish и ждем, когда проект соберется и мы сможем работать.

Нам нужно добавить зависимости которых нам не хватает в build.gradle модуля в раздел dependencies. А так же включить viewBinding для того, чтобы было удобна делать связь верстки с кодом (смотри изображение)

Верстка экрана

Теперь можно преступить к верстанию экрана. Для начала мы добавим только несколько вьюшек. Для того, чтобы не нужно было у каждой вьюшке проставлять отступы от края экрана, воспользуемся специальным виджетом `Guideline`. Он позволяет выставить границы, за которые будут «цепляться» вьюшки. Если у вас экран открылся в режиме `Design`, то я рекомендую перейти в режим `Split`. Так удобнее мне объяснять и можно будет копировать однотипные элементы. Чтобы добавить Guideline можно внутри элемента `ConstraintLayout` написать ` android:id напишем @+id/ плюс название в зависимости от расположения (start, end, top, bottom). В параметре android:orientation поставим vertical/horizontal в зависимости от направления линии. И изменить параметр app:layout_constraintGuide_begin на app:layout_constraintGuide_end для элементов с id=end/bottom .

Теперь добавим отображение того, чей сейчас ход Х или О. Для этого добавим 3 ImageView. Но для начала, давайте создадим сами иконки Х и О, а так же ß для того, чтобы показывать чей ход.

Для этого справа в области project щелкните правой кнопкой мыши (ПКМ) выберите New → Vector Asset.

В появившемся окне щелкнуть по изображению в пункте Clip Art, найти по поиску back стрелку назад и нажать OK. Я выбрал, чтобы концы были скругленными, для этого во втором выпадающем списке выбрать Round. Вы можете посмотреть, как выглядят остальные и выбрать понравившийся. Размер я задал 64 в пункте Size, а цвет в Color: F44336. Вы же в палитре можете выбрать тот цвет, который Вам больше всего понравился. Название в пункте Name я указал ic_arrow, чтоб проще было использовать. Для иконок, принято название начинать с ic_ и в snake case, т.е. с подчеркиванием. И нажимаем Next → Finish. Теперь самостоятельно сделайте крестик и нолик. Для них я выбрал иконку close и panorama fish eye соответственно и выбрал цвет 454FCE, а названия дал ic_cross и ic_circle.

После всех этих действий, в разделе res → drawable появятся новые файлы с нашими иконками. Я рекомендую значение цвета из параметра android:tint перенести в параметр android:fillColor , а сам tint удалить. На некоторых китайских телефонах, отображение ведет себя не корректно и качество иконки ухудшается.

Теперь давайте вернемся к верстке и добавим 3 элемента ImageView. Для этого перейдем в режим Design (это как один из способов верстания экрана), найдем ImageView и перетащим его на макет. В появившемся экране выберем иконку ic_cross. В поле id напишем название cross. Таким же способом перетащим еще 2 элемента для ic_arrow и ic_circle и дадим им имя id direction и circle соответственно. Теперь выделим каждый элемент поочередно и потянув за верхний круг свяжем вьюшку с верхним guideline.

Теперь сделаем из них цепочку, чтоб они были посередине и склеены друг с другом. Для этого выделяем эти 3 элемента вышкой, нажимаем ПКМ → Chains → Create Horizontal Chain.

Затем снова ПКМ → Chains → Horizontal Chain Style → packed. Попробуйте другие стили и посмотрите, чем они отличаются друг от друга.

Теперь они склеились вместе и находятся посередине, как я и хотел.

Добавим еще один элемент Barrier, который служит для того, чтобы следующий элемент расположить после других, не зависимо от того, какого размера будет каждый. Нажмем на кнопку Guidelines → Add Horizontal Barrier.

И установим следующие значения:

У вас должно получиться что-то вроде этого.

Теперь осталось добавить последний элемент верстки это GridLayout. Но его нужно выбрать из подключенной библиотеки и выбрать androidx.gridlayout.widget.GridLayout. Его уже нужно добавить вручную.

Аргументы app:columnCount и app:rowCount отвечают за количество колонок и строк соответственно. Устанавливаем значение 3, т.к. поле у нас 3х3. Аргументы app:layout_constraintDimensionRatio отвечает за соотношение сторон. Для того, что бы у нас был квадрат нужно его выставить в 1:1, вот из-за этого аргументаи пришлось подключать библиотеку, т.к. на версиях Android 5 этот аргумент не работает. И для того, чтобы соотношение работало, необходимо установить android:layout_width и android:layout_height в 0dp. Аргументы app:layout_constraintXXX_toXXX отвечают за привязку нашей вьюшки к другим элементам. Ну и запишем id=»@+id/field» , а во внутрь добавим ImageView. Но так как их понадобиться 9 штук и чтобы у каждой вьюшке не прописывать одни и те же аргументы, можно создать стиль. Для этого щелкаем ПКМ по values → New → Values Resource File.

Читайте также:  Набор иконки для android

В появившемся окне, в поле File name указываем styles и нажимаем OK. В созданном файле сделаем следующую запись:

Аргументы layout_columnWeight и layout_rowWeight служат для установки весов вьюшек и чтобы они равными размерами распределялись по ширине и высоте соответственно. Для того, чтобы эти веса заработали, необходимо android:layout_width и android:layout_height установить в 0dp. А в android:background прописываем атрибут, который будет браться из темы и отображать нажатие на вьюшку. Теперь осталось подключить этот стиль к нашей вьюшке. Возвращаемся к нашей верстке и у созданной ImageView меняем на следующее:

style=»@style/CellStyle» – позволяет применить наш стиль для разных вьюшек, а tools:src=»https://otus.ru/journal/krestiki-noliki/@drawable/ic_cross» позволяет отображать картинку на макете, но когда проект будет создан и установлен на телефоне, то картинки не будет. Продублируем этот элемент, чтобы в общем счете их получилось 9. В итоге должно получиться следующее:

Соединяем верстку с кодом (Binding)

Теперь нужно перейти во фрагмент MainFragment и поправить то, что было сгенерировано студией и добавить binding, который связывает верстку с кодом.

А оставшийся метод onActivityCreated полностью удалите. Все элементы, которые студия подчеркнет, нужно импортировать с помощью подсказок.

Пишем код

Теперь давайте перейдем в класс MainViewModel и уберем сгенерированные TODO. Нам необходимо хранить состояния ячеек (пустая, крестик, нолик) и для этого создадим массив этих состояний потому, что в Gridlayout все ячейки хранятся списком. А для расчета того кто победил, будем переводить индекс в массиве в координаты [строка:колонка], но об этом позже.

Создадим enum class для хранения состояния. В нем будет храниться картинка и возможность по ней кликать, ведь когда мы уже поставили символ или игра закончилась, то уже кликать по ячейкам нельзя. Напишем следующее в этом же файле в самом низу за пределами `>`.

Создадим поле с массивом этих состояний, я назову ее matrix для простоты. Так же добавим поле для хранения текущего состояния, т.е. чей сейчас ход и создадим метод initGame для инициализации начального состояния игры при первом запуске приложения (init – вызывается при создании класса MainViewModel ) и при сбросе игры ( onReloadClick ).

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

Здесь mCurrentMove является изменяемым и он закрыт для обращения из вне класса, а currentMove является не изменяемым и он доступен снаружи класса.

Давайте подпишемся на изменение хода и будем отображать на экране чей сейчас ход. Для этого перейдем в MainFragment , переопределим метод onViewCreated и добавим в него следующее.

binding.field.forEachIndexed – к каждой вьюшке находящейся в GridLayout устанавливаем слушатель на клик.

binding.direction – это наша стрелочка на экране. Соберите проект и запустите его, посмотрите что происходит когда мы кликаем по ячейкам. Попробуйте убрать комментирование со строки со scaleY, а строку с rotation закомментировать или убрать и посмотреть что получилось.

Добавим отображение иконке в той ячейке, по которой мы кликнули. Чтобы не перерисовывать весь массив ячеек, а менять значение только той, по которой мы кликнули, будем передавать индекс ячейки и ее новое значение. Для этого добавим еще одно поле mCellStateByIndex, в которую будет передаваться индекс и новое состояние ячейки.

SingleLiveEvent – этот класс служит для того, чтобы при смене конфигурации (например, переворота экрана) не вызывалось снова событие на отрисовку вьюшки. Этот класс нужно создать отдельным файлом.

Добавим еще состояние нашей игры (запущена и остановлена), чтобы нельзя было кликать по ячейкам, когда игра завершилась и LiveData, в которой будет храниться состояние игры и список состояний ячеек

Создадим enum GameStatus и напишем его ниже CellState.

Добавим поле mStates и сделаем несколько изменений.

Создаем свою вьюшку и рисуем на ней сетку

Создадим новый файл. Для этого в правой части проекта щелкните ПКМ по ru.otus.tictactoe → New → Kotlin Class/File и введите название FieldView.

И напишите следующее в этот файл:

Обязательно нужно наследоваться от androidx.gridlayout.widget.GridLayout .

Еще нужно добавить в ресурсы в которых будет указан цвет и размер линии. Для этого ПКМ по res → New → Android Resource File.

В появившемся окне, в поле File name: написать values и нажать OK.

Появится новый файл values.xml. откройте его и напишите следующее:

Теперь ошибки должны исчезнуть.

Осталось поменять нашу вьюшку в верстке.

Вычисляем, кто выиграл

Для начала создадим sealed class с возможными вариантами выигрыша (по горизонтали, по вертикали, по диагонали и нет выигрыша).

Создадим методы расчета выигрышного положения.

Сбрасывание состояния игры

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

Добавьте иконку cached и назовите ее ic_reload. Добавьте ресурс, как это делали с цветом и размером, только в открывшемся окне, поменяйте Resource type на Menu и в File name напишите menu_reload. А в ресурсах strings добавьте название кнопки

Теперь осталось только добавить ее и реализовать обработку этой кнопки. Для этого переходим в MainFragment и добавляем следующее.

Источник

Оцените статью