Some cleanup

This commit is contained in:
Andrew Cooper
2022-04-10 16:09:49 +10:00
parent 0e1ef8fc46
commit fd159ac582
3 changed files with 19 additions and 14 deletions

View File

@@ -9,6 +9,7 @@ internal class HomeTeamPlay : Play
private readonly IRandom _random;
private readonly Clock _clock;
private readonly Defense _defense;
private readonly BallContest _ballContest;
private bool _playContinues;
public HomeTeamPlay(TextIO io, IRandom random, Clock clock, Defense defense)
@@ -18,6 +19,7 @@ internal class HomeTeamPlay : Play
_random = random;
_clock = clock;
_defense = defense;
_ballContest = new BallContest(0.5f, "Shot is blocked. Ball controlled by {0}.", _io, _random);
}
internal override bool Resolve(Scoreboard scoreboard)
@@ -39,10 +41,13 @@ internal class HomeTeamPlay : Play
Resolve(jumpShot, scoreboard);
}
// Either the above resolution has transition to a lay-up
// or the chosen shot is not a jump shot and has not been resolved yet.
_playContinues |= shot is not JumpShot;
while (_playContinues)
{
_playContinues = false;
if (ClockIncrementsToHalfTime(scoreboard)) { return false; }
Resolve(shot, scoreboard);
}
@@ -50,29 +55,21 @@ internal class HomeTeamPlay : Play
return false;
}
private void Resolve(JumpShot shot, Scoreboard scoreboard)
{
var ballContest = new BallContest(0.5f, "Shot is blocked. Ball controlled by {0}.", _io, _random);
private void Resolve(JumpShot shot, Scoreboard scoreboard) =>
Resolve(shot.ToString(), _defense / 8)
.Do(0.341f, () => scoreboard.AddBasket("Shot is good"))
.Or(0.682f, () => ResolveShotOffTarget(scoreboard))
.Or(0.782f, () => ballContest.Resolve(scoreboard))
.Or(0.782f, () => _ballContest.Resolve(scoreboard))
.Or(0.843f, () => ResolveFreeThrows(scoreboard, "Shooter is fouled. Two shots."))
.Or(() => scoreboard.Turnover($"Charging foul. {scoreboard.Home} loses ball."));
}
private void Resolve(Shot shot, Scoreboard scoreboard)
{
_playContinues = false;
private void Resolve(Shot shot, Scoreboard scoreboard) =>
Resolve(shot.ToString(), _defense / 7)
.Do(0.4f, () => scoreboard.AddBasket("Shot is good. Two points."))
.Or(0.7f, () => ResolveShotOffTheRim(scoreboard))
.Or(0.875f, () => ResolveFreeThrows(scoreboard, "Shooter fouled. Two shots."))
.Or(0.925f, () => scoreboard.Turnover($"Shot blocked. {scoreboard.Visitors}'s ball."))
.Or(() => scoreboard.Turnover($"Charging foul. {scoreboard.Home} loses ball."));
}
private void ResolveShotOffTarget(Scoreboard scoreboard) =>
Resolve("Shot is off target", 6 / _defense)

View File

@@ -31,6 +31,8 @@ internal class VisitingTeamPlay : Play
_io.WriteLine();
}
// Either the above resolution has transition to a lay-up
// or the chosen shot is not a jump shot and has not been resolved yet.
_playContinues |= shot is not JumpShot;
while (_playContinues)
@@ -48,7 +50,7 @@ internal class VisitingTeamPlay : Play
.Do(0.35f, () => scoreboard.AddBasket("Shot is good."))
.Or(0.75f, () => ResolveBadShot(scoreboard, "Shot is off the rim.", _defense * 6))
.Or(0.9f, () => ResolveFreeThrows(scoreboard, "Player fouled. Two shots."))
.Or(() => _io.WriteLine("Offensive foul. Dartmouth's ball."));
.Or(() => _io.WriteLine($"Offensive foul. {scoreboard.Home}'s ball."));
private void Resolve(Shot shot, Scoreboard scoreboard) =>
Resolve(shot.ToString(), _defense / 7)
@@ -57,7 +59,7 @@ internal class VisitingTeamPlay : Play
void ResolveBadShot(Scoreboard scoreboard, string message, float defenseFactor) =>
Resolve(message, defenseFactor)
.Do(0.5f, () => scoreboard.Turnover("Dartmouth controls the rebound."))
.Do(0.5f, () => scoreboard.Turnover($"{scoreboard.Home} controls the rebound."))
.Or(() => ResolveVisitorsRebound(scoreboard));
void ResolveVisitorsRebound(Scoreboard scoreboard)
@@ -67,7 +69,7 @@ internal class VisitingTeamPlay : Play
{
_io.WriteLine();
scoreboard.Turnover();
scoreboard.AddBasket("Ball stolen. Easy lay up for Dartmouth.");
scoreboard.AddBasket($"Ball stolen. Easy lay up for {scoreboard.Home}.");
return;
}

View File

@@ -2,6 +2,12 @@ using Games.Common.Randomness;
namespace Basketball;
/// <summary>
/// Supports a chain of actions to be performed based on various probabilities. The original game code gets a new
/// random number for each probability check. Evaluating a set of probabilities against a single random number is
/// much simpler, but yield a very different outcome distribution. The purpose of this class is to simplify the code
/// to for the original probabilistic branch decisions.
/// </summary>
internal struct Probably
{
private readonly float _defenseFactor;