This commit is contained in:
JFronny 2020-06-13 12:15:11 +02:00
parent 199a27bcad
commit ccec3490d9
6 changed files with 93 additions and 28 deletions

View File

@ -13,12 +13,12 @@ namespace Lemonade
private readonly Image imgControl; private readonly Image imgControl;
public AnimationScreen(Settings set) : base(100, 20, Black, set.Color) public AnimationScreen(Settings settings) : base(100, 20, Black, settings.Color)
{ {
ContentPanel.ForeColor = DarkGray; ContentPanel.ForeColor = DarkGray;
Title = "Lemonade - Anim"; Title = "Lemonade - Anim";
imgControl = new Image(new Pixel[0, 0]); imgControl = new Image(new Pixel[0, 0]);
SetWeather(new Weather()); SetWeather(new Weather(settings));
ContentPanel.Controls.Add(imgControl); ContentPanel.Controls.Add(imgControl);
Input += (screen, args) => Ok?.Invoke(); Input += (screen, args) => Ok?.Invoke();
Close += (screen, args) => Ok?.Invoke(); Close += (screen, args) => Ok?.Invoke();
@ -29,7 +29,6 @@ namespace Lemonade
public void SetWeather(Weather w) public void SetWeather(Weather w)
{ {
Title = $"Lemonade - Weather: {w}"; Title = $"Lemonade - Weather: {w}";
//TODO weather events (storm (no sales), heat wave (more sales))
Pixel sky = new Pixel(w.W switch Pixel sky = new Pixel(w.W switch
{ {
Rainy => Black, Rainy => Black,

View File

@ -1,15 +1,45 @@
using System; using System;
using System.Collections.Generic;
namespace Lemonade namespace Lemonade
{ {
public class PlayerState public class PlayerState
{ {
#region Autogenerated equality comparison stuff
protected bool Equals(PlayerState other) => Number == other.Number;
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((PlayerState) obj);
}
public override int GetHashCode() => Number;
private sealed class NumberEqualityComparer : IEqualityComparer<PlayerState>
{
public bool Equals(PlayerState x, PlayerState y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
if (x.GetType() != y.GetType()) return false;
return x.Number == y.Number;
}
public int GetHashCode(PlayerState obj) => obj.Number;
}
public static IEqualityComparer<PlayerState> NumberComparer { get; } = new NumberEqualityComparer();
#endregion
public readonly int Number;
public int Budget; public int Budget;
public int Earnings; public int Earnings;
public int Expenses; public int Expenses;
public int Glasses; public int Glasses;
public int GlassPrice; public int GlassPrice;
public int Number;
public int Sales; public int Sales;
public int Signs; public int Signs;
@ -19,24 +49,27 @@ namespace Lemonade
Number = number; Number = number;
} }
//TODO (maybe) balance, increase difficulty?
public void CalculateIncome(int signCost, int glassCost, Weather weather, Settings settings) public void CalculateIncome(int signCost, int glassCost, Weather weather, Settings settings)
{ {
//Calculate combined expenses
Expenses = signCost * Signs + glassCost * Glasses; Expenses = signCost * Signs + glassCost * Glasses;
//Calculate a scalar for sales between 0.2 and 1.5 based on the weather factor
double weatherFactor = double weatherFactor = (weather.Factor * 2 + 1d) / (settings.DifficultyFactor * 2d + 1d) / 2d;
(weather.Factor * 2 + 1d) / (settings.DifficultyFactor * 2d + 1d) / //Calculate a scalar between 0.3 and (basically) 2.5 based on the amount of signs
2d; //calculate a scalar for sales between 0.2 and 1.5 based on the weather factor double signFactor = 2.5d - (settings.DifficultyFactor + 0.1) * 2d / (Signs + 1d);
double signFactor = //Calculate a scalar between (basically) 0 and 3 based on the price of lemonades
2.5d - (settings.DifficultyFactor + 0.1) * 2d / double priceFactor = 3 / (GlassPrice / 2d + 1);
(Signs + 1d); //calculate a scalar between 0.3 and (basically) 2.5 based on the amount of signs //Multiply the factors and sanitize results
double Sales = (int) (weatherFactor * signFactor * priceFactor * Glasses);
priceFactor = //Apply weather events to Sales
3 / (GlassPrice / 2 + if (weather.Heatwave) Sales = (int) (Sales * 1.2);
1); //calculate a scalar between (basically) 0 and 3 based on the price of lemonades if (weather.Thunderstorm) Sales = 0;
Sales = (int) Math.Max(Math.Min(weatherFactor * signFactor * priceFactor * Glasses, Glasses), //Sanitize sales
0); //Multiply the factors and sanitize results Sales = Math.Max(Math.Min(Sales, Glasses), 0);
Earnings = (int) Math.Floor((double) Sales * GlassPrice); //Convert result to integer //Calculate earnings from sales
Earnings = (int) Math.Floor((double) Sales * GlassPrice);
//Calculate new budget
Budget += Earnings - Expenses; Budget += Earnings - Expenses;
} }
} }

View File

@ -24,12 +24,19 @@ namespace Lemonade
public event OkDelegate Ok; public event OkDelegate Ok;
public void Setup(IEnumerable<PlayerState> players) public void Setup(IEnumerable<PlayerState> players, Weather weather)
{ {
lab.Content = players.ToStringTable( if (weather.Heatwave)
lab.Content = "There was a heatwave";
else if (weather.Thunderstorm)
lab.Content = "Lightning struck your table while you were setting it up. Nothing was sold";
else
lab.Content = $"The weather was {weather}. Nothing out of the ordinary happened";
lab.Content += Environment.NewLine + players.ToStringTable(
new[] new[]
{ {
"Player", "Glasses made", "Earnings per glass", "Glasses sold", "Signs made", "Income", "Expenses", "Player", "Glasses made", "Earnings per glass", "Glasses sold", "Signs made",
"Income", "Expenses",
"Profit", "Budget" "Profit", "Budget"
}, },
s => s.Number, s => s.Number,

View File

@ -1,20 +1,22 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading; using System.Threading;
using CC_Functions.Commandline.TUI;
namespace Lemonade namespace Lemonade
{ {
//TODO implement thunderstorm chance on bad weather //TODO implement visual feedback for weather events
public class ScreenManager public class ScreenManager
{ {
private readonly AnimationScreen _animator; private readonly AnimationScreen _animator;
private readonly List<PlayerState> _players;
private readonly ResultScreen _result; private readonly ResultScreen _result;
private readonly Settings _settings; private readonly Settings _settings;
private readonly TransactionScreen _transaction; private readonly TransactionScreen _transaction;
private int _currentPlayer; private int _currentPlayer;
private int _day; private int _day;
private bool _initialEvent = true; private bool _initialEvent = true;
private readonly List<PlayerState> _players;
private bool _running; private bool _running;
private GameState _state; private GameState _state;
private Weather _weather; private Weather _weather;
@ -75,8 +77,7 @@ namespace Lemonade
case GameState.Setup: case GameState.Setup:
if (_initialEvent) if (_initialEvent)
{ {
_day++; _weather = new Weather(_settings);
_weather = new Weather();
_animator.SetWeather(_weather); _animator.SetWeather(_weather);
_animator.Render(); _animator.Render();
_initialEvent = false; _initialEvent = false;
@ -98,8 +99,19 @@ namespace Lemonade
case GameState.Event: case GameState.Event:
if (_initialEvent) if (_initialEvent)
{ {
_result.Setup(_players); _result.Setup(_players, _weather);
_result.Render(); _result.Render();
_day++;
if (_players.Any(s => s.Budget < GlassCost))
{
Console.Clear();
IEnumerable<PlayerState> lost = _players.Where(s => s.Budget < GlassCost);
Console.WriteLine($"The following players are out: {string.Join(", ", lost.Select(s => s.Number.ToString()))}");
Thread.Sleep(2000);
Console.Clear();
_players.RemoveAll(s => lost.Contains(s));
}
DiffDraw.Draw(_settings.Color, true);
_initialEvent = false; _initialEvent = false;
} }
_result.ReadInput(); _result.ReadInput();

View File

@ -84,6 +84,10 @@ namespace Lemonade
_signs.Value = 0; _signs.Value = 0;
CalculateMax(); CalculateMax();
_infoLabel.Content = $"It is day {day}, the weather is {weather}"; _infoLabel.Content = $"It is day {day}, the weather is {weather}";
if (weather.W == W.Hot_and_dry)
_infoLabel.Content += ". There is a chance of heatwaves";
else if (weather.W == W.Rainy)
_infoLabel.Content += ". There is a chance of thunderstorms";
_infoLabel.Point = new Point(ContentPanel.Size.Width / 2 - _infoLabel.Content.Length / 2, 0); _infoLabel.Point = new Point(ContentPanel.Size.Width / 2 - _infoLabel.Content.Length / 2, 0);
_glassesLabel.Content = $"How many glasses of lemonade do you wish to make? {lemonadeCost}ct each"; _glassesLabel.Content = $"How many glasses of lemonade do you wish to make? {lemonadeCost}ct each";
_glassesLabel.Point = new Point(ContentPanel.Size.Width / 2 - _glassesLabel.Content.Length / 2, 2); _glassesLabel.Point = new Point(ContentPanel.Size.Width / 2 - _glassesLabel.Content.Length / 2, 2);

View File

@ -6,7 +6,17 @@ namespace Lemonade
{ {
private static readonly Random rnd = new Random(); private static readonly Random rnd = new Random();
public double Factor = rnd.NextDouble(); public readonly bool Heatwave;
public readonly bool Thunderstorm;
public double Factor;
public Weather(Settings settings)
{
Factor = rnd.NextDouble();
Heatwave = W == W.Hot_and_dry && rnd.NextDouble() > settings.DifficultyFactor;
Thunderstorm = W == W.Rainy && rnd.NextDouble() < settings.DifficultyFactor;
}
public W W public W W
{ {