From 837890dde44a3d7cafa8df1064e8a0c808fda4e5 Mon Sep 17 00:00:00 2001 From: Jeremy Kahn Date: Wed, 16 Aug 2023 09:36:31 -0500 Subject: [PATCH 1/4] fix(utils): make findInField return correct plot --- src/utils/index.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/utils/index.js b/src/utils/index.js index 8fa17ebbb..5f59bebb8 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -721,12 +721,20 @@ export const findInField = memoize( * @returns {?farmhand.plotContent} */ (field, condition) => { - const [plot = null] = - field.find(row => { - return row.find(condition) - }) ?? [] + /** @type {?farmhand.plotContent} */ + let foundPlot = null - return plot + field.find(row => { + const matchingPlot = row.find(condition) + + if (matchingPlot) { + foundPlot = matchingPlot + } + + return matchingPlot + }) + + return foundPlot }, { serializer: memoizationSerializer, From 58d38b19ca726a2565503e982a5f1281bf6169a3 Mon Sep 17 00:00:00 2001 From: Jeremy Kahn Date: Wed, 16 Aug 2023 09:40:33 -0500 Subject: [PATCH 2/4] refactor(utils): move findInField to its own file --- src/data/achievements.js | 2 +- src/game-logic/reducers/applyCrows.test.js | 2 +- src/game-logic/reducers/helpers.js | 3 ++- src/utils/findInField.js | 31 ++++++++++++++++++++++ src/utils/index.js | 29 +------------------- 5 files changed, 36 insertions(+), 31 deletions(-) create mode 100644 src/utils/findInField.js diff --git a/src/data/achievements.js b/src/data/achievements.js index 1b19c7d88..1e4eb45a0 100644 --- a/src/data/achievements.js +++ b/src/data/achievements.js @@ -2,7 +2,6 @@ import { addItemToInventory } from '../game-logic/reducers/' import { doesPlotContainCrop, dollarString, - findInField, getCropLifeStage, getProfitRecord, integerString, @@ -11,6 +10,7 @@ import { percentageString, } from '../utils' import { memoize } from '../utils/memoize' +import { findInField } from '../utils/findInField' import { cropLifeStage, standardCowColors } from '../enums' import { COW_FEED_ITEM_ID, I_AM_RICH_BONUSES } from '../constants' diff --git a/src/game-logic/reducers/applyCrows.test.js b/src/game-logic/reducers/applyCrows.test.js index aef142e36..80a93f10f 100644 --- a/src/game-logic/reducers/applyCrows.test.js +++ b/src/game-logic/reducers/applyCrows.test.js @@ -1,5 +1,5 @@ -import { findInField } from '../../utils' import { MAX_CROWS, SCARECROW_ITEM_ID } from '../../constants' +import { findInField } from '../../utils/findInField' import { randomNumberService } from '../../common/services/randomNumber' diff --git a/src/game-logic/reducers/helpers.js b/src/game-logic/reducers/helpers.js index 47022f39f..845f6cafc 100644 --- a/src/game-logic/reducers/helpers.js +++ b/src/game-logic/reducers/helpers.js @@ -1,7 +1,8 @@ import { itemType } from '../../enums' import { SCARECROW_ITEM_ID } from '../../constants' -import { findInField, getPlotContentType } from '../../utils' +import { getPlotContentType } from '../../utils' +import { findInField } from '../../utils/findInField' // This file is designed to contain common logic that is needed across multiple // reducers. diff --git a/src/utils/findInField.js b/src/utils/findInField.js new file mode 100644 index 000000000..fd28a01dc --- /dev/null +++ b/src/utils/findInField.js @@ -0,0 +1,31 @@ +/** @typedef {import("../index").farmhand.plotContent} farmhand.plotContent */ +import { memoize } from './memoize' + +import { memoizationSerializer } from './' + +export const findInField = memoize( + /** + * @param {(?farmhand.plotContent)[][]} field + * @param {function(?farmhand.plotContent): boolean} condition + * @returns {?farmhand.plotContent} + */ + (field, condition) => { + /** @type {?farmhand.plotContent} */ + let foundPlot = null + + field.find(row => { + const matchingPlot = row.find(condition) + + if (matchingPlot) { + foundPlot = matchingPlot + } + + return matchingPlot + }) + + return foundPlot + }, + { + serializer: memoizationSerializer, + } +) diff --git a/src/utils/index.js b/src/utils/index.js index 5f59bebb8..ed7d3e570 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -138,7 +138,7 @@ export const chooseRandom = list => list[chooseRandomIndex(list)] * accept function arguments. * @param {any[]} args */ -const memoizationSerializer = args => +export const memoizationSerializer = args => JSON.stringify( [...args].map(arg => (typeof arg === 'function' ? arg.toString() : arg)) ) @@ -714,33 +714,6 @@ export const getPriceEventForCrop = cropItem => ({ getCropLifecycleDuration(cropItem) - PRICE_EVENT_STANDARD_DURATION_DECREASE, }) -export const findInField = memoize( - /** - * @param {(?farmhand.plotContent)[][]} field - * @param {function(?farmhand.plotContent): boolean} condition - * @returns {?farmhand.plotContent} - */ - (field, condition) => { - /** @type {?farmhand.plotContent} */ - let foundPlot = null - - field.find(row => { - const matchingPlot = row.find(condition) - - if (matchingPlot) { - foundPlot = matchingPlot - } - - return matchingPlot - }) - - return foundPlot - }, - { - serializer: memoizationSerializer, - } -) - export const doesMenuObstructStage = () => window.innerWidth < BREAKPOINTS.MD const itemTypesToShowInReverse = new Set([itemType.MILK]) From ab839a9bd53d15d26b107419ceb7a2e104680b00 Mon Sep 17 00:00:00 2001 From: Jeremy Kahn Date: Wed, 16 Aug 2023 09:52:50 -0500 Subject: [PATCH 3/4] test(utils): validate findInField --- src/utils/findInField.test.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/utils/findInField.test.js diff --git a/src/utils/findInField.test.js b/src/utils/findInField.test.js new file mode 100644 index 000000000..2bab29cdb --- /dev/null +++ b/src/utils/findInField.test.js @@ -0,0 +1,33 @@ +/** + * @typedef {import("../components/Farmhand/Farmhand").farmhand.state['field']} farmhand.state.field + */ + +import { carrot, pumpkin } from '../data/crops' + +import { findInField } from './findInField' + +const carrotPlot = { + itemId: carrot.id, + fertilizerType: 'NONE', +} + +describe('findInField', () => { + /** @type farmhand.state.field} */ + const field = [[null, carrotPlot, null]] + + test('returns the desired plot from the field', () => { + const foundPlot = findInField(field, plot => { + return plot?.itemId === carrot.id + }) + + expect(foundPlot).toEqual(carrotPlot) + }) + + test('yields null if desired plot is not in the field', () => { + const foundPlot = findInField(field, plot => { + return plot?.itemId === pumpkin.id + }) + + expect(foundPlot).toEqual(null) + }) +}) From 0e3e5ba137ab086dde496b674a7761a014665f69 Mon Sep 17 00:00:00 2001 From: Jeremy Kahn Date: Wed, 16 Aug 2023 09:56:38 -0500 Subject: [PATCH 4/4] refactor(utils): simplify findInField --- src/utils/findInField.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/utils/findInField.js b/src/utils/findInField.js index fd28a01dc..7cdeb6943 100644 --- a/src/utils/findInField.js +++ b/src/utils/findInField.js @@ -10,20 +10,15 @@ export const findInField = memoize( * @returns {?farmhand.plotContent} */ (field, condition) => { - /** @type {?farmhand.plotContent} */ - let foundPlot = null - - field.find(row => { - const matchingPlot = row.find(condition) - - if (matchingPlot) { - foundPlot = matchingPlot + for (const row of field) { + for (const plot of row) { + if (condition(plot)) { + return plot + } } + } - return matchingPlot - }) - - return foundPlot + return null }, { serializer: memoizationSerializer,