//check for other similar meals that are close to the proposed meal //d - is the day to start checking from //t - is the meal type function proximityAllowable(d, t){ for (pDay=d-1; (pDay gt 0 and pDay gt (d-minMealProximity-1)); pDay=pDay-1){ //check against types of the already planned meals if (listContains(menu[pDay].type, t)){ return false; } } return true; } //check for repeat side-dishes //d - is the day to start checking from //iSide - is which side to check (integer, currently must be 1 or 2) //sSide - is the value of the side dish chosen function sideProximityAllowable(d, iSide, sSide){ if (sSide is ""){ return true; } //if not choosing a side, no need to validate, allow it. for (pDay=d-1; (pDay gt 0 and pDay gt (d-minSideProximity-1)); pDay=pDay-1){ //check against types of the already planned meals if (listContains(evaluate("menu[#pDay#].side#iSide#"), sSide)){ return false; } } return true; } //this function implements all of our per-meal rules function mealAllowable(day, randMealTypeList){ for(t=1; t lte listLen(randMealTypeList); t=t+1){ //for each type of the random meal if (minMealProximity gt 0){ //allow 0-proximity check ("don't care") if (not (proximityAllowable(day, listGetAt(randMealTypeList, t)))){ return false; } }else{ return true; } } return true; } //this function will: // - copy the meal struct from the meals array to the menu array // - if the meal has been used the maximum number of times, it is taken out of the meals array so it won't be chosen at random again function assignMeal(day, mealIndex){ menu_meals[mealIndex].spent=menu_meals[mealIndex].spent+1; //increment the number of times this meal has been used menu[day] = StructNew(); menu[day].name = menu_meals[mealIndex].name; menu[day].difficulty = menu_meals[mealIndex].difficulty; menu[day].maxFrequency = menu_meals[mealIndex].maxFrequency; menu[day].spent = menu_meals[mealIndex].spent; menu[day].type = menu_meals[mealIndex].type; menu[day].exception = ""; menu[day].side1 = ""; menu[day].side2 = ""; //assign first side sides_list = menu_meals[mealIndex].side1; //copy string to its own variable so its not overwritten tries = 0; while (tries lt 20){ menu[day].side1 = application.udf.getRandomListItem(sides_list, day + tries); //send day as random seed if (sideProximityAllowable(day, 1, menu[day].side1)) {break;} tries=tries+1; } //assign second side tries = 0; while (tries lt 20){ menu[day].side2 = application.udf.getRandomListItem(fruit_n_veggie_list, day + tries); //send day as random seed tries=tries+1; if (sideProximityAllowable(day, 2, menu[day].side2)) {break;} } //if meal used max number of times, remove it from the array to speed future searches up if (menu_meals[mealIndex].spent gte menu_meals[mealIndex].maxFrequency){ arrayDeleteAt(menu_meals, mealIndex); } } #MonthAsString(menuMonth)# #menuYear#

#MonthAsString(menuMonth)# #menuYear#

SundayMondayTuesdayWednesdayThursdayFridaySaturday
   
#day#
#menu[day].name#
#menu[day].side1#

#menu[day].side2#
#day#
#menu[day].exception#
   
bContinue = true; //check to see if the current day is listed as an exception - if so, insert exception instead of meal for (x_check = 1; x_check lte arrayLen(exceptions); x_check=x_check+1){ if (exceptions[x_check].date eq day){ menu[day] = exceptions[x_check]; menu[day].type = ""; //added here so that it's not needed when declaring exceptions - must exist for proximity check for nearby meals menu[day].side1 = ""; //same^ menu[day].side2 = ""; //same^ mealMatch = true; bContinue = false; break; } } //if current day is not an exception if (bContinue){ randomMeal = RandRange(1, arrayLen(menu_meals)); //choose a meal at random if (day gt 1){ if (mealAllowable(day, menu_meals[randomMeal].type)){ //does the random choice meet all requirements? assignMeal(day, randomMeal); mealMatch = true; } }else{ assignMeal(day, randomMeal); mealMatch = true; } }