Часть 2 из 5
В этой части мы собираемся начать писать логику игры и добавлять тесты, чтобы убедиться, что наша игра будет работать.
- «Часть 1 - Настройка проекта, зависимости и Hello Tic Tac Toe! приложение."
- Часть 2. Структура, состояние и тесты игры.
- Часть 3 - Геймплей и базовый стиль.
- Часть 4 - Подсказки, новая игра и многое другое.
- Часть 5 - Очистка и запоздалые мысли.
Обновление от 22 июля 2019 г .: зависимости проекта обновлены.
- Вавилон 7.x
- Реагировать 16.x
- Redux 4.x
- Webpack 4.x
Полный список обновлений можно найти в package.json.
Новые зависимости
Чтобы написать тесты для наших действий, редукторов и операций, нам нужно будет добавить шутку в качестве зависимости разработчика в наш проект. Jest хорош, потому что он содержит все, что нам нужно для написания, запуска и сбора информации для нашего кода.
Мы также будем использовать redux-thunk, чтобы позволить нам условно отправлять действия для нашей игры.
yarn add --dev jest redux-thunk
Обновите тестовый сценарий файла package.json
с помощью команды jest cli, чтобы выполнить все тесты, найденные в нашем проекте. По умолчанию Jest ищет файлы, которые начинаются с «test, * .test или * .spec».
// package.json scripts: { ..., ..., "test": "jest" } // rest of package.json
Структура игры
Крестики-нолики - довольно простая игра. Существует сетка, составленная из трех на три квадрата, где каждый игрок делает ход, отмечая «X» или «O» в каждом квадрате. Выигрывает тот игрок, который первым соберет три в ряд, столбец или диагональ. Поскольку игра настолько проста, нам нужно всего четыре состояния.
board
- числовой массив 3x3; текущее состояние игрового поля.gameover
- логический; есть победитель или это ничья.player
- число; текущий игрок или нет (0).winner
- число; игрок, выигравший игру, или ничья (0).
Управление государством
Мы собираемся использовать шаблон re-ducks, чтобы организовать наши редукторы, типы и действия redux в уток. Есть много способов управления и организации ваших файлов redux, но мне нравится шаблон re-ducks, потому что он разбивает состояние на папки, которыми легко управлять и которые упрощают нам написание тестов.
Типичная «утка» будет содержать следующие файлы:
index.js
- экспорт для нашей утки.reducers.js
- редукторы redux.actions.js
- действия, которые могут быть использованы нашими операциями.operations.js
- операции, которые можно выполнять на нашей утке. Операция может отправлять одно или несколько действий.selectors.js
- отображает сложное состояние или производное значение, присвоенное реквизитам (необязательно).types.js
- константы типа действия.test.js
- тесты для нашей утки.
Утки хранятся в папке: src/state/ducks/.
Игровая утка - Редукторы, действия и виды
Единственная утка для нашей игры будет «игровой» уткой. Он будет содержать четыре состояния, перечисленные в разделе «Структура игры».
Создайте папку game
в папке src/state/ducks/
и добавьте в нее файлы, перечисленные в разделе «Управление состоянием».
Мы начнем с написания тестов для наших редукторов, типов и действий. Откройте файл test.js
и добавьте в него этот код:
Если вы запустите yarn test
сейчас, вы получите неудачные тесты с сообщениями, в которых говорится: «TypeError: reducer не является функцией» или «TypeError: action. * Не является функцией», поскольку мы еще не реализовали их.
Откройте файл reducers.js
, actions.js
и types.js
и добавьте следующую реализацию:
Запустите yarn test
еще раз, и вы увидите, что все они уже проходят.
Игровая утка - операции и селекторы
Шаблон re-ducks описывает операции как интерфейс нашей утки. Операции, представленные через нашу утку, можно использовать для обновления состояния нашей утки.
Некоторые из наших утиных операций просты и могут быть представлены одна за другой с их действием, но есть другие, которые немного сложнее и требуют некоторой логики, прежде чем они отправят действия для изменения состояния.
Сначала мы обновим наш test.js
файл новым разделом для операций, прежде чем реализовывать их в файлах operations.js
и utils/game.js
.
ПРИМЕЧАНИЕ. Мы не используем селекторы, но их можно использовать для получения нашего состояния утки и получения из него нового состояния. Это должны быть чистые функции, такие как редукторы, которые не изменяют состояние нашей утки.
Мы можем просто использовать пустой экспорт в selectors.js
файле в качестве заполнителя.
// ducks/game/selector.js export {};
Дичь - утка обнаженная
Теперь, когда мы реализовали нашу утку, нам нужно открыть ее, чтобы компоненты могли использовать ее для визуализации своего состояния.
В файле index.js
экспортируйте редукторы, операции, селекторы и типы:
Создайте еще один index.js
файл в src/state/ducks/
, чтобы сгруппировать всех отдельных уток (пока только game
). Это редукторы, которые будут объединены в корневом редукторе хранилища redux.
// src/state/ducks/index.js export { default as gameState } from './game'; // ... // more exports from other ducks
Redux магазин
Чтобы использовать игровую утку с redux, нам нужно добавить ее редукторы в хранилище redux. Создайте store.js
файл вsrc/state/
для настройки магазина.
Мы экспортируем функцию configureStore
, которая настраивает хранилище, объединяя все наши утки в один корневой редуктор, добавляя промежуточное программное обеспечение преобразователя, чтобы мы могли отложить или условно отправить действия и применить любое начальное состояние перед созданием и возвратом хранилища.
Использование утки
Откройте файл src/index.js
и обновите его, чтобы использовать созданное нами хранилище redux.
Мы используем response-redux Provider
, чтобы предоставить наш store
всем нашим компонентам.
Позже, если мы захотим сохранить наше состояние в локальном хранилище, мы можем использовать переменную initialState
, чтобы загрузить его снова, если мы обновим или вернемся в игру после перехода.
В файле src/views/App.jsx
обновите его, чтобы использовать нашу игровую утку.
Проверьте, работает ли наше приложение, запустив yarn start
.
Продолжение следует…
Весь исходный код в этой части можно найти здесь: