Trouble with simple battle game in C# - c#

The main idea is to each member on team1 attack a random enemy on team2. The damage dealt is based on a spell casted at random from a Grimoire book.
My Code:
using System;
namespace simple_test
{
class Program
{
public class IceLance : Hechizo //hechizo == spell
{
public IceLance(uint d) : base(20)
{
danio = d; // danio == damage
return;
}
public override void Castear() // castear == cast
{
Console.WriteLine("Ice Lance");
}
protected uint danio = 5; // danio == damage
}
public abstract class Hechizo
{
protected Hechizo(uint c)
{
costo = c; // costo == cost
}
public abstract void Castear();
protected uint costo = 1;
public uint Costo
{
get { return costo; }
}
}
public class Personaje // personaje == character
{
public Personaje()
{ }
public Personaje(uint s)
{
salud = s;
}
public void RecibirDanio(uint d) // RecibirDanio == RecieveDamage
{
salud -= d; // salud = salud - d // salud == Health
}
public virtual void Ataque() // Ataque == Attack
{
Console.WriteLine("Ataque melee");
return;
}
public bool IsVivo() // IsVivo == IsAlive
{
return salud > 0;
}
protected uint salud = 100;
}
public class Humano : Personaje // Humano == Human
{
public Humano() : base()
{ }
public Humano(uint s, uint m) : base(s)
{
mana = m;
}
public void CastearGrimorio(int idx)
{
if ((grimorio == null) ||
(idx >= grimorio.Length) || (grimorio[idx] == null))
return;
uint c = grimorio[idx].Costo;
if (mana >= c)
{
mana -= c;
grimorio[idx].Castear();
}
}
public void AprenderHechizo(Hechizo h) // AprenderHechizo == LearnSpell
{
if (grimorio == null)
{
grimorio = new Hechizo[1];
}
else
{
Hechizo[] nuevoGrimorio = new Hechizo[grimorio.Length + 1];
for (uint i = 0; i < grimorio.Length; ++i)
{
nuevoGrimorio[i] = grimorio[i];
}
grimorio = nuevoGrimorio;
}
grimorio[grimorio.Length - 1] = h;
}
public override void Ataque()
{
if (grimorio == null)
Console.WriteLine("Sin mana :(");
else
CastearGrimorio(rnd.Next(0, grimorio.Length));//con esto lanza hechizos al azar
return;
}
private uint mana = 10;
private Hechizo[] grimorio;
private Random rnd = new Random();
}
static public bool TodosMuertos(Personaje[] team) // TodosMuertos == AllDead
{
for (int i = 0; i < team.Length; ++i)
{
if (team[i].IsVivo())
{
return false;
}
}
return true;
}
static void Main(string[] args)
{
Personaje[] team1 = new Personaje[41];
for (int i = 0; i < 3; ++i)
{
Humano mage = new Humano(80, 100);
mage.AprenderHechizo(new IceLance(20));
mage.AprenderHechizo(new IceLance(10));
mage.AprenderHechizo(new IceLance(0));
team1[i] = mage;
}
Personaje[] team2 = new Personaje[41];
for (int i = 0; i < 3; ++i)
{
Humano mage = new Humano(80, 100);
mage.AprenderHechizo(new IceLance(20));
mage.AprenderHechizo(new IceLance(10));
mage.AprenderHechizo(new IceLance(0));
team2[i] = mage;
}
while (!TodosMuertos(team1) && !TodosMuertos(team2)) // turnos
{
Console.WriteLine("team1");
for (int i = 0; i < team1.Length; ++i)
{
if (team1[i].IsVivo())
{
team1[i].Ataque();
// Here should go the RecieveDamage funtion
}
Console.ReadKey();
}
}
}
}
}
This one is a simplified version of the code, i.e. it only has one class and one spell.
I'm not sure how to write the part of how to select a member of the opposite team and in base of the spell casted receiveDamage according to its damage.
PS: I added some references to the spanish language used in the code

You can use the Random class to get a random number between 0 and the number of alive mages on the other team, and use that number to attack. Modify your attack function to take a target mage as a parameter and get them to take damage from there.
using System.Linq; // Add to top of page to use linq functions - .Where()
....
public class Humano : Personaje // Humano == Human
{
...
public override void Ataque(Personaje personaje)
{
if (grimorio == null)
Console.WriteLine("Sin mana :(");
else
{
// Modify CastearGrimoiro to return spell damage. Use person parameter to inflict damage on that person
uint damage = CastearGrimorio(rnd.Next(0, grimorio.Length));//con esto lanza hechizos al azar
personaje.RecibirDanio(damage);
}
}
...
static Random _random = new Random();
static void TakeTeamTurn(Personaje[] team, Personaje[] enemyTeam)
{
var aliveMages = team.Where(m => m.IsVivo()).ToList();
foreach(var mage in aliveMages)
{
// Get team to attack
var attackableMages = enemyTeam.Where(m => m.IsVivo()).ToList(); // Get a list of alive mages on the other team
var mageAttackIndex = _random.Next(attackableMages.Count); // Get a random number between 0 and the number of attackable mages
// (Not written here) Modify your Ataque method to take a mage parameter.
// In the Ataque method or some other method you can use this parameter to do damage to the target mage
var mageToAttack = attackableMages[mageAttackIndex];
mage.Ataque(mageToAttack);
}
}
static void Main(string[] args)
{
...
while (!TodosMuertos(team1) && !TodosMuertos(team2)) // turnos
{
Console.WriteLine("team1");
TakeTeamTurn(team1, team2);
Console.WriteLine("team2");
TakeTeamTurn(team2, team1);
Console.ReadKey();
}
....
Working example here - https://pastebin.com/kSregt24

Related

C#: Get the sum of the value passed to this list

I'm creating a daily report of expenses and incomes, and I would like to return the total I pass to a list. But I'm failing.
Here's the main part.
Class "Movimento", which defines the expense or the incomes themselves.
namespace Agenda_personale
{
internal class Movimento
{
public double Totale;
public DateTime Data;
//public bool IsSpesa()
//{
//if (Totale < 0) { return true; } // se è minore di 0 registra un negativo, quindi una perdita
//else { return false; }
//}
public bool IsSpesa() => Totale < 0;
}
}
And finally, the Bilancio class, which includes the methods to be used to get the expenses, their dates, etc..
internal class Bilancio3
{
private List<Movimento> singoleSpese = new List<Movimento>(); // le liste devono stare private
private List<Movimento> ReportDelMese = new List<Movimento>();
private List<Movimento> ReportDelGiorno = new List<Movimento>();
public double SaldoResiduo()
{
double totale = 0;
for (int i = 0; i < singoleSpese.Count; i++) // singoleSpese è legato a RegistraSpese che aggiunge spese (e date) individuali
{
Movimento spesa = singoleSpese[i];
totale = totale + spesa.Totale; // .Totale è una proprietà
}
Console.WriteLine(totale);
return totale;
}
public void tutteLeSpese()
{
foreach (Movimento s in singoleSpese) // ci dà lui l'oggetto da scorrere
Console.WriteLine(s.Totale + " " + s.Data);
}
public void RegistraMovimento(Movimento s)
{
this.singoleSpese.Add(s);
return;
}
public void ReportGiornaliero()
{
for (int i = 0; i < singoleSpese.Count; i++)
{
int giorno = singoleSpese[i].Data.Day;
int mese = singoleSpese[i].Data.Month;
int anno = singoleSpese[i].Data.Year;
DateTime oggi = DateTime.Now;
if (giorno == oggi.Day)
{
if (mese == oggi.Month)
{
if (anno == oggi.Year)
{
this.ReportDelGiorno.Add(new Movimento());
}
}
}
}
Console.Write(ReportDelGiorno.Sum(x => Convert.ToInt32(x)));
return;
}
public void ReportMensile()
{
for (int i = 0; i < singoleSpese.Count; i++)
{
int mese = singoleSpese[i].Data.Month;
int anno = singoleSpese[i].Data.Year;
DateTime oggi = DateTime.Now;
if (mese == oggi.Month)
{
if (anno == oggi.Year)
{
this.ReportDelMese.Add(new Movimento());
}
}
}
Console.Write(ReportDelMese.Sum(x => Convert.ToInt32(x)));
return;
}
public bool HaiSpesoTroppo()
{
if (SaldoResiduo() < 0)
{
return true;
}
return false;
}
}
}
Error I get is:
Unhandled exception. System.InvalidCastException: Unable to cast object of type 'Agenda_personale.Movimento' to type 'System.IConvertible'.
at System.Convert.ToInt32(Object value)
at Agenda_personale.Bilancio3.<>c.b__6_0(Movimento x) in C:\Users\gabri\source\repos\Agenda_personale\Agenda_personale\Bilancio3.cs:line 85
at System.Linq.Enumerable.Sum[TSource](IEnumerable1 source, Func2 selector)
at Agenda_personale.Bilancio3.ReportGiornaliero() in C:\Users\gabri\source\repos\Agenda_personale\Agenda_personale\Bilancio3.cs:line 85
at Agenda_personale.Program.TestBilancio3() in C:\Users\gabri\source\repos\Agenda_personale\Agenda_personale\Program.cs:line 66
at Agenda_personale.Program.Main(String[] args) in C:\Users\gabri\source\repos\Agenda_personale\Agenda_personale\Program.cs:line 27
Interested in getting the total of ReportDelGiorno and ReportDelMese lists.
Thanks in advance.
ReportDelGiorno and ReportDelMese a lists of Movimento which does not implement IConvertible and can't be converted to int. Just sum Totale:
Console.Write(ReportDelGiorno.Sum(x => x.Totale));
Cast the result to int if needed:
Console.Write((int)ReportDelGiorno.Sum(x => x.Totale));
Try first projecting your Movimento.Totale property (making an assumption here on what you're trying to sum up) using Select() before you call the Sum method, for example:
ReportDelGiorno.Select(m => m.Totale).Sum()
This should return the sum of your "Totale"s.

c# strange classes behavior

so, im making small unity game and have some classes for working with big nubmer's
here is the code for class CurrLevel
public class CurrLevel {
public CurrLevel (int levelNum, string id) {
valuesLevel = "pow" + levelNum.ToString();
if(levelNum != 0){
numberFormatSci = "10^" + levelNum.ToString();
} else {
numberFormatSci = "";
}
identificator = id;
}
public string valuesLevel;
public string numberFormatSci;
public string identificator;
public int getValue(){
return PlayerPrefs.GetInt(identificator+"-"+valuesLevel);
}
public void setValue(int value){
PlayerPrefs.SetInt(identificator+"-"+valuesLevel, value);
}
public void add(int value){
PlayerPrefs.SetInt(identificator+"-"+valuesLevel, PlayerPrefs.GetInt(identificator+"-"+valuesLevel) + value);
}
public void substract(int value){
PlayerPrefs.SetInt(identificator+"-"+valuesLevel, PlayerPrefs.GetInt(identificator+"-"+valuesLevel) - value);
}
}
here is the code for class SomeCurrency
public class SomeCurrency {
public string identificator;
public CurrLevel[] levels = new CurrLevel[10];
public SomeCurrency(string id){
identificator = id;
for(int i = 0; i < 30; i=i+3){
levels[i/3] = new CurrLevel(i, identificator);
}
}
public void add(int power, double value){
int full = (int) value;
int leftover = (int) (value*1000 - full*1000);
if(power >= 3){
levels[power/3-1].add(leftover);
}
levels[power/3].add(full);
updateValues();
}
public SomeCurrency copy(SomeCurrency CurrToCopy){
SomeCurrency copy = new SomeCurrency(CurrToCopy.identificator);
for(int i = 0; i < 30; i++){
copy.levels[i/3] = CurrToCopy.levels[i/3];
}
return copy;
}
public void addAnotherCurrency(SomeCurrency anotherCurr){
for(int i = 0; i < 30; i=i+3){
this.add(i, anotherCurr.levels[i/3].getValue());
}
updateValues();
}
public bool substractAnotherCurrency(SomeCurrency anotherCurr){
SomeCurrency buffer = copy(anotherCurr);
Debug.Log(anotherCurr.levels[1].getValue());
if(canSubstract(buffer)){
Debug.Log(anotherCurr.levels[1].getValue());
// for(int i = 27; i >= 0; i-=3){
// levels[i/3].substract(anotherCurr.levels[i/3].getValue());
// }
return true;
} else {
return false;
}
}
public bool canSubstract(SomeCurrency fromWhereSubstract){
bool possible = false;
for(int i = 0; i < 30; i+=3){
fromWhereSubstract.levels[i/3].substract(levels[i/3].getValue());
if(i != 27){
if(fromWhereSubstract.levels[i/3].getValue() < 0){
fromWhereSubstract.levels[i/3+1].substract(1);
fromWhereSubstract.levels[i/3].add(1000);
}
}
}
if(fromWhereSubstract.levels[9].getValue() < 0){
possible = true;
}
return possible;
}
public void setValue(int power, double value){
int full = (int) value;
int leftover = (int) (value*1000 - full*1000);
if(power >= 3){
string beforeid = identificator+"-"+levels[power/3-1].valuesLevel;
PlayerPrefs.SetInt(beforeid,leftover);
}
string thisid = identificator+"-"+levels[power/3].valuesLevel;
PlayerPrefs.SetInt(thisid,full);
updateValues();
}
public string getStringValue(){
int maxlvl = 0;
for(int i = 27; i >= 0; i=i-3){
if(levels[i/3].getValue() > 0){
maxlvl = i/3;
break;
}
}
string result = levels[maxlvl].getValue().ToString();
if(maxlvl > 0){
string leftover = levels[maxlvl-1].getValue().ToString();
while(leftover.Length != 3){
leftover = "0"+leftover;
}
result += "." + leftover + "*" + levels[maxlvl].numberFormatSci;
}
return result;
}
public void resetValues(){
for(int i = 0; i < 30; i+=3){
levels[i/3].setValue(0);
}
}
private void updateValues(){
for(int i = 0; i < 27; i=i+3){
levels[i/3] = new CurrLevel(i, identificator);
if(levels[i/3].getValue() >= 1000){
levels[i/3].setValue(levels[i/3].getValue()-1000);
levels[i/3+1].setValue(levels[i/3+1].getValue()+1);
}
}
}
}
So basicly, in the code i create to new variables type of SomeCurrency
public NumberFormatting.SomeCurrency playerScore = new NumberFormatting.SomeCurrency("playerScore");
public NumberFormatting.SomeCurrency playerClickValue = new NumberFormatting.SomeCurrency("playerClickValue");
playerScore.resetValues();
playerScore.add(6, 1.32);
playerClickValue.resetValues();
playerClickValue.add(3, 103.831);
And later, when player clicks the button i try to substract one from another
Debug.Log(playerClickValue.levels[1].getValue());
Debug.Log(playerScore.substractAnotherCurrency(playerClickValue));
Debugger firstly print 103 (original value of playerClickValue.levels[1].getValue() from click function), then it prints 103 again (from the function substractAnotherCurrency before if(canSubstract(buffer)), but printing the same variable after this canSubstract shows the value of 783. So, my functions somehow change original value of playerClickValue every time i call substractAnotherCurrency.
What should i change to keep the playerClickValue same, but still checking can i suubstract it from another SomeCurrency, and after checking if i can - do so.
In C#, objects are passed by reference, meaning that if you modify an object in a fonction, it will be modified everywhere. You can read more about it, it will be important when coding. It seems you tried to do something like a copy somewhere, but you don't use the copy at all.
Also, are you sure you want to edit a variable in canSubstact?
The name suggest if will just return a bool and not change anything but you actually call substact in it
fromWhereSubstract.levels[i/3+1].substract(1);

Processing int to name of list

I try to write a simple console application with Hanoi towers. But I am stuck at one point.
In my program I ask a person to write from to which tower wants to put the disk, but: I have 3 lists as towers, I'll ask for a number from gamer and now how I can build a "compare method"? Because I don't want to copy the same piece of code 6 times...
class Towers : Disks
{
//public Towers(int Value, int WhereItIs) : base(Value, WhereItIs) { }
public List<Disks> Tower1 = new List<Disks>();
public List<Disks> Tower2 = new List<Disks>();
public List<Disks> Tower3 = new List<Disks>();
public void Compare(int dyskFrom, int dyskWhere) {
}
public void Display() {
foreach(var i in Tower1){
Console.WriteLine("Where: {0} | Value: {1}", i.WhereItIs, i.Value);
}
}
public void Build(int TowerHigh) {
for (int i = TowerHigh; i > 0; i--) {
Tower1.Add(new Disks {Value = i, WhereItIs = 1 });
}
}
}
class Disks
{
public int Value; //wartosc krazka
public int WhereItIs; //na ktorej wiezy sie on znajduje
}
class Program
{
static void Main(string[] args)
{
Towers Tower = new Towers();
int TowerHigh;
Console.Write("Podaj wysokość wieży: ");
TowerHigh = int.Parse(Console.ReadLine());
Tower.Build(TowerHigh);
Tower.Display();
Tower.Compare(1, 2);
}
}
It's easier to create an array of Stack<Disk>(). This way you can select a tower by index.
I would use a Stack, because thats typically the functionality you need.
Something like: PSEUDO (typed in browser, no syntax checked)
class Disk
{
public int Size {get; set;}
}
static void Main(string[] args)
{
// create the Stack<Disk> array
Stack<Disk>[] towers = new Stack<Disk>[3];
// create each tower
for(int i=0;i<towers.Length;i++)
{
towers[i] = new Stack<Disk>();
// fill the towers.
for(int j=3;j>0;j--)
towers[i].Enqueue(new Disk { Size = j });
}
bool isHoldingDisk = false;
while(true)
{
DisplayTowers(towers);
if(isHoldingDisk)
Console.WriteLine("On what tower do you want to place it?");
else
Console.WriteLine("Choose a tower to pick a disk");
var key = Console.ReadKey(true);
var chosenTowerIndex = 0;
switch(key)
{
case(Key.Escape):
break;
case(Key.D1):
chosenTowerIndex = 0;
break;
case(Key.D1):
chosenTowerIndex = 1;
break;
case(Key.D1):
chosenTowerIndex = 2;
break;
// etc...
}
if((chosenTowerIndex < 1) || (chosenTowerIndex >= towers.Length))
continue;
// check here if you are holding a disk
if(isHoldingDisk)
{
// logic for testing if you can place the disk here...
// using towers[chosenTowerIndex]
// check if it is completed...
if(completed)
break;
isHoldingDisk = false;
}
else
{
// check if you can pickup a disk....(if there is any)
isHoldingDisk = true;
}
}
// final display...
DisplayTowers(towers);
Console.WriteLine("Thanks for playing");
}
static void DisplayTowers(Stack<Disk>[] towers)
{
// draw some fancy asc-ii art...
}

Fibonacci with huge numbers in c#

I`m trying to find the first fib number to contain 1000 digits. Because i have no data-type capeable of holding such a number, i created a class called hugeNumber which holds the digits in a list, with a decimal base. I get a stack overflow at the generation of the list for the "hugenum" class - I am not sure why (is it really not the right way to do it? Is there a better way?)
Here's my code:
class hugeNum
{
List<int> digits = new List<int>();
public hugeNum(int basic)
{
digits.Add(basic);
}
public hugeNum()
{
}
public static hugeNum operator +(hugeNum first, hugeNum second)
{
hugeNum generated = new hugeNum();
hugeNum finalIter = null;
int carry = 0;
int i = 0;
for (i = 0; i<second.digits.Count && i<first.digits.Count; i++)
{
generated.digits.Add(first.digits[i] + second.digits[i] + carry);
if (generated.digits[i] >= 10)
{
carry = 1;
generated.digits[i] -= 10;
}
else
carry = 0;
}
finalIter = first;
if (i==first.digits.Count)
{
finalIter = second;
}
while (i<finalIter.digits.Count)
{
generated.digits.Add(finalIter.digits[i]);
i++;
}
return generated;
}
public int amountOfDigits()
{
return this.digits.Count;
}
}
class Program
{
public static int fibHugesUntilIter(hugeNum huge1, hugeNum huge2, int reqDigits, int iter)
{
if (huge2.amountOfDigits() == reqDigits)
return iter;
return fibHugesUntilIter(huge2, huge1 + huge2, reqDigits, iter + 1);
}
static void Main(string[] args)
{
Console.WriteLine(fibHugesUntilIter(new hugeNum(1), new hugeNum(1), 1000, 1));
}
}
You can use BigInteger without recursion:
public static int FibHugesUntil(BigInteger huge1, BigInteger huge2, int reqDigits)
{
int number = 1;
while (huge2.ToString().Length < reqDigits)
{
var huge3 = huge1 + huge2;
huge1 = huge2;
huge2 = huge3;
number++;
}
return number;
}
static void Main(string[] args)
{
Console.WriteLine(FibHugesUntil(BigInteger.Zero, BigInteger.One, 1000));
}
Answer: 4782

Logic to prevent insertion if there are no available slots

I'm developing an application in ASP.NET with C# and I'm trying to figure out the best way to implement a logic statement that will stop the system from allowing another reservation to be taken if the trailer for canoes and kayaks is full. The issue is the trailer will hold canoes and kayaks, but there's a lot of different combinations.
There are 5 "rows" on the trailer that count upwards vertically, and 2 "columns" that dissect the 5 rows in the middle. I will draw you a diagram to show you what it looks like, and what boats can go where. "C" will stand for Canoe and "K" will stand for Kayak. The trailer looks like this:
C only|C only }
______|______ } BOAT TRAILER
1C\2K|1C\2K }
______|______ }
1C\2K|1C\2K }
______|______ }
1C\2K|1C\2K }
______|______ }
C only| C only }
______|______ }
So my question is, what's the best option as far as coding and logic is concerned to not take any more "reservations" when the trailer is full? This application will be a .aspx form that will do an insert command to SQL server taking customer information.
public enum BoatType : int
{
Kayak = 1,
Canoe = 2
}
public class BoatReservation
{
public int ReservationID { get; set; }
public BoatType ReservationBoatType { get; set; }
}
public class BoatTrailer
{
public List<BoatReservation> CanoeSlots = new List<BoatReservation>();
public List<BoatReservation> RegularSlots = new List<BoatReservation>();
public BoatTrailer()
{
}
public bool AddBoat(BoatReservation b)
{
bool boatAdded = false;
switch (b.ReservationBoatType)
{
case BoatType.Canoe:
if (CanoeSlots.Count() < 4)
{
CanoeSlots.Add(b);
boatAdded = true;
}
else
{
var reg = RegularSlots.Sum(x => Convert.ToInt16(x.ReservationBoatType));
if (reg <= 10)
{
RegularSlots.Add(b);
boatAdded = true;
}
}
break;
case BoatType.Kayak:
{
var reg = RegularSlots.Sum(x => Convert.ToInt16(x.ReservationBoatType));
if (reg <= 11)
{
RegularSlots.Add(b);
boatAdded = true;
}
}
break;
}
return boatAdded;
}
public void RemoveBoat(BoatReservation b)
{
switch (b.ReservationBoatType)
{
case BoatType.Kayak:
if (RegularSlots.Contains(b))
{
RegularSlots.Remove(b);
}
break;
case BoatType.Canoe:
if (RegularSlots.Contains(b))
{
RegularSlots.Remove(b);
}
else
{
if (CanoeSlots.Contains(b))
{
CanoeSlots.Remove(b);
if (RegularSlots.Where(fb => fb.ReservationBoatType == BoatType.Canoe).Count() > 0)
{
//Move Reservation From Regular to Canoe Only With Opening
BoatReservation mv = RegularSlots.FindLast(fb => fb.ReservationBoatType == BoatType.Canoe);
RegularSlots.Remove(mv);
CanoeSlots.Add(mv);
}
}
}
break;
}
}
public string AvailableSlots()
{
string Output = string.Empty;
int AvailableCanoeCnt = (4 - CanoeSlots.Count()) + ((12 - RegularSlots.Count()) / 2);
int AvailableKayakCnt = (12 - RegularSlots.Count());
Output = string.Format("Canoe Slots Left: {0} Kayak Slots Left {1} ", AvailableCanoeCnt, AvailableKayakCnt);
return Output;
}
}
Quick class that handles reservations (both adding and deleting) of canoes/kayaks to fit a trailer.
Not the best question for this site but I will provide a pseudo structure for this.
Trailer Object
JustCanoes int
CanoeKayakBlend int
When reserving...
If the reservation is for a canoe, and the JustCanoes value is < 4, then increase JustCanoes by 1
If JustCanoes is >= 4
If CanoeKayakBlend <= 10
increase CanoeKayakBlend by 2
else
Sorry no reservation available
If the reservation is for a kayak
If CanoeKayakBlend <= 11
increase CanoeKayakBlend by 1
else
Sorry no reservation available
A very quick and simplistic implementation: Here's the Compartment class
class Compartment
{
private readonly int _maxCanoe;
private readonly int _maxKayak;
private int _currentCanoe;
private int _currentKayak;
private readonly int _id;
private bool _fullCanoe;
private bool _fullKayak;
public Compartment(int id, int maxC, int maxK)
{
_id = id;
_maxCanoe = maxC;
_maxKayak = maxK;
_currentCanoe = _currentKayak = 0;
UpdateCapacityStatus();
}
private void UpdateCapacityStatus()
{
_fullCanoe = _maxCanoe == _currentCanoe;
_fullKayak = _maxKayak == _currentKayak;
}
private string Status
{
get { return IsFull() ? "FULL" : "Space available"; }
}
public bool IsFull()
{
return _fullKayak && _fullCanoe;
}
public void AddCanoe()
{
_fullKayak = true; // disable adding kayak
_currentCanoe = _currentCanoe + 1;
_fullCanoe = _maxCanoe == _currentCanoe; //update canoe status
}
public void AddKayak()
{
_fullCanoe = true; //disable adding canoe
_currentKayak = _currentKayak + 1;
_fullKayak = _maxKayak == _currentKayak; //update kayak status
}
public override string ToString()
{
return string.Format("Id: {5}, Status: {0}, with {1} of {2} canoes or {3} of {4} kayaks", Status, _currentCanoe, _maxCanoe, _currentKayak, _maxKayak, _id);
}
public bool CanAddCanoe()
{
return !_fullCanoe;
}
public bool CanAddKayak()
{
return !_fullKayak;
}
}
And here's the driver console app to test, to use it you should refactor it of course.
`class Program
{
static void Main(string[] args)
{
var trailer = new List
{
new Compartment(1, 1, 0),
new Compartment(2, 1, 0),
new Compartment(3, 1, 2),
new Compartment(4, 1, 2),
new Compartment(5, 1, 2),
new Compartment(6, 1, 2),
new Compartment(7, 1, 2),
new Compartment(8, 1, 2),
};
foreach (var compartment in trailer)
{
Console.WriteLine(compartment.ToString());
}
Console.WriteLine("Press c for canoe or k for kayak");
var keepGoing = true;
while (keepGoing)
{
var input = Console.Read();
if (input == 99 || input == 107) //99 c, 107 k
{
if (trailer.All(c => c.IsFull()))
{
keepGoing = false;
}
else
{
if (input == 99)
{
if(!trailer.Any(t=>t.CanAddCanoe()))
{
Console.WriteLine("Cannot add a canoe!!!!");
}
else
{
var firstAvailable = trailer.First(c => c.CanAddCanoe());
firstAvailable.AddCanoe();
}
}
else if (input == 107)
{
if (!trailer.Any(t => t.CanAddKayak()))
{
Console.WriteLine("Cannot add a kayak!!!!");
}
else
{
var firstAvailable = trailer.First(c => c.CanAddKayak());
firstAvailable.AddKayak();
}
}
else
{
Console.WriteLine("Press c for canoe or k for kayak");
}
}
foreach (var compartment in trailer)
{
Console.WriteLine(compartment.ToString());
}
}
}
Console.ReadKey();
}
}`

Categories