2425-2ihif-pose-classroom-ex-col-02-bucket-chain-ex-col-02-bucket-chain created by GitHub Classroom
Find a file
2024-12-12 17:04:24 +01:00
BucketChain Initialized everything and completed Bucket.cs, Fire.cs, Well.cs. 2024-12-12 17:04:24 +01:00
BucketChain.Test Initial commit 2024-11-17 08:52:38 +00:00
pics Initial commit 2024-11-17 08:52:38 +00:00
.gitignore Initial commit 2024-11-17 08:52:38 +00:00
BucketChain.sln Initial commit 2024-11-17 08:52:38 +00:00
readme.adoc add deadline 2024-12-12 14:54:24 +00:00

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

= Col.02 -- Bucket Chain

In this assignment you will simulate a simple bucket chain used to fight fires.
This method was very common in the past, but is sometimes still used today.

People create a chain and pass buckets with water from one to the other until the last person can use it to fight the fire.

image:pics/historic_bucket_chain.jpg[Historic BucketChain, width=300]
image:pics/throwing_water.jpg[Throwing Water, width=300]
image:pics/modern_bucket_chain.jpg[Modern BucketChain, width=300]

This chain will be implemented as a *double linked list*.

[plantuml]
----
@startuml

class Bucket {
    -double _capacityLiters [readonly]
    -double _contentLiters
    +bool IsEmpty [readonly]

    +Bucket(double)
    +double Fill(double)
    +double Empty()
}

class Chain {
    -Fire _fire [readonly]
    -int _requiredPeople [readonly]
    -Well _well [readonly]
    -double _bucketSize [readonly]
    -Person _firstPerson
    -int _availableBuckets

    +Chain(int, int, double, Well, Fire, Person)
    +bool Operate(int, out bool)
    +string ToString() [override]
}

class Fire {
    -double _growRate [readonly]
    +double FireSize [private set]
    +bool Extinguished [readonly]

    +Fire(double, double)
    +void GetHitByWater(double)
    +void BurnHigher()
    +string ToString() [override]
}

class Person {
    -Bucket? _backwardBucket
    -Bucket? _forwardBucket
    +bool HasBucket [readonly]
    +Person? LeftNeighbor [private set]
    +Person? RightNeighbor [private set]
    +int LastStepPerformed [private set]

    +Person()
    +void JoinChain(Person, bool)
    +bool MoveBucket(int)
    +void FightFire(Fire)
    +void UseWell(Well, Bucket?)
    +string ToString() [override]
}

class Well {
    -double _maxCapacity [readonly]
    -double _refillRate [readonly]
    +double LitersRemaining [private set]

    +Well(double, double)
    +void Refill()
    +void FillBucket(Bucket)
    +string ToString() [override]
}

Chain "1" -r- "1" Person
Person "0..2" -- "0..2" Person
Chain "1" -l- "1" Fire
Chain "1" -d- "1" Well
Person "1" -- "0..2" Bucket

@enduml
----

NOTE: The class diagram still contains the private fields, but _not_ the private methods. You need to start structuring your applications yourself.

== Bucket Movement

Buckets filled with water move in the _forward_ direction to the right, towards the fire.
Emptied buckets move in the _backward_ direction to the left, towards the well.

.Movement of buckets in the chain
image::pics/chain_illustration.png[Chain Movement,width=600]

CAUTION: The fire can only be fought if the chain is long enough. For example: if 6 people are required to span the distance between well and fire, but only 5 work in the chain the buckets cannot be emptied on the fire.

The `Chain` class calls the `UseWell` method for the _first_ person if they have an empty bucket, and it calls the `FightFire` method for the _last_ person if they have a filled bucket.

=== Bucket Exchange

Buckets are always exchanged between two people in the chain who negotiate the exchange themselves.
The `Chain` class as overall instance simply calls the `MoveBucket` method for each person, but the actual actions are determined by the people themselves.

A person can, at all times, have:

* No buckets or
* One forward bucket or
* One backward bucket or
* One forward _and_ one backward bucket

.Possible States of a person
image::pics/person_states.png[Possible states of a person,width=600]

It can only accept a forward bucket if that 'slot' is empty -- the same is true for the backward bucket.
Only first and last person can switch a bucket from 'forward' to 'backward' or vice versa (by filling or emptying).

The following shows _some_ possible exchange scenarios:

* image:pics/swap_sample_01.png[Swap Sample 1, width=400]
* image:pics/swap_sample_02.png[Swap Sample 2, width=400]
* image:pics/swap_sample_03.png[Swap Sample 3, width=400]
* image:pics/swap_sample_04.png[Swap Sample 4, width=400]

=== Exchange limit

Each person can only perform one exchange per _step_.
For example, if person 1 exchanges buckets with person 2, person 2 _cannot_ exchange buckets with person 3 during this step, but person 3 could still exchange buckets with person 4.
This leads to buckets being transported step by step instead of being passed from start to finish within one step.

=== Number of Buckets

In each chain there is a limited amount of buckets.
It is possible, that there are fewer buckets than people in the chain.
That means, that some people sometimes won't have a bucket in hand.
They still stay at their position and forward buckets as they arrive at their location.

== People joining the Chain

In the excitement of a burning fire people are running from all directions to join the bucket chain and help extinguish the fire.
As a result, new people can join at all positions of the chain.
Doing so they will talk to their new neighbors (left, right or both), quickly introducing themselves, so that everyone knows who to hand full buckets to and from whom to receive the empty ones.

* image:pics/join_chain_01.png[Join Chain Option 1, width=500]
* image:pics/join_chain_02.png[Join Chain Option 2, width=500]
* image:pics/join_chain_03.png[Join Chain Option 3, width=500]

There can be _more_ people than required, but the fire can only be fought if there are _at least_ enough.

== Implementation Hints

Parts of the specified logic is quite complex and might be hard to understand.
Make sure to _carefully_ read the provided XML Doc as well as reading through and understanding the provided unit tests.

It might be helpful to draw different scenarios on a piece of paper before starting the implementation to better understand what has to happen in which case.

TIP: You _will_ need some `private` helper methods

=== Symbols

The string representations ask for specific symbols, you may use these:

[cols="1,4",width=50%]
|===
|Symbol |Usage

|🔘
|Empty Bucket

|🔵
|Filled Bucket

|🫲
|No Bucket

|❔
|Open slot for missing person in the chain

|🔥
|Fire

|💧
|Well
|===

== Program & Sample Run

A `Program` has already been provided which creates a fire, a well, some people and a chain.
It executes several steps on the chain to finally extinguish the fire.
Based on the current step people will join the chain at different positions.
Only after a while the chain will be long enough to start fighting the fire.
Once you are done with your implementation this program should run to completion.

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

The application will wait for a second between steps so that the progression of the buckets up and down the chain is better visible.

video::pics/bucket_chain_sample_run.mp4[Sample Run Video,width=500]