From 66cc7055faf980b6ac5020f88171a93a90fb2813 Mon Sep 17 00:00:00 2001
From: MarcUs7i <96580944+MarcUs7i@users.noreply.github.com>
Date: Mon, 18 Nov 2024 08:45:15 +0100
Subject: [PATCH] Removed Bugs from cs files & almost completed
CoffeeVendingMachine.cs
---
CoffeeVendingMachines/CoffeeVendingMachine.cs | 287 ++++++++++++++++--
CoffeeVendingMachines/CoinDepot.cs | 2 +-
CoffeeVendingMachines/Model.cs | 12 +-
CoffeeVendingMachines/Product.cs | 13 +-
4 files changed, 273 insertions(+), 41 deletions(-)
diff --git a/CoffeeVendingMachines/CoffeeVendingMachine.cs b/CoffeeVendingMachines/CoffeeVendingMachine.cs
index ee791ed..7b88ded 100644
--- a/CoffeeVendingMachines/CoffeeVendingMachine.cs
+++ b/CoffeeVendingMachines/CoffeeVendingMachine.cs
@@ -2,24 +2,45 @@
public class CoffeeVendingMachine
{
- private static readonly CoinType[] withdrawalOrder;
+ private static readonly CoinType[] withdrawalOrder =
+ [
+ CoinType.Euro02,
+ CoinType.Euro01,
+ CoinType.Cent50,
+ CoinType.Cent20,
+ CoinType.Cent10,
+ CoinType.Cent05
+ ];
private readonly CoinDepot[] _currentChangeCoins;
private readonly CoinDepot[] _currentInputCoins;
private readonly Product[] _products;
- public readonly string Location;
- public readonly int TotalChangeAmountInMachine;
- public readonly int TotalMoneyCurrentlyInput;
- public readonly Product[] AvailableProducts;
+ public string Location { get; }
+ public int TotalChangeAmountInMachine => SumDepotValue(_currentChangeCoins);
+ public int TotalMoneyCurrentlyInput => SumDepotValue(_currentInputCoins);
+ public Product[] AvailableProducts => GetAvailableProducts();
+ ///
+ /// Creates a new coffee vending machine.
+ ///
+ ///
+ ///
+ ///
public CoffeeVendingMachine(CoinDepot[] coinDepots, Product[] products, string location)
{
- //TODO
+ Location = location;
+ _currentChangeCoins = coinDepots;
+ _products = products;
+ _currentInputCoins = CreateCoinDepots(6);
}
- public CoffeeVendingMachine(string location)
+ ///
+ /// Creates a new coffee vending machine with default products.
+ ///
+ ///
+ public CoffeeVendingMachine(string location) : this(CreateCoinDepots(6, true), CreateDefaultProducts(), location)
{
- //TODO
+ // no need to implement anything here
}
public CoinDepot[] Cancel()
@@ -28,66 +49,274 @@ public class CoffeeVendingMachine
return [];
}
+ ///
+ /// Inserts the given coin into the machine.
+ ///
+ ///
+ /// True if the coin was inserted, false otherwise.
public bool InsertCoin(CoinType coin)
{
- //TODO
+ foreach (var inputDepot in _currentInputCoins)
+ {
+ if (inputDepot.Coin == coin)
+ {
+ inputDepot.Add();
+ return true;
+ }
+ }
+
return false;
}
- public bool SelectProduct(string productName, out CoinDepot[]? change, out int? price)
+ ///
+ /// Withdraws the change from the machine.
+ ///
+ ///
+ ///
+ ///
+ /// True if the change was withdrawn, false otherwise.
+ public bool SelectProduct(string productName, out CoinDepot[]? change, out int? remainder)
{
- //TODO
- change = null;
- price = null;
- return false;
+ if(!TryFindProduct(productName, out Product? product) || product == null || !product.InStock || TotalMoneyCurrentlyInput < product.Price)
+ {
+ change = null;
+ remainder = null;
+ return false;
+ }
+
+ int returnAmount = TotalMoneyCurrentlyInput - product.Price;
+ AddInputToChange();
+ product.AddSale();
+ int? remainingAmount = PrepareChangeCoins(returnAmount, out CoinDepot[] changeCoins);
+
+ change = changeCoins;
+ remainder = remainingAmount;
+
+ return true;
}
+ ///
+ /// Withdraws the input coins from the machine.
+ ///
+ /// The withdrawn coins.
public override string ToString()
{
- //TODO
- return "";
+ string coinString = "";
+ string productString = "";
+ foreach (var coin in CoinType.GetValues(typeof(CoinType)))
+ {
+ CoinDepot? depot = GetDepotByType(_currentChangeCoins, (CoinType)coin);
+ if (depot != null)
+ {
+ coinString += $"|{depot.ToString()}".PadRight(40) + $"|{Environment.NewLine}";
+ }
+ }
+ foreach (var product in _products)
+ {
+ productString += $"|{product.ToString()}".PadRight(40) + $"|{Environment.NewLine}";
+ }
+ return $"|=======================================|{Environment.NewLine}" +
+ $"|Machine located at: {Location}".PadRight(40) + $"|{Environment.NewLine}" +
+ $"|=======================================|{Environment.NewLine}" +
+ coinString +
+ $"|=======================================|{Environment.NewLine}" +
+ productString +
+ "|=======================================|";
}
+ ///
+ /// Adds the input coins to the change coins.
+ ///
private void AddInputToChange()
{
- //TODO
+ for (int i = 0; i < _currentInputCoins.Length; i++)
+ {
+ while (_currentInputCoins[i].Count > 0)
+ {
+ _currentChangeCoins[i].Add();
+ _currentInputCoins[i].Withdraw();
+ }
+ }
}
- private static CoinDepot[] CreateCoinDepots(int count)
+ ///
+ /// Creates the coin depots.
+ ///
+ ///
+ /// The created coin depots.
+ private static CoinDepot[] CreateCoinDepots(int count, bool fill = false)
{
- //TODO
- return [];
+ CoinDepot[] coinDepots = new CoinDepot[count];
+ CoinType[] coinTypes = (CoinType[])Enum.GetValues(typeof(CoinType));
+ for (int i = 0; i < count; i++)
+ {
+ coinDepots[i] = new CoinDepot(coinTypes[i]);
+ }
+
+ if (fill)
+ {
+ for (int i = 0; i < coinDepots.Length; i++)
+ {
+ while(coinDepots[i].Count < 3) // magic number
+ {
+ coinDepots[i].Add();
+ }
+ }
+ }
+
+ return coinDepots;
}
+ ///
+ /// Creates the default products.
+ ///
+ /// The default products.
private static Product[] CreateDefaultProducts()
{
- //TODO
- return [];
+ Product[] products = new Product[3]; // magic number
+ products[0] = new Product("Cappuccino", 085, 10);
+ products[1] = new Product("Mocca", 100, 10);
+ products[2] = new Product("Cacao", 060, 10);
+
+ return products;
}
+ ///
+ /// Gets the depot by the given coin type.
+ ///
+ ///
+ ///
+ /// The depot with the given coin type or null if not found.
private static CoinDepot? GetDepotByType(CoinDepot[] coinDepots, CoinType coinType)
{
- //TODO
+ foreach (var coinDepot in coinDepots)
+ {
+ if (coinDepot.Coin == coinType)
+ {
+ return coinDepot;
+ }
+ }
return null;
}
+ ///
+ /// Prepares the change coins for the given amount.
+ ///
+ ///
+ ///
+ /// The remaining amount that could not be changed.
private int? PrepareChangeCoins(int amount, out CoinDepot[] changeCoins)
{
- //TODO
- changeCoins = [];
- return null;
+ changeCoins = CreateCoinDepots(_currentChangeCoins.Length);
+
+ foreach (var coinType in withdrawalOrder)
+ {
+ CoinDepot? depot = GetDepotByType(_currentChangeCoins, coinType);
+ if (depot == null)
+ {
+ continue;
+ }
+
+ while (amount >= (int)coinType && depot.Count > 0)
+ {
+ amount -= (int)coinType;
+ depot.Withdraw();
+ CoinDepot? changeDepot = GetDepotByType(changeCoins, coinType);
+ changeDepot?.Add();
+ }
+ }
+
+ changeCoins = RemoveUnusedCoins(changeCoins);
+ return amount > 0 ? amount : null;
+ }
+
+ private CoinDepot[] RemoveUnusedCoins(CoinDepot[] coins)
+ {
+ int count = 0;
+ foreach (var coin in coins)
+ {
+ if (coin.Count > 0)
+ {
+ count++;
+ }
+ }
+
+ CoinDepot[] usedCoins = new CoinDepot[count];
+ int j = 0;
+ for (int i = 0; i < coins.Length; i++)
+ {
+ if (coins[i].Count > 0)
+ {
+ usedCoins[j] = coins[i];
+ j++;
+ }
+ }
+
+ return usedCoins;
}
+ ///
+ /// Sums the value of all coins in the coin depots.
+ ///
+ ///
+ /// The sum of all coins in the coin depots.
private static int SumDepotValue(CoinDepot[] coinDepots)
{
- //TODO
- return 0;
+ int sum = 0;
+ foreach (var coinDepot in coinDepots)
+ {
+ sum += coinDepot.Count * (int)coinDepot.Coin;
+ }
+ return sum;
}
+ ///
+ /// Tries to find a product by its name.
+ ///
+ ///
+ ///
+ /// True if the product was found, false otherwise.
private bool TryFindProduct(string productName, out Product? product)
{
- //TODO
+ foreach (var _product in _products)
+ {
+ if(_product.Name == productName)
+ {
+ product = _product;
+ return true;
+ }
+ }
+
product = null;
return false;
}
+
+ ///
+ /// Gets the available products.
+ ///
+ /// The available products.
+ private Product[] GetAvailableProducts()
+ {
+ int count = 0;
+ foreach (var product in _products)
+ {
+ if (product.InStock)
+ {
+ count++;
+ }
+ }
+
+ Product[] availableProducts = new Product[count];
+ int j = 0;
+ for (int i = 0; i < _products.Length; i++)
+ {
+ if (_products[i].InStock)
+ {
+ availableProducts[j] = _products[i];
+ j++;
+ }
+ }
+
+ return availableProducts;
+ }
}
diff --git a/CoffeeVendingMachines/CoinDepot.cs b/CoffeeVendingMachines/CoinDepot.cs
index f51b62a..d2e650c 100644
--- a/CoffeeVendingMachines/CoinDepot.cs
+++ b/CoffeeVendingMachines/CoinDepot.cs
@@ -29,7 +29,7 @@ public class CoinDepot
public override string ToString()
{
- return $"{Coin}: {Count}";
+ return $"{Coin} x{Count}";
}
public bool Withdraw()
diff --git a/CoffeeVendingMachines/Model.cs b/CoffeeVendingMachines/Model.cs
index 7119c36..d0340b1 100644
--- a/CoffeeVendingMachines/Model.cs
+++ b/CoffeeVendingMachines/Model.cs
@@ -2,10 +2,10 @@ namespace CoffeeVendingMachines;
public enum CoinType
{
- Cent05,
- Cent10,
- Cent20,
- Cent50,
- Euro01,
- Euro02
+ Cent05 = 005,
+ Cent10 = 010,
+ Cent20 = 020,
+ Cent50 = 050,
+ Euro01 = 100,
+ Euro02 = 200
}
\ No newline at end of file
diff --git a/CoffeeVendingMachines/Product.cs b/CoffeeVendingMachines/Product.cs
index 47d021a..c962494 100644
--- a/CoffeeVendingMachines/Product.cs
+++ b/CoffeeVendingMachines/Product.cs
@@ -5,17 +5,20 @@ public class Product
public const int FallbackPrice = 50;
private readonly int _price;
private int _stock;
- public readonly bool InStock;
- public readonly string Name;
+ public bool InStock => _stock > 0;
+ public string Name { get; }
public int NumberSold { get; private set; }
- public int Price { get; private init; }
+ public int Price => _price;
public Product (string name, int price = FallbackPrice, int stock = 0)
{
Name = name;
_price = price;
_stock = stock;
- InStock = _stock > 0;
+ if(price <= 0 || price % 5 != 0)
+ {
+ _price = FallbackPrice;
+ }
}
public bool AddSale()
@@ -32,6 +35,6 @@ public class Product
public override string ToString()
{
- return $"{Name} € {Price} [{_stock} in stock | {NumberSold} sold]";
+ return $"{Name,-10} € {(decimal)Price/100:0.00} [{_stock} in stock | {NumberSold} sold]";
}
}