UNPKG

react-memory-game

Version:
429 lines (377 loc) 14.7 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryGame = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _lodash = require('lodash'); require('regenerator-runtime/runtime'); var _MemoryGrid = require('./MemoryGrid'); var _MemoryGrid2 = _interopRequireDefault(_MemoryGrid); var _MemoryCard = require('./MemoryCard'); var _MemoryCard2 = _interopRequireDefault(_MemoryCard); var _Counter = require('./Counter'); var _Counter2 = _interopRequireDefault(_Counter); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var MEMORY_GAME_CONTEXT = '__memory_game_context__'; var BOARD_SIZE = 16; var ResetButton = function ResetButton(_ref, context) { var _ref$children = _ref.children, children = _ref$children === undefined ? 'Reset Game' : _ref$children; var resetGame = context[MEMORY_GAME_CONTEXT].resetGame; return _react2.default.createElement( 'button', { className: 'memory-game--reset', onClick: resetGame }, children ); }; ResetButton.contextTypes = _defineProperty({}, MEMORY_GAME_CONTEXT, _propTypes2.default.object.isRequired); var Board = function Board(props, context) { var cards = context[MEMORY_GAME_CONTEXT].cards; return _react2.default.createElement( _MemoryGrid2.default, null, cards ); }; Board.contextTypes = _defineProperty({}, MEMORY_GAME_CONTEXT, _propTypes2.default.object.isRequired); var MovesCounter = function MovesCounter(props, context) { var movesCounter = context[MEMORY_GAME_CONTEXT].movesCounter; return _react2.default.createElement(_Counter2.default, { counter: movesCounter }); }; MovesCounter.contextTypes = _defineProperty({}, MEMORY_GAME_CONTEXT, _propTypes2.default.object.isRequired); var PairsFoundCounter = function PairsFoundCounter(props, context) { var pairsFoundCounter = context[MEMORY_GAME_CONTEXT].pairsFoundCounter; return _react2.default.createElement(_Counter2.default, { counter: pairsFoundCounter }); }; PairsFoundCounter.contextTypes = _defineProperty({}, MEMORY_GAME_CONTEXT, _propTypes2.default.object.isRequired); var MemoryGame = exports.MemoryGame = function (_Component) { _inherits(MemoryGame, _Component); function MemoryGame(props) { var _this2 = this; _classCallCheck(this, MemoryGame); var _this = _possibleConstructorReturn(this, (MemoryGame.__proto__ || Object.getPrototypeOf(MemoryGame)).call(this, props)); Object.defineProperty(_this, 'getPreparedCard', { enumerable: true, writable: true, value: function value(display, _value) { return { value: _value, display: display, state: _MemoryCard.CARD_STATE.CLOSED }; } }); Object.defineProperty(_this, 'prepareCardPairs', { enumerable: true, writable: true, value: function value(pairs) { return pairs.map(function (pair, index) { return pair.map(function (card) { return _this.getPreparedCard(card, index); }); }).reduce(function (prev, curr) { return prev.concat(curr); }); } }); Object.defineProperty(_this, 'prepareSingleCards', { enumerable: true, writable: true, value: function value(cards) { var preparedCards = cards.map(_this.getPreparedCard); return preparedCards.concat((0, _lodash.cloneDeep)(preparedCards)); } }); Object.defineProperty(_this, 'getInitialState', { enumerable: true, writable: true, value: function value(cards) { var randomise = _this.props.dryRun ? _lodash.identity : _lodash.shuffle; var prepareCards = Array.isArray(cards[0]) ? _this.prepareCardPairs : _this.prepareSingleCards; return { moves: 0, pairsFound: 0, glimpse: false, cards: randomise(prepareCards(cards)) }; } }); Object.defineProperty(_this, 'resetGame', { enumerable: true, writable: true, value: function value(cards) { clearTimeout(_this.timeout); _this.setState(_this.getInitialState(cards), function () { if (_this.props.glimpse) { _this.startGlimpse(); } }); } }); Object.defineProperty(_this, 'startGlimpse', { enumerable: true, writable: true, value: function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() { var cards; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: cards = (0, _lodash.cloneDeep)(_this.state.cards).map(function (card) { return _extends({}, card, { state: _MemoryCard.CARD_STATE.OPEN }); }); _this.setState({ cards: cards, glimpse: true }); _this.timeout = setTimeout(function () { _this.closeOpenCards(); _this.setState({ glimpse: false }); }, _this.props.glimpse); case 3: case 'end': return _context.stop(); } } }, _callee, _this2); })); return function value() { return _ref2.apply(this, arguments); }; }() }); Object.defineProperty(_this, 'getOpenCards', { enumerable: true, writable: true, value: function value() { return (0, _lodash.cloneDeep)(_this.state.cards).filter(function (card) { return card.state === _MemoryCard.CARD_STATE.OPEN; }); } }); Object.defineProperty(_this, 'openCard', { enumerable: true, writable: true, value: function value(position) { var cards = (0, _lodash.cloneDeep)(_this.state.cards); cards[position].state = cards[position].state === _MemoryCard.CARD_STATE.CLOSED ? _MemoryCard.CARD_STATE.OPEN : cards[position].state; _this.setState({ cards: cards }, _this.checkForPair); } }); Object.defineProperty(_this, 'closeOpenCards', { enumerable: true, writable: true, value: function value() { clearTimeout(_this.timeout); var cards = (0, _lodash.cloneDeep)(_this.state.cards).map(function (card) { return _extends({}, card, { state: card.state === _MemoryCard.CARD_STATE.OPEN ? _MemoryCard.CARD_STATE.CLOSED : card.state }); }); _this.setState({ cards: cards }); } }); Object.defineProperty(_this, 'findCardPair', { enumerable: true, writable: true, value: function value() { var cards = (0, _lodash.cloneDeep)(_this.state.cards).map(function (card) { return _extends({}, card, { state: card.state === _MemoryCard.CARD_STATE.OPEN ? _MemoryCard.CARD_STATE.FOUND : card.state }); }); _this.setState({ cards: cards }); } }); Object.defineProperty(_this, 'hasGameEnded', { enumerable: true, writable: true, value: function value() { (0, _lodash.cloneDeep)(_this.state.cards).some(function (card) { return card.state !== _MemoryCard.CARD_STATE.FOUND; }); } }); Object.defineProperty(_this, 'scheduleCloseCards', { enumerable: true, writable: true, value: function value() { var delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 700; _this.timeout = setTimeout(_this.closeOpenCards, delay); } }); Object.defineProperty(_this, 'incrementCounter', { enumerable: true, writable: true, value: function value() { _this.setState({ moves: _this.state.moves + 1 }); } }); Object.defineProperty(_this, 'incrementFoundPairsCounter', { enumerable: true, writable: true, value: function value() { _this.setState({ pairsFound: _this.state.pairsFound + 1 }); } }); Object.defineProperty(_this, 'checkForPair', { enumerable: true, writable: true, value: function value() { var openCards = _this.getOpenCards(); if (openCards.length !== 2) { return; } _this.incrementCounter(); if (openCards[0].value === openCards[1].value) { _this.findCardPair(); _this.incrementFoundPairsCounter(); } else { _this.scheduleCloseCards(); } } }); Object.defineProperty(_this, 'handleCardClick', { enumerable: true, writable: true, value: function value(position) { return function () { if (_this.state.glimpse) { return; } var openCards = _this.getOpenCards(_this.state); switch (openCards.length) { case 0: { _this.openCard(position); break; } case 1: { _this.openCard(position); break; } default: { break; } } }; } }); if (props.cards.length !== BOARD_SIZE / 2) { throw new Error('Wrong card set size: <MemoryGame /> expects ' + BOARD_SIZE / 2 + ' cards or pairs'); } _this.state = _this.getInitialState(props.cards); return _this; } _createClass(MemoryGame, [{ key: 'componentWillMount', value: function componentWillMount() { var _props = this.props, glimpse = _props.glimpse, glimpseOnMount = _props.glimpseOnMount; if (glimpse && glimpseOnMount) { this.startGlimpse(); } } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { if (nextProps.cards !== this.props.cards) { this.resetGame(nextProps.cards); } } }, { key: 'getChildContext', value: function getChildContext() { return _defineProperty({}, MEMORY_GAME_CONTEXT, { cards: this.getMemoryCards(), resetGame: this.resetGame.bind(this, this.props.cards), movesCounter: this.state.moves, pairsFoundCounter: this.state.pairsFound }); } }, { key: 'getMemoryCards', value: function getMemoryCards() { var _this3 = this; return (0, _lodash.cloneDeep)(this.state.cards).map(function (card, position) { return _react2.default.createElement( _MemoryCard2.default, { onClick: _this3.handleCardClick(position), key: position, state: card.state }, card.display ); }); } }, { key: 'render', value: function render() { return _react2.default.createElement( 'div', { className: 'memory-game' }, this.props.children ); } }]); return MemoryGame; }(_react.Component); Object.defineProperty(MemoryGame, 'propTypes', { enumerable: true, writable: true, value: { cards: _propTypes2.default.arrayOf(_propTypes2.default.any).isRequired, glimpse: _propTypes2.default.number, glimpseOnMount: _propTypes2.default.bool } }); Object.defineProperty(MemoryGame, 'Reset', { enumerable: true, writable: true, value: ResetButton }); Object.defineProperty(MemoryGame, 'Board', { enumerable: true, writable: true, value: Board }); Object.defineProperty(MemoryGame, 'MovesCounter', { enumerable: true, writable: true, value: MovesCounter }); Object.defineProperty(MemoryGame, 'PairsFoundCounter', { enumerable: true, writable: true, value: PairsFoundCounter }); Object.defineProperty(MemoryGame, 'childContextTypes', { enumerable: true, writable: true, value: _defineProperty({}, MEMORY_GAME_CONTEXT, _propTypes2.default.object.isRequired) }); exports.default = MemoryGame;