Framework/Betting/Bank.cs

Component that manages betting for seats in a card game. It enforces min/max bet settings, provides chip denominations, and implements host-only operations to commit, refund, award, collect wagers to pot or house, and reset wagers and ready flags.

Networking
namespace CardGames;

/// <summary>
/// Betting controller for a game. Manages wagers and bankrolls for each seat, and enforces minimum and maximum bet limits.
/// </summary>
public sealed class Bank : Component
{
	/// <summary>
	/// Smallest wager that counts as a bet (a seat that can't cover this sits out).
	/// </summary>
	[Property] public long MinBet { get; set; } = 10;

	/// <summary>
	/// Largest wager a seat may commit in a round.
	/// </summary>
	[Property] public long MaxBet { get; set; } = 500;

	/// <summary>
	/// Chip denominations offered as bet buttons.
	/// </summary>
	[Property] public long[] ChipValues { get; set; } = { 10, 25, 100 };

	/// <summary>
	/// Host: move <paramref name="amount"/> chips from a seat's bankroll into its committed wager. False if unaffordable or over <see cref="MaxBet"/>.
	/// </summary>
	public bool Commit( Seat seat, long amount )
	{
		if ( !Networking.IsHost || seat is null || amount <= 0 || seat.Currency < amount ) return false;
		if ( seat.Wager + amount > MaxBet ) return false;
		seat.Currency -= amount;
		seat.Wager += amount;
		return true;
	}

	/// <summary>
	/// Host: return a seat's committed wager to its bankroll (cancel the bet).
	/// </summary>
	public void Refund( Seat seat )
	{
		if ( !Networking.IsHost || seat is null ) return;
		seat.Currency += seat.Wager;
		seat.Wager = 0;
	}

	/// <summary>
	/// Host: pay chips into a seat's bankroll (winnings paid by the house).
	/// </summary>
	public void Award( Seat seat, long amount )
	{
		if ( !Networking.IsHost || seat is null || amount <= 0 ) return;
		seat.Currency += amount;
	}

	/// <summary>
	/// Host: the seat's committed wager is lost to the house (clears the chips in front of it).
	/// </summary>
	public void CollectToHouse( Seat seat )
	{
		if ( !Networking.IsHost || seat is null ) return;
		seat.Wager = 0;
	}

	/// <summary>
	/// Host: move the seat's committed wager into a pot.
	/// </summary>
	public void CollectToPot( Seat seat, Pot pot )
	{
		if ( !Networking.IsHost || seat is null || pot is null ) return;
		pot.Contribute( seat, seat.Wager );
		seat.Wager = 0;
	}

	/// <summary>
	/// Host: clear every seat's wager and ready flag, ready for a fresh betting phase.
	/// </summary>
	public void Reset( IEnumerable<Seat> seats )
	{
		if ( !Networking.IsHost || seats is null ) return;

		foreach ( var seat in seats )
		{
			seat.Wager = 0;
			seat.Ready = false;
		}
	}
}