/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ import React from 'react'; import { FlipperPlugin, RoundedSection, Button, produce, CenteredView, Info, colors, styled, FlexRow, Text, brandColors, } from 'flipper'; import {Draft} from 'immer'; type Player = ' ' | 'X' | 'O'; type State = { cells: readonly [ Player, Player, Player, Player, Player, Player, Player, Player, Player, ]; winner: Player; turn: 'X' | 'O'; }; function initialState(): State { return { // Cells // 0 1 2 // 3 4 5 // 6 7 8 cells: [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '] as const, turn: Math.random() < 0.5 ? 'O' : 'X', winner: ' ', } as const; } const computeNextState = produce( (draft: Draft, cell: number, player: 'X' | 'O') => { draft.cells[cell] = player; draft.turn = player === 'X' ? 'O' : 'X'; draft.winner = computeWinner(draft.cells); }, ); function computeWinner(c: State['cells']): Player { // check the 2 diagonals if ((c[0] === c[4] && c[0] === c[8]) || (c[2] === c[4] && c[2] === c[6])) { return c[4]; } for (let i = 0; i < 3; i++) { // check vertical if (c[i] === c[3 + i] && c[i] === c[6 + i]) { return c[i]; } // check horizontal if (c[i * 3] === c[i * 3 + 1] && c[i * 3] === c[i * 3 + 2]) { return c[i * 3]; } } return ' '; } export default class ReactNativeTicTacToe extends FlipperPlugin< State, any, any > { state = initialState(); componentDidMount() { this.client.subscribe('XMove', ({move}: {move: number}) => { this.makeMove('X', move); }); this.client.subscribe('GetState', () => { this.sendUpdate(); }); this.sendUpdate(); } makeMove(player: 'X' | 'O', move: number) { if (this.state.turn === player && this.state.cells[move] === ' ') { this.setState(computeNextState(this.state, move, player), () => this.sendUpdate(), ); } } sendUpdate() { this.client.call('SetState', this.state); } handleCellClick(move: number) { this.makeMove('O', move); } handleReset() { this.setState(initialState(), () => this.sendUpdate()); } render() { const {winner, turn, cells} = this.state; return ( This plugin demonstrates how to create pure JavaScript Flipper plugins for React Native. Find out how to create a similar plugin at{' '} fbflipper.com . Flipper Tic-Tac-Toe

{winner !== ' ' ? `Winner! ${winner}` : turn === 'O' ? 'Your turn' : 'Mobile players turn..'} {cells.map((c, idx) => ( this.handleCellClick(idx)}> {c} ))}
); } } const Container = styled('div')({ border: `4px solid ${brandColors.Flipper}`, borderRadius: 4, padding: 20, marginTop: 20, }); const GameBoard = styled(FlexRow)({ flexWrap: 'wrap', justifyContent: 'space-between', marginTop: 20, marginBottom: 20, }); const Cell = styled('button')({ padding: 20, height: 80, minWidth: 80, fontSize: 24, margin: 20, flex: 0, borderRadius: 4, backgroundColor: colors.highlight, color: 'white', ':disabled': { backgroundColor: colors.greyTint2, }, });