导语
通过编程计算饥荒游戏中,所有农作物可满足肥度自给自足的种植搭配
思路
- 穷举出所有农作物,包括生长季节,生长素,堆肥,肥料消耗数值等属性(后续如果版本更新或有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土豆
芦笋 + 南瓜 + 土豆