// получаем максимальный номинал из перечисления, который есть в запасах и который меньше указанной суммы: private static Banknote_values max_available_value_less_than(uint summ, Banknote_values max_value) { var banknote_value = ((max_value == Banknote_values.how_many_banknotes_values)? max_value - 1 : max_value); while ((Banknote.get_banknote_value_by_text(banknote_value) > summ) || (banknotes_stock_for_check[Convert.ToInt32(banknote_value)].get_banknote_quantity() == 0)) { if (banknote_value == Banknote_values.ten_rubles) { break; } // переходим к более низкому номиналу, пока номинал превышает сумму или в нулевом количестве banknote_value--; } return(banknote_value); }
// МЕТОДЫ: // наполняем банкомат случайным образом, не выходя за рамки ограничений: public static void create_random_ATM_stock() { Random random_number = new Random(); var banknote_value = Banknote_values.ten_rubles; // здесь немного корявый момент, по сути это должно быть первое значение из перечисления, но как к нему обратиться я не знаю do { // делим максимальное количество купюр на количество номиналов, этим будем ограничивать случайное количество: uint random_quantity = Convert.ToUInt32(random_number.Next()) % (max_banknotes_number / number_of_banknotes_values); Banknote next_banknote = new Banknote(Banknote.get_banknote_value_by_text(banknote_value), random_quantity); // добавляем новую стопку купюр одного номинала в запас банкомата, даже если их 0: banknotes_stock.Add(next_banknote); banknote_value++; // переходим к следующему номиналу } while (banknote_value < Banknote_values.how_many_banknotes_values); // перебираем все номиналы }
static void Main(string[] args) { BanknoteHandler handler = new TwoDollarsHandler(null); handler = new TenDollarsHandler(handler); handler = new FiftyDollarsHandler(handler); handler = new HundredDollarsHandler(handler); var bancomat = new Bancomat(handler); Console.WriteLine("Validating banknotes...\n"); var fiftyDollars = new Banknote(CurrencyType.Dollar, 50); Console.WriteLine(fiftyDollars + ": " + bancomat.Validate(fiftyDollars)); var thirteenDollars = new Banknote(CurrencyType.Dollar, 13); Console.WriteLine(thirteenDollars + ": " + bancomat.Validate(thirteenDollars)); Console.WriteLine("\n\nCashing out..."); var currency = CurrencyType.Dollar; var amount = 360; Console.WriteLine($"\n{amount} {currency} cash:"); var cash = bancomat.CashOut(currency, amount); foreach (var banknote in cash) { Console.WriteLine(banknote); } amount = 365; Console.WriteLine($"\n{amount} {currency} cash:"); try { cash = bancomat.CashOut(currency, amount); foreach (var banknote in cash) { Console.WriteLine(banknote); } } catch (Exception e) { Console.WriteLine(e.Message); } Console.ReadKey(); }
public Cassette(Banknote banknote, int number) { Number = number; Banknote = banknote; }
private void button_replenishment_Click(object sender, EventArgs e) { uint number_to_replenish = 0; // общее количество купюр для пополнения bool everything_is_ok = true; for (int i = 0; i < textbox_array.Length; i++) // идём по всем номиналам купюр { try { uint quantity_for_value = 0; if (textbox_array[i].Text != "") // если поле пустое - оставляем ноль, иначе ловит ошибку // здесь могут быть и буквы, поэтому это всё происходит под try: { quantity_for_value = Convert.ToUInt32(textbox_array[i].Text); } if (quantity_for_value < 0) // отрицательное значение - тоже плохо { everything_is_ok = false; label_what_to_do.Text = "Количества не могут быть отрицательными!"; } number_to_replenish += quantity_for_value; // количество купюр увеличиваем на значение из поля // проверяем, не превысит ли количество вносимых купюр установленное максимально возможное: if ((number_to_replenish + ATM.how_many_banknotes()) > ATM.get_maximum_banknotes_number()) { everything_is_ok = false; label_what_to_do.Text = "Ограничение! Общее количество не должно превышать " + (ATM.get_maximum_banknotes_number() - ATM.how_many_banknotes()); } } catch { everything_is_ok = false; label_what_to_do.Text = "Введены некорректные количества, введите корректные:"; } if (!everything_is_ok) { break; // если на каком-то поле некорректное значение или перебор по купюрам, обрываем проверку } } if (!everything_is_ok) { // красим строку сигнальным цветом, чтобы пользователь увидел, что надо исправить label_what_to_do.ForeColor = Color.Yellow; } else // everything_is_ok { uint summ_of_replenishment = 0; // считаем общую сумму, на которую пополняем var value = Banknote_values.ten_rubles; for (int i = 0; i < textbox_array.Length; i++) // опять идём по всем номиналам, полям для количеств { textbox_array[i].Visible = false; // выше было проверено, что всё ок, поэтому поля для ввода количеств больше не нужны uint quantity_for_value = 0; // количество для пополнения определённого номинала if (textbox_array[i].Text != "") // иначе не сможем конвертировать пустоту в число { quantity_for_value = Convert.ToUInt32(textbox_array[i].Text); } ATM.replenish_banknote(Banknote.get_banknote_value_by_text(value), quantity_for_value); summ_of_replenishment += (Banknote.get_banknote_value_by_text(value) * quantity_for_value); value++; } // показываем результат, прячем лишнее label_what_to_do.Text = "Успешно внесена сумма: " + summ_of_replenishment; label_what_to_do.ForeColor = Color.MediumSpringGreen; button_replenishment.Visible = false; label1.Visible = false; label2.Visible = false; label3.Visible = false; label4.Visible = false; label5.Visible = false; label6.Visible = false; label7.Visible = false; label8.Visible = false; } }
public object Clone() { return(new Cassette((Banknote)Banknote.Clone(), Number)); }
// функция проверяет, можем ли мы выдать заданную сумму и заполняет массив купюр (достоинство-количество), // которыми можно выдать. Возвращает истину, если всё получилось и ложь - если нет. private bool check_and_withdrawal(bool by_large_values) { label_no_result.Visible = false; uint users_wish = 0; // в этой переменной будем хранить сумму, которую хочет получить пользователь // СНАЧАЛА ПРОВЕРЯЕМ, НОРМАЛЬНУЮ ЛИ СУММУ ХОЧЕТ ПОЛЬЗОВАТЕЛЬ try { // пытаемся получить сумму из окошка для неё, если там не число - ловим ошибку users_wish = Convert.ToUInt32(textBox_for_summ.Text); } catch { MessageBox.Show("Запрашиваемая сумма не корректна!"); } if (users_wish == 0) // 0 - нормальное число, но не в данном случае { label_no_result.Text = "Введите ненулевую и недробную сумму"; return(false); } // если пользователь хочет больше, чем есть - тоже сразу нет: uint ATM_balanсe = ATM.how_much_money(); if (users_wish > ATM_balanсe) { label_no_result.Text = "В банкомате нет столько денег!\nПроверьте баланс и попробуйте ввести сумму меньше."; return(false); } // если пользователь хочет более мелкие деньги, чем есть, то тоже нет: if (users_wish % Banknote.get_banknote_value_by_text(min_available_value()) != 0) { label_no_result.Text = "Минимальная доступная купюра: "; label_no_result.Text += Banknote.get_banknote_value_by_text(min_available_value()); label_no_result.Text += "р. Скорректируйте сумму для выдачи с учётом этого."; return(false); } // для каждой транзакции будем заполнять массив с проверочными остатками заново: banknotes_stock_for_check.Clear(); // пара сокращений: Banknote_values min_value = Banknote_values.ten_rubles; Banknote_values max_value = Banknote_values.how_many_banknotes_values; if (by_large_values) // нужна выдача крупными купюрами, о мелких не беспокоимся, просто копируем данные { for (var value = min_value; value < max_value; value++) { Banknote next_banknote = new Banknote(Banknote.get_banknote_value_by_text(value), ATM.how_many_banknotes_of(value)); banknotes_stock_for_check.Add(next_banknote); } } else // нужна выдача мелкими купюрами, тут код подлиннее, чтобы сразу понять, какими купюрами можем обойтись { // изначально полагаем максимальную мелкую купюру равной 200р Banknote_values max_small_value = Banknote_values.two_hundred_rubles; uint summ_of_small_values = 0; // будем считать сумму, которую можем выдать мелкими купюрами // копируем остатки банкомата в массив для проверки выдачи суммы, считаем сумму мелких купюр: for (var value = min_value; value < max_value; value++) { Banknote next_banknote = new Banknote(Banknote.get_banknote_value_by_text(value), ATM.how_many_banknotes_of(value)); banknotes_stock_for_check.Add(next_banknote); if (value <= max_small_value) { summ_of_small_values += next_banknote.get_summ(); // если посчитали всю сумму мелкими купюрами, и её не хватает, то добавляем к мелким следующую купюру if ((value == max_small_value) && (summ_of_small_values < users_wish)) { max_small_value++; // мы не будем проверять здесь, что значение выйдет за предел диапазона, т.к. уже проверили, что всех денег банкомата для суммы хватит } } } max_value = max_small_value; // ограничиваем максимальный номинал максимальной мелкой купюрой, которой хватит для выдачи суммы мелкими купюрами } // очистим массив снимаемых купюр, будем пополнять его по мере набора желаемой суммы try_to_withdraw.Clear(); // сумма, которую снимаем: uint total_summ_to_withdraw = 0; // ЖАДНЫЙ АЛГОРИТМ, подбираем купюры для выдачи начиная с самой крупной подходящей: while (users_wish > 0) // будем уменьшать это значение по мере подбора банкнот { // идём от наиболее больших сумм, это же проверка, так мы быстрее наберём нужную сумму Banknote_values max_enum_value = max_available_value_less_than(users_wish, max_value); var max_available_banknote_value = Banknote.get_banknote_value_by_text(max_enum_value); // максимально "доступный" номинал по факту может оказаться и не доступным: if (banknotes_stock_for_check[Convert.ToInt32(max_enum_value)].get_banknote_quantity() == 0) { // тогда мы не можем эту купюру использовать и набор суммы завершён label_no_result.Text = "Не удаётся набрать запрашиваемую сумму, не хватает каких-то купюр.\n"; label_no_result.Text += "Попробуйте ввести сумму "; label_no_result.Text += Convert.ToString(total_summ_to_withdraw); // очистим уже частично заполненный массив снимаемых купюр: try_to_withdraw.Clear(); return(false); // проверка окончена } // ИНАЧЕ продолжаем, добавляем купюру в список для снятия: banknotes_stock_for_check[Convert.ToInt32(max_enum_value)].substract_banknote(); try_to_withdraw.Add(max_available_banknote_value); total_summ_to_withdraw += max_available_banknote_value; users_wish -= max_available_banknote_value; } // дошли до сюда, значит набрали всю сумму // скрываем кнопки и поле для суммы, готовим текст о результате textBox_for_summ.Visible = false; button_by_small_value.Visible = false; button_by_large_value.Visible = false; // снимаем все подобранные банкноты по очереди, и печатаем их неповторяющиеся номиналы var used_banknote = try_to_withdraw[0]; // это для печати, сохраняем номинал первой банкноты на выдачу var number_of_used_banknotes = 0; // это тоже для печати string info_about_banknotes = "\nиспользованы купюры:\n" + used_banknote; foreach (var value in try_to_withdraw) { ATM.withdraw_banknote(value); if (value != used_banknote) // показываем количество для выданной купюры { info_about_banknotes += " x " + number_of_used_banknotes + '\n' + value; used_banknote = value; // начинаем рассматривать следующую number_of_used_banknotes = 0; } number_of_used_banknotes++; } info_about_banknotes += " x " + number_of_used_banknotes; // добавляем информацию о количестве последней выданной купюры label_for_positive_result.Text = "ВЫДАНА СУММА " + total_summ_to_withdraw; label_for_positive_result.Text += info_about_banknotes; label_for_positive_result.Visible = true; return(true); }
public bool Validate(Banknote banknote) => _handler.Validate(banknote);