mercredi 29 novembre 2023

Need help finding issue in meal generator

I have a meal generator that generates meals for 4 days of the week. There are some meals that I want to count as 2 meals because they produce leftovers. I also have some of the meals in groups (pesto, spaghetti, and tortellini are pasta) which I do not want to appear together in the output. If no pasta meals are selected, 4 meals should show up in the output. If one pasta meal appears in the output, then there should be 3 meals total: the pasta meal, and 2 non pasta meals. That means that a pasta meal cannot be selected as the 4th meal ever.

My code is split into 3 files: main.cpp

#include "include\mealSelector.h"

int main() {
    std::vector<std::string> meals = {
        "Spaghetti", "Pesto", "Frozen Pizza", "Nachos", "Potato Skins",
        "Quesadillas", "Hoagies", "Lunch meat sandwiches", "Brats",
        "Chicken, Potatoes and Broccoli", "Taquitos and Mini Corn dogs",
        "App Night", "Grilled Cheese", "Mac & Cheese", "Tortellini"
    };

    MealSelector mealSelector(meals);
    mealSelector.shuffleMeals();
    mealSelector.selectMeals();

    return 0;
}

mealSelector.cpp

#include "include/MealSelector.h"
#include <algorithm>

MealSelector::MealSelector(const std::vector<std::string>& initialMeals)
    : meals(initialMeals), mealCount(0), pastaAllowed(true) {} // Initialize [Meal Group]Allowed here

void MealSelector::shuffleMeals() {
    std::random_device rd{};
    std::seed_seq ss{ rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd() };
    std::mt19937 mt{ ss };
    std::shuffle(meals.begin(), meals.end(), mt);
}

void MealSelector::selectMeals() {
    for (const auto& meal : meals) {
        if (mealCount >= 4) {
            break; // Exit the loop once we have 4 meals
        }

        if (canSelectPastaMeal(meal) && ((mealCount < 3) || (mealCount == 3 && pastaAllowed))) {
            handleSelectedPastaMeal(meal);
        } else {
            handleRegularMeal(meal);
        }
    }
}

void MealSelector::printAndAddMeal(const std::string& meal) {
    std::cout << meal << std::endl;
    chosenMeals.insert(meal);
}

bool MealSelector::isPastaMeal(const std::string& meal) {
    return (meal == "Pesto" || meal == "Spaghetti" || meal == "Tortellini");
}

bool MealSelector::canSelectPastaMeal(const std::string& meal) {
    if (isPastaMeal(meal)) {
        if (!pastaAllowed || mealCount >= 3) {
            return false; // Disallow selecting more pasta meals if one is already selected
        }

        for (const auto& selectedMeal : lastPastaSelections) {
            if (mealCount - selectedMeal.second < 3 && meal != selectedMeal.first) {
                return false; // Check conditions for pasta meal selection
            }
        }
    }
    return true;
}

void MealSelector::handleSelectedPastaMeal(const std::string& meal) {
    if (mealCount >= 4 || !pastaAllowed) {
        return; //Exit if already selected 4 meals or if pasta is not allowed
    }

    //Check if the pasta meal is allowed based on previous selections
    if (isPastaMeal(meal) && lastPastaSelections.find(meal) != lastPastaSelections.end()) {
        return; // Exit if this pasta meal was already chosen
    }

    // Ensure mutual exclusion among pasta meals
    for (const auto& pasta : {"Spaghetti", "Tortellini", "Pesto"}) {
        if (pasta != meal && lastPastaSelections.find(pasta) != lastPastaSelections.end()) {
            return; // Exit if another pasta meal was already chosen
        }
    }

    printAndAddMeal(meal);
    mealCount += (isPastaMeal(meal)) ? 2 : 1; // Pasta meals count as 2 meals

    if (isPastaMeal(meal)) {
        pastaAllowed = false; // Set pastaAllowed to false after selecting one pasta meal
        lastPastaSelections[meal] = mealCount;
    }
}

void MealSelector::handleRegularMeal(const std::string& meal) {
    if (!isPastaMeal(meal) && mealCount == 3) {
        pastaAllowed = false;
    }
    printAndAddMeal(meal);
    mealCount++;
}

mealSelector.h

#pragma once

#include <iostream>
#include <vector>
#include <random>
#include <unordered_set>
#include <unordered_map>

class MealSelector {
private:
    std::vector<std::string> meals;
    std::unordered_set<std::string> chosenMeals;
    std::unordered_map<std::string, int> lastPastaSelections; // Track last selection for each pasta meal
    int mealCount;
    bool pastaAllowed;

public:
    MealSelector(const std::vector<std::string>& initialMeals);

    void shuffleMeals();
    void selectMeals();

private:
    void printAndAddMeal(const std::string& meal);
    bool isPastaMeal(const std::string& meal);
    bool canSelectPastaMeal(const std::string& meal);

    void handleSelectedPastaMeal(const std::string& meal);
    void handleRegularMeal(const std::string& meal);
};

When I run my code, sometimes it outputs something like this: Tortellini Spaghetti Grilled Cheese

This: Potato Skins Lunch meat sandwiches Mac & Cheese Tortellini

Or This: Spaghetti Tortellini Pesto

I cannot for the life of me figure out what is wrong. It may be a brain fart but please help.




Aucun commentaire:

Enregistrer un commentaire