编程计算饥荒所有农作物搭配(JavaScript版)

导语

通过编程计算饥荒游戏中,所有农作物可满足肥度自给自足的种植搭配

思路 

  1. 穷举出所有农作物,包括生长季节,生长素,堆肥,肥料消耗数值等属性(后续如果版本更新或有MOD农作物需添加,在此处修改添加)
const ALL_CROPS = [
  {
    name: '大蒜',
    season: ['春', '夏', '秋', '冬'],
    water: 1,
    auxin: 2,
    compost: -4,
    fertilizer: 2
  },
...
]

 2.根据游戏机制可以有两种作物搭配或三种作物搭配,此处涉及到关键算法之一,从所有作物中选择2个或3个的组合,既组合算法中的M选N

/**
 * 获取作物的所有组合方式 在crops中选取amout个元素
 * @param crops
 * @param amount
 * @returns {*[]|*[]}
 */
function cropsCombine (crops, amount) {
    // TODO
}

 3.判断步骤2中的作物搭配,是否可以满足肥料度自给自足。若可以,返回对应的配比系数

/**
 * 测试作物组合是否满足肥料自给自足
 * @param crops
 * @returns {number[]}
 */
function test (crops) {
    // TODO
}

 4.对春夏秋冬四个季节,找出适合生长的作物,然后执行算法

下面附上完整代码

const MAP_FERTILIZER = { auxin: '生长素', compost: '堆肥', fertilizer: '肥料' }
const ALL_CROPS = [
  {
    name: '大蒜',
    season: ['春', '夏', '秋', '冬'],
    water: 1,
    auxin: 2,
    compost: -4,
    fertilizer: 2
  }, {
    name: '番茄',
    season: ['春', '夏', '秋'],
    water: 3,
    auxin: -1,
    compost: -1,
    fertilizer: 2
  }, {
    name: '胡萝卜',
    season: ['春', '秋', '冬'],
    water: 1,
    auxin: -2,
    compost: 1,
    fertilizer: 1
  }, {
    name: '火龙果',
    season: ['春', '夏'],
    water: 2,
    auxin: 2,
    compost: 2,
    fertilizer: -4
  }, {
    name: '茄子',
    season: ['春', '秋'],
    water: 2,
    auxin: 1,
    compost: 1,
    fertilizer: -2
  }, {
    name: '辣椒',
    season: ['夏', '秋'],
    water: 1,
    auxin: 2,
    compost: 2,
    fertilizer: -4
  }, {
    name: '榴莲',
    season: ['春'],
    water: 1,
    auxin: 2,
    compost: 2,
    fertilizer: -4
  }, {
    name: '芦笋',
    season: ['春', '冬'],
    water: 1,
    auxin: 1,
    compost: -2,
    fertilizer: 1
  }, {
    name: '南瓜',
    season: ['秋', '冬'],
    water: 2,
    auxin: -2,
    compost: 1,
    fertilizer: 1
  }, {
    name: '石榴',
    season: ['春', '夏'],
    water: 2,
    auxin: -4,
    compost: 2,
    fertilizer: 2
  }, {
    name: '土豆',
    season: ['春', '秋', '冬'],
    water: 1,
    auxin: 1,
    compost: 1,
    fertilizer: -2
  }, {
    name: '西瓜',
    season: ['春', '夏'],
    water: 3,
    auxin: 2,
    compost: -1,
    fertilizer: -1
  }, {
    name: '洋葱',
    season: ['春', '夏', '秋'],
    water: 2,
    auxin: -4,
    compost: 2,
    fertilizer: 2
  }, {
    name: '玉米',
    season: ['春', '夏', '秋'],
    water: 1,
    auxin: 1,
    compost: -2,
    fertilizer: 1
  }
]
// 是否打印肥度
const LOG_FERTILITY = false
// 系数为1是否省略
const OMIT_ONE = true

/**
 * 测试作物组合是否满足肥料自给自足
 * @param crops
 * @returns {number[]}
 */
function test (crops) {
  if (!crops || crops.length < 2 || crops.length > 3) return

  let auxin, compost, fertilizer

  const crop0 = crops[0]
  const crop1 = crops[1]
  const crop2 = crops[2]

  if (crops.length === 2) {
    // 两种作物可以是 1:1, 1:2, 2:1, 1:3, 3:1

    // 1:1
    auxin = crop0.auxin + crop1.auxin
    compost = crop0.compost + crop1.compost
    fertilizer = crop0.fertilizer + crop1.fertilizer
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [1, 1]
    }

    // 1:2
    auxin = crop0.auxin + crop1.auxin * 2
    compost = crop0.compost + crop1.compost * 2
    fertilizer = crop0.fertilizer + crop1.fertilizer * 2
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [1, 2]
    }

    // 2:1
    auxin = crop0.auxin * 2 + crop1.auxin
    compost = crop0.compost * 2 + crop1.compost
    fertilizer = crop0.fertilizer * 2 + crop1.fertilizer
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [2, 1]
    }
  }

  if (crops.length === 3) {
    // 三种作物可以是 1:1:1, 2:1:1, 1:2:1, 1:1:2, 1:2:2, 2:1:2, 2:2:1

    // 1:1:1
    auxin = crop0.auxin + crop1.auxin + crop2.auxin
    compost = crop0.compost + crop1.compost + crop2.compost
    fertilizer = crop0.fertilizer + crop1.fertilizer + crop2.fertilizer
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [1, 1, 1]
    }

    // 2:1:1
    auxin = crop0.auxin * 2 + crop1.auxin + crop2.auxin
    compost = crop0.compost * 2 + crop1.compost + crop2.compost
    fertilizer = crop0.fertilizer * 2 + crop1.fertilizer + crop2.fertilizer
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [2, 1, 1]
    }

    // 1:2:1
    auxin = crop0.auxin + crop1.auxin * 2 + crop2.auxin
    compost = crop0.compost + crop1.compost * 2 + crop2.compost
    fertilizer = crop0.fertilizer + crop1.fertilizer * 2 + crop2.fertilizer
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [1, 2, 1]
    }

    // 1:1:2
    auxin = crop0.auxin + crop1.auxin + crop2.auxin * 2
    compost = crop0.compost + crop1.compost + crop2.compost * 2
    fertilizer = crop0.fertilizer + crop1.fertilizer + crop2.fertilizer * 2
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [1, 1, 2]
    }

    // 1:2:2
    auxin = crop0.auxin + crop1.auxin * 2 + crop2.auxin * 2
    compost = crop0.compost + crop1.compost * 2 + crop2.compost * 2
    fertilizer = crop0.fertilizer + crop1.fertilizer * 2 + crop2.fertilizer * 2
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [1, 2, 2]
    }
    // 2:1:2
    auxin = crop0.auxin * 2 + crop1.auxin + crop2.auxin * 2
    compost = crop0.compost * 2 + crop1.compost + crop2.compost * 2
    fertilizer = crop0.fertilizer * 2 + crop1.fertilizer + crop2.fertilizer * 2
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [2, 1, 2]
    }
    // 2:2:1
    auxin = crop0.auxin * 2 + crop1.auxin * 2 + crop2.auxin
    compost = crop0.compost * 2 + crop1.compost * 2 + crop2.compost
    fertilizer = crop0.fertilizer * 2 + crop1.fertilizer * 2 + crop2.fertilizer
    if (auxin >= 0 && compost >= 0 && fertilizer >= 0) {
      return [2, 2, 1]
    }
  }
}

/**
 * 获取作物的所有组合方式 在crops中选取amout个元素
 * @param crops
 * @param amount
 * @returns {*[]|*[]}
 */
function cropsCombine (crops, amount) {
  if (!crops || !crops.length) return []
  return getFlagArrs(crops.length, amount).map(flagArr => flagArr.map((coefficient, index) => coefficient && crops[index]).filter(Boolean))
}

function getFlagArrs (m, n) {
  if (!n || n < 1 || m < n) return []

  const flagArrs = []
  const flagArr = new Array(n).fill(1).concat(new Array(m - n).fill(0))
  flagArrs.push(flagArr.concat())

  let stop = false
  while (!stop) {
    let leftIndex = 0
    for (let i = 0; i < m - 1; i++) {
      if (flagArr[i] === 1 && flagArr[i + 1] === 0) {
        for (let j = 0; j < i; j++) {
          flagArr[j] = j < leftIndex ? 1 : 0
        }

        flagArr[i] = 0
        flagArr[i + 1] = 1

        const newFlagArr = flagArr.concat()
        flagArrs.push(newFlagArr)

        stop = newFlagArr.slice(-n).join('').indexOf('0') == -1
        break
      }

      flagArr[i] === 1 && leftIndex++
    }
  }
  return flagArrs
}

/**
 * 获取表达式
 * @param crops
 * @param amount
 * @returns {*[]|*[]}
 */
function getExpression (combinedCrops) {
  const scale = test(combinedCrops)
    if (!scale) return
    return combinedCrops = scale.map((coefficient, index) => {
      const crop = combinedCrops[index]
      const coefficientFormated =  OMIT_ONE ? (coefficient === 1 ? '' : coefficient) : coefficient
      const fertility =  LOG_FERTILITY ? `${crop.auxin}, ${crop.compost}, ${crop.fertilizer})` : ''

      return coefficientFormated + crop.name + fertility
    }).join(' + ')
}

;(['春', '夏', '秋', '冬']).forEach(season => {
  const crops = ALL_CROPS.filter(crop => crop.season && crop.season.indexOf(season) > -1)

  // 两种作物
  const double = cropsCombine(crops, 2).map(getExpression).filter(Boolean)

  // 三种作物
  const triple = cropsCombine(crops, 3).map(getExpression).filter(Boolean)

  console.log(`${season}:
两种作物搭配:
${double.join('\n') || '无'}

三种作物搭配:
${triple.join('\n') || '无'}

  `)
})

 输出结果

春:
两种作物搭配:
2番茄 + 火龙果
番茄 + 茄子
2番茄 + 榴莲
番茄 + 土豆
胡萝卜 + 西瓜
石榴 + 2西瓜
2西瓜 + 洋葱

三种作物搭配:
大蒜 + 2胡萝卜 + 火龙果
大蒜 + 2胡萝卜 + 2茄子
大蒜 + 2胡萝卜 + 榴莲
2胡萝卜 + 火龙果 + 2芦笋
胡萝卜 + 茄子 + 芦笋
2胡萝卜 + 榴莲 + 2芦笋
大蒜 + 火龙果 + 石榴
大蒜 + 2茄子 + 石榴
大蒜 + 榴莲 + 石榴
火龙果 + 2芦笋 + 石榴
2茄子 + 2芦笋 + 石榴
榴莲 + 2芦笋 + 石榴
大蒜 + 2胡萝卜 + 2土豆
2番茄 + 茄子 + 土豆
胡萝卜 + 芦笋 + 土豆
大蒜 + 石榴 + 2土豆
2芦笋 + 石榴 + 2土豆
大蒜 + 火龙果 + 洋葱
大蒜 + 2茄子 + 洋葱
大蒜 + 榴莲 + 洋葱
火龙果 + 2芦笋 + 洋葱
2茄子 + 2芦笋 + 洋葱
榴莲 + 2芦笋 + 洋葱
大蒜 + 2土豆 + 洋葱
2芦笋 + 2土豆 + 洋葱
2胡萝卜 + 火龙果 + 2玉米
胡萝卜 + 茄子 + 玉米
2胡萝卜 + 榴莲 + 2玉米
火龙果 + 石榴 + 2玉米
2茄子 + 石榴 + 2玉米
榴莲 + 石榴 + 2玉米
胡萝卜 + 土豆 + 玉米
石榴 + 2土豆 + 2玉米
火龙果 + 洋葱 + 2玉米
2茄子 + 洋葱 + 2玉米
榴莲 + 洋葱 + 2玉米
2土豆 + 洋葱 + 2玉米


夏:
两种作物搭配:
2番茄 + 火龙果
2番茄 + 辣椒
石榴 + 2西瓜
2西瓜 + 洋葱

三种作物搭配:
大蒜 + 火龙果 + 石榴
大蒜 + 辣椒 + 石榴
大蒜 + 火龙果 + 洋葱
大蒜 + 辣椒 + 洋葱
火龙果 + 石榴 + 2玉米
辣椒 + 石榴 + 2玉米
火龙果 + 洋葱 + 2玉米
辣椒 + 洋葱 + 2玉米


秋:
两种作物搭配:
番茄 + 茄子
2番茄 + 辣椒
番茄 + 土豆

三种作物搭配:
大蒜 + 2胡萝卜 + 2茄子
大蒜 + 2胡萝卜 + 辣椒
大蒜 + 2茄子 + 2南瓜
大蒜 + 辣椒 + 2南瓜
大蒜 + 2胡萝卜 + 2土豆
2番茄 + 茄子 + 土豆
大蒜 + 2南瓜 + 2土豆
大蒜 + 2茄子 + 洋葱
大蒜 + 辣椒 + 洋葱
大蒜 + 2土豆 + 洋葱
胡萝卜 + 茄子 + 玉米
2胡萝卜 + 辣椒 + 2玉米
茄子 + 南瓜 + 玉米
辣椒 + 2南瓜 + 2玉米
胡萝卜 + 土豆 + 玉米
南瓜 + 土豆 + 玉米
2茄子 + 洋葱 + 2玉米
辣椒 + 洋葱 + 2玉米
2土豆 + 洋葱 + 2玉米


冬:
两种作物搭配:

三种作物搭配:
大蒜 + 2胡萝卜 + 2土豆
胡萝卜 + 芦笋 + 土豆
大蒜 + 2南瓜 + 2土豆
芦笋 + 南瓜 + 土豆

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

okey573

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值