2425-2ihif-pose-classroom-ex-col-03-santa-col-03-santa-template created by GitHub Classroom
Find a file
2024-12-19 16:36:04 +01:00
pics Initial commit 2024-12-11 15:23:18 +00:00
SantaClausInc Completed Parcel 2024-12-19 16:36:04 +01:00
SantaClausInc.Test Initial commit 2024-12-11 15:23:18 +00:00
.gitignore Initial commit 2024-12-11 15:23:18 +00:00
readme.adoc add deadline 2024-12-19 13:58:27 +00:00
SantaClausInc.sln Initial commit 2024-12-11 15:23:18 +00:00

[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/_bYEbrbV)
:sectnums:
:nofooter:
:toc: left
:icons: font
:data-uri:
:source-highlighter: highlightjs
:stem: latexmath

= Col.03 -- Santa Claus Inc.

The Santa Claus Inc. company is preparing a very extensive delivery tour for Christmas.
Your task is to implement a tour planning software which will:

* Determine how many and which presents each child will receive
* Load & prepare the sleighs
** Due to a recent efficiency program several Santa clones are available to operate multiple sleighs
* Send the sleighs on delivery tours to the various cities
* Prints the tour logs of the sleighs

image::pics/santa.png[Santa's Sleigh]

== Implementation

.Logic
[plantuml]
----
@startuml
hide empty fields
hide empty methods

class GoodAndNaughtyList {
    +GoodAndNaughtyList(List<ChildInfo>)
    +List<ChildInfo> GetChildrenByCity(string)
    +List<string> GetAllCities()
    {static} +int CalcParcels(double)
}
class ChildInfo {
    +string Name [readonly]
    +int Age [readonly]
    +string City [readonly]
    +int HouseId [readonly]
    +double GoodOrNaughty [readonly]
}
class Parcel {
    +ChildInfo ForChild [readonly]
    +string Description [readonly]

    +string ToString() [override]
}
class Sleigh {
    +string TargetCity [readonly]

    +Sleigh(int, string)
    +bool Load(Stack<Parcel>)
    +List<string> ExecuteTour()
}

Parcel "n" -l- "1" ChildInfo
Sleigh "1" -d- "n" Parcel
GoodAndNaughtyList "1" -- "n" ChildInfo

@enduml
----

.Utility
[plantuml]
----
@startuml
hide empty fields
hide empty methods

class List<TValue> {
    +int InitialCapacity [const]
    +int Count [private set]
    +int Capacity [readonly]
    +TValue? this[int index]

    +List()
    +void Add(TValue)
}
class Stack<TValue> {
    +int Count [private set]

    +Stack()
    +void Push(TValue)
    +TValue? Peek()
    +TValue? Pop()
}
class Preparation {
    {static} +List<Sleigh> PrepareTours(GoodAndNaughtyList)
}
class RandomProvider {
    {static} +Random Random
}

@enduml
----

NOTE: As usual extensive XMLDoc & Unit Tests have been provided

=== Collections

* To support the complex logic this application requires, supporting collections need to be _implemented_
* These collections have to be implemented in a _generic_ fashion

==== List

* Implement as an _array list_
* It has to be _generic_, accepting a `TValue` _type parameter_
* The initial size is `4`
* The growth factor is `1.5`
** If the calculated size is not a whole number round _up_ to the next whole number
* Provides an _indexer_
** If an invalid index is supplied the `default` value of the `TValue` type parameter is returned

TIP: You do _not_ have to implement additional methods like `Remove` or `Contains`

==== Stack

* Implement a stack based on _nodes_ and _pointers_
** You could add a _private_ node class
* It has to be generic, accepting a `TValue` type parameter
* Implement _correctly_:
** `Push`
** `Peek`
** `Pop`
* If the stack is empty `Peek` & `Pop` return the `default` value of the `TValue` type

=== Tour Planning Logic

* Read the provided XMLDoc carefully
* The following contains some additional explanations & clarifications for some parts of the implementation

CAUTION: Just in case it is not clear enough for someone: you must _not_ use framework collections, but only those you implemented yourself in this assignment

==== `GoodAndNaughtyList`

* The 'good or naughty' rating of a child is multiplied by `1.5` to determine the amount of presents which will be allocated for that child
** A _negative_ (very naughty) rating does _not_ lead to the child having to give Santa presents 😉
*** => the min. amount is `0`
** The amount of presents is rounded _down_ to the next whole number
** Only 'whole' presents are allocated -- no '0.6 presents' or something like that
* `GetAllCities` returns a _distinct_ list of city names

==== `Parcel`

* The `ToString` implementation follows the format `<Description> for <ChildName> (age <ChildAge>)`
** Example: `Watercolors for Josef (age 9)`

==== `Preparation`

* There is a defined set of possible toys which can be used in presents
* For each present one of the toys is selected by random
** Use `RandomProvider` for the selection logic
* For each city a single sleigh is prepared
** Make sure to set the capacity of the sleigh big enough to hold all parcel piles for all children who will receive at least one present in this city -- sleighs use advanced magic technology, so the size can be easily set as required
* For each child a dedicated pile of presents is prepared
** That pile has a minimal size of one, but can contain many more presents
** Each child has exactly one pile of presents
** No pile of presents contains presents of different children
** The amount of presents is determined by the 'good or naughty' value of each child
* Those piles loaded first on the sleigh will be delivered last
** Those loaded last will be removed first

TIP: A sleigh is a _stack of stacks_

==== `RandomProvider`

You don't have to implement anything here.
But you should read up on https://learn.microsoft.com/en-us/dotnet/api/system.random.shared?view=net-9.0[`Random.Shared`].

==== `Sleigh`

* Several aspects of the sleighs have already been explained in previous sections
* When the sleigh executes its tour delivering all the presents to the deserving, good children it creates a log entry for each of the steps
** First it travels to a city
** Then to the house of the first child
** Then it delivers all the presents
** Then moves to the next house
** ...
** Once all presents have been delivered it returns home to the north-pole
* Each step gets assigned a unique, incrementing step number
* Be careful with the _indentation_ of the various log messages
** 'Inner' steps are indented more than 'outer' steps
** See the sample run output for an example
* The log entries are kept in a `List`

== Program & Sample Run

A `Program` file has been provided.
Executing it after implementing all required pieces should result in an output similar to the following -- toy selection can vary due to randomized generation.

image::pics/sample_run.png[Sample Run]