@ files
This commit is contained in:
parent
60c55d1180
commit
26131b1c4d
|
@ -1,7 +1,101 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using CC_Functions.Commandline.TUI;
|
||||
using CC_Functions.Misc;
|
||||
using static System.ConsoleColor;
|
||||
using static Lemonade.W;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
public class AnimationScreen
|
||||
public class AnimationScreen : CenteredScreen
|
||||
{
|
||||
public event OkDelegate Ok;
|
||||
public delegate void OkDelegate();
|
||||
private Image imgControl;
|
||||
public AnimationScreen(Settings set) : base(100, 20, Black, set.Color)
|
||||
{
|
||||
ContentPanel.ForeColor = DarkGray;
|
||||
Title = "Lemonade - Anim";
|
||||
imgControl = new Image(new Pixel[0,0]);
|
||||
SetWeather(new Weather());
|
||||
ContentPanel.Controls.Add(imgControl);
|
||||
Input += (screen, args) => Ok?.Invoke();
|
||||
Close += (screen, args) => Ok?.Invoke();
|
||||
}
|
||||
|
||||
public void SetWeather(Weather w)
|
||||
{
|
||||
Title = $"Lemonade - Weather: {w}";
|
||||
//TODO weather events (storm (no sales), heat wave (more sales))
|
||||
Pixel sky = new Pixel(w.W switch
|
||||
{
|
||||
Rainy => Black,
|
||||
Cloudy => DarkBlue,
|
||||
Warm => Blue,
|
||||
Sunny => Blue,
|
||||
Hot_and_dry => Magenta,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
}, Black, ' ');
|
||||
Pixel grass = new Pixel(w.W switch
|
||||
{
|
||||
Rainy => Green,
|
||||
Cloudy => Green,
|
||||
Warm => Green,
|
||||
Sunny => Green,
|
||||
Hot_and_dry => Green,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
}, Black, ' ');
|
||||
Pixel table = new Pixel(DarkGreen, Black, ' ');
|
||||
Pixel glass = new Pixel(Yellow, Black, ' ');
|
||||
Pixel sun = new Pixel(w.W switch
|
||||
{
|
||||
Rainy => Yellow,
|
||||
Cloudy => Yellow,
|
||||
Warm => Yellow,
|
||||
Sunny => Yellow,
|
||||
Hot_and_dry => Red,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
}, Black, ' ');
|
||||
Pixel cloud = new Pixel(Gray, Black, ' ');
|
||||
Pixel rain = new Pixel(DarkBlue, Black, ' ');
|
||||
Pixel[,] image = new Pixel[20, 200];
|
||||
//Draw sky
|
||||
image.Populate(sky);
|
||||
//Draw rain
|
||||
Random rainRng = new Random(100);
|
||||
if (w.W == Rainy)
|
||||
for (int i = 2; i < 12; i++)
|
||||
for (int j = 0; j < 200; j++)
|
||||
if (rainRng.NextDouble() < 0.1)
|
||||
{
|
||||
image[i, j] = rain;
|
||||
image[i + 1, j] = rain;
|
||||
}
|
||||
//Draw floor
|
||||
for (int i = 13; i < 20; i++)
|
||||
for (int j = 0; j < 200; j++)
|
||||
image[i, j] = grass;
|
||||
//Draw table
|
||||
for (int i = 12; i < 16; i++)
|
||||
for (int j = 40; j < 60; j++)
|
||||
image[i, j] = table;
|
||||
//Draw glasses
|
||||
for (int j = 43; j < 57; j += 4)
|
||||
{
|
||||
image[11, j] = glass;
|
||||
image[11, j + 1] = glass;
|
||||
}
|
||||
//Draw sun
|
||||
if (w.W != Rainy && w.W != Cloudy)
|
||||
image.DrawEllipse(new Rectangle(2, 1, 14, 6), sun);
|
||||
//Draw clouds
|
||||
if (w.W == Rainy || w.W == Cloudy)
|
||||
{
|
||||
image.DrawEllipse(new Rectangle(8, 1, 25, 3), cloud);
|
||||
image.DrawEllipse(new Rectangle(40, 3, 40, 3), cloud);
|
||||
}
|
||||
//Set image
|
||||
imgControl.Img = image;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,98 @@
|
|||
$HEADER$namespace $NAMESPACE$
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using CC_Functions.Commandline.TUI;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
public class $CLASS$ {$END$}
|
||||
public static class EllipseDrawer
|
||||
{
|
||||
private static PointF GetEllipsePointFromX(float x, float a, float b) =>
|
||||
//(x/a)^2 + (y/b)^2 = 1
|
||||
//(y/b)^2 = 1 - (x/a)^2
|
||||
//y/b = -sqrt(1 - (x/a)^2) --Neg root for upper portion of the plane
|
||||
//y = b*-sqrt(1 - (x/a)^2)
|
||||
new PointF(x, b * -(float)Math.Sqrt(1 - x * x / a / a));
|
||||
|
||||
public static void DrawEllipse(this Pixel[,] target, Rectangle area, Pixel basePixel)
|
||||
{
|
||||
int p0 = target.GetLength(0);
|
||||
int p1 = target.GetLength(1);
|
||||
bool[,] tmp = new bool[p0, p1];
|
||||
DrawEllipse(tmp, new Rectangle(area.Y, area.X, area.Height, area.Width));
|
||||
for (int i = 0; i < p0; i++)
|
||||
for (int j = 0; j < p1; j++)
|
||||
if (tmp[i, j])
|
||||
target[i, j] = basePixel;
|
||||
}
|
||||
|
||||
private static void DrawEllipse(bool[,] pixels, Rectangle area)
|
||||
{
|
||||
// Get the size of the matrix
|
||||
int matrixWidth = pixels.GetLength(0);
|
||||
int matrixHeight = pixels.GetLength(1);
|
||||
int offsetY = area.Top;
|
||||
int offsetX = area.Left;
|
||||
// Figure out how big the ellipse is
|
||||
float ellipseWidth = area.Width;
|
||||
float ellipseHeight = area.Height;
|
||||
// Figure out the radiuses of the ellipses
|
||||
float radiusX = ellipseWidth / 2;
|
||||
float radiusY = ellipseHeight / 2;
|
||||
//Keep track of the previous y position
|
||||
int prevY = 0;
|
||||
bool firstRun = true;
|
||||
// Loop through the points in the matrix
|
||||
for (int x = 0; x <= radiusX; ++x)
|
||||
{
|
||||
int xPos = x + offsetX;
|
||||
int rxPos = (int)ellipseWidth - x - 1 + offsetX;
|
||||
if (xPos < 0 || rxPos < xPos || xPos >= matrixWidth) continue;
|
||||
PointF pointOnEllipseBoundCorrespondingToXMatrixPosition = GetEllipsePointFromX(x - radiusX, radiusX, radiusY);
|
||||
int y = (int) Math.Floor(pointOnEllipseBoundCorrespondingToXMatrixPosition.Y + (int)radiusY);
|
||||
int yPos = y + offsetY;
|
||||
int ryPos = (int)ellipseHeight - y - 1 + offsetY;
|
||||
if (yPos >= 0)
|
||||
{
|
||||
if (xPos < matrixWidth && yPos < matrixHeight) pixels[xPos, yPos] = true;
|
||||
if(xPos < matrixWidth && ryPos > -1 && ryPos < matrixHeight) pixels[xPos, ryPos] = true;
|
||||
if (rxPos < matrixWidth)
|
||||
{
|
||||
if (yPos < matrixHeight) pixels[rxPos, yPos] = true;
|
||||
if (ryPos > -1 && ryPos < matrixHeight) pixels[rxPos, ryPos] = true;
|
||||
}
|
||||
}
|
||||
//While there's a >1 jump in y, fill in the gap (assumes that this is not the first time we've tracked y, x != 0)
|
||||
for (int j = prevY - 1; !firstRun && j > y - 1 && y > 0; --j)
|
||||
{
|
||||
int jPos = j + offsetY;
|
||||
int rjPos = (int)ellipseHeight - j - 1 + offsetY;
|
||||
if(jPos == rjPos - 1) continue;
|
||||
if(jPos > -1 && jPos < matrixHeight) pixels[xPos, jPos] = true;
|
||||
if(rjPos > -1 && rjPos < matrixHeight) pixels[xPos, rjPos] = true;
|
||||
if (rxPos < matrixWidth)
|
||||
{
|
||||
if(jPos > -1 && jPos < matrixHeight) pixels[rxPos, jPos] = true;
|
||||
if(rjPos > -1 && rjPos < matrixHeight) pixels[rxPos, rjPos] = true;
|
||||
}
|
||||
}
|
||||
firstRun = false;
|
||||
prevY = y;
|
||||
float countTarget = radiusY - y;
|
||||
for (int count = 0; count < countTarget; ++count)
|
||||
{
|
||||
++yPos;
|
||||
--ryPos;
|
||||
// Set all four points in the matrix we just learned about
|
||||
// also, make the indication that for the rest of this row, we need to fill the body of the ellipse
|
||||
if(yPos > -1 && yPos < matrixHeight) pixels[xPos, yPos] = true;
|
||||
if(ryPos > -1 && ryPos < matrixHeight) pixels[xPos, ryPos] = true;
|
||||
if (rxPos < matrixWidth)
|
||||
{
|
||||
if(yPos > -1 && yPos < matrixHeight) pixels[rxPos, yPos] = true;
|
||||
if(ryPos > -1 && ryPos < matrixHeight) pixels[rxPos, ryPos] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ namespace Lemonade
|
|||
{
|
||||
public enum GameState
|
||||
{
|
||||
|
||||
Setup,
|
||||
Transaction,
|
||||
Event
|
||||
}
|
||||
}
|
|
@ -1,7 +1,14 @@
|
|||
using CC_Functions.Commandline.TUI;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
public class Image
|
||||
public class Image : Control
|
||||
{
|
||||
public Pixel[,] Img;
|
||||
public Image(Pixel[,] img) => Img = img;
|
||||
|
||||
public override Pixel[,] Render() => Img;
|
||||
|
||||
public override bool Selectable { get; } = false;
|
||||
}
|
||||
}
|
|
@ -5,4 +5,8 @@
|
|||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CC-Functions.Commandline" Version="1.1.7468.32091" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,35 @@
|
|||
$HEADER$namespace $NAMESPACE$
|
||||
using System;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
public struct $STRUCT$ {$END$}
|
||||
public class PlayerState
|
||||
{
|
||||
public int Budget;
|
||||
public int Glasses;
|
||||
public int Signs;
|
||||
public int GlassPrice;
|
||||
public int Expenses;
|
||||
public int Earnings;
|
||||
public int Sales;
|
||||
public int Number;
|
||||
|
||||
public PlayerState(int number)
|
||||
{
|
||||
Budget = 200;
|
||||
Number = number;
|
||||
}
|
||||
|
||||
public void CalculateIncome(int signCost, int glassCost, Weather weather, Settings settings)
|
||||
{
|
||||
Expenses = signCost * Signs + glassCost * Glasses;
|
||||
|
||||
double weatherFactor = (weather.Factor * 2 + 1d) / (settings.DifficultyFactor * 2d + 1d) / 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); //calculate a scalar between 0.3 and (basically) 2.5 based on the amount of signs
|
||||
double priceFactor = 3 / (GlassPrice / 2 + 1); //calculate a scalar between (basically) 0 and 3 based on the price of lemonades
|
||||
Sales = (int)Math.Max(Math.Min(weatherFactor * signFactor * priceFactor * Glasses, Glasses), 0); //Multiply the factors and sanitize results
|
||||
Earnings = (int)Math.Floor((double)Sales * GlassPrice); //Convert result to integer
|
||||
|
||||
Budget += Earnings - Expenses;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,12 @@ namespace Lemonade
|
|||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hello World!");
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Settings settings = new Settings();
|
||||
ScreenManager screenManager = new ScreenManager(settings);
|
||||
screenManager.Run();
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,42 @@
|
|||
$HEADER$namespace $NAMESPACE$
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using CC_Functions.Commandline;
|
||||
using CC_Functions.Commandline.TUI;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
public class $CLASS$ {$END$}
|
||||
public class ResultScreen : CenteredScreen
|
||||
{
|
||||
public event OkDelegate Ok;
|
||||
public delegate void OkDelegate();
|
||||
private Label lab;
|
||||
public ResultScreen(Settings settings) : base(200, 20, ConsoleColor.Black, settings.Color)
|
||||
{
|
||||
ContentPanel.ForeColor = ConsoleColor.DarkGray;
|
||||
Title = "Lemonade - Daily financial report";
|
||||
lab = new Label("");
|
||||
ContentPanel.Controls.Add(lab);
|
||||
Input += (screen, args) => Ok?.Invoke();
|
||||
Close += (screen, args) => Ok?.Invoke();
|
||||
}
|
||||
|
||||
public void Setup(IEnumerable<PlayerState> players)
|
||||
{
|
||||
lab.Content = players.ToStringTable(new[] {"Player", "Glasses made", "Earnings per glass", "Glasses sold", "Signs made", "Income", "Expenses", "Profit", "Budget"},
|
||||
(s) => s.Number,
|
||||
(s) => s.Glasses,
|
||||
(s) => s.GlassPrice,
|
||||
(s) => s.Sales,
|
||||
(s) => s.Signs,
|
||||
(s) => s.Earnings,
|
||||
(s) => s.Expenses,
|
||||
(s) => s.Earnings - s.Expenses,
|
||||
(s) => s.Budget);
|
||||
lab.Render();
|
||||
ActualSize = new Size(lab.Size.Width, lab.Size.Height);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,113 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using CC_Functions.Commandline.TUI;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
//TODO implement thunderstorm chance on bad weather
|
||||
public class ScreenManager
|
||||
{
|
||||
private readonly AnimationScreen _animator;
|
||||
private readonly ResultScreen _result;
|
||||
private readonly Settings _settings;
|
||||
private readonly TransactionScreen _transaction;
|
||||
private GameState _state;
|
||||
private bool _running;
|
||||
private List<PlayerState> _players;
|
||||
private int _currentPlayer;
|
||||
private bool _initialEvent = true;
|
||||
private int _day;
|
||||
private Weather _weather;
|
||||
private int signCost => 15;
|
||||
private int GlassCost => _day < 5 ? 2 : 4;
|
||||
|
||||
public ScreenManager(Settings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
_animator = new AnimationScreen(settings);
|
||||
_animator.Ok += () =>
|
||||
{
|
||||
_state = GameState.Transaction;
|
||||
_currentPlayer = 0;
|
||||
_initialEvent = true;
|
||||
_transaction.SetUp(_players[_currentPlayer], _settings, _currentPlayer, _day, _weather, signCost, GlassCost);
|
||||
};
|
||||
_transaction = new TransactionScreen(settings);
|
||||
_transaction.Ok += (glasses, price, signs) =>
|
||||
{
|
||||
_initialEvent = true;
|
||||
_players[_currentPlayer].Glasses = glasses;
|
||||
_players[_currentPlayer].GlassPrice = price;
|
||||
_players[_currentPlayer].Signs = signs;
|
||||
_players[_currentPlayer].CalculateIncome(signCost, GlassCost, _weather, settings);
|
||||
_currentPlayer++;
|
||||
if (_currentPlayer >= _players.Count)
|
||||
{
|
||||
_state = GameState.Event;
|
||||
_currentPlayer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_transaction.Tab(true);
|
||||
_transaction.Tab(false);
|
||||
}
|
||||
};
|
||||
_result = new ResultScreen(settings);
|
||||
_result.Ok += () =>
|
||||
{
|
||||
_initialEvent = true;
|
||||
_state = GameState.Setup;
|
||||
};
|
||||
_state = GameState.Setup;
|
||||
_players = new List<PlayerState>();
|
||||
for (int i = 0; i < settings.PlayerCount; i++) _players.Add(new PlayerState(i + 1));
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
_running = true;
|
||||
_state = GameState.Setup;
|
||||
while (_running)
|
||||
{
|
||||
switch (_state)
|
||||
{
|
||||
case GameState.Setup:
|
||||
if (_initialEvent)
|
||||
{
|
||||
_day++;
|
||||
_weather = new Weather();
|
||||
_animator.SetWeather(_weather);
|
||||
_animator.Render();
|
||||
_initialEvent = false;
|
||||
}
|
||||
_animator.ReadInput();
|
||||
Thread.Sleep(100);
|
||||
break;
|
||||
case GameState.Transaction:
|
||||
if (_initialEvent)
|
||||
{
|
||||
_transaction.SetUp(_players[_currentPlayer], _settings, _currentPlayer, _day, _weather, signCost, GlassCost);
|
||||
_transaction.Render();
|
||||
_initialEvent = false;
|
||||
}
|
||||
_transaction.ReadInput();
|
||||
Thread.Sleep(100);
|
||||
break;
|
||||
case GameState.Event:
|
||||
if (_initialEvent)
|
||||
{
|
||||
_result.Setup(_players);
|
||||
_result.Render();
|
||||
_initialEvent = false;
|
||||
}
|
||||
_result.ReadInput();
|
||||
Thread.Sleep(100);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,77 @@
|
|||
$HEADER$namespace $NAMESPACE$
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using CC_Functions.Commandline.TUI;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
public class $CLASS$ {$END$}
|
||||
public class Settings
|
||||
{
|
||||
public bool Color { get; private set; } = true;
|
||||
public int PlayerCount { get; private set; }
|
||||
public float DifficultyFactor { get; private set; }
|
||||
public Settings()
|
||||
{
|
||||
Configure();
|
||||
}
|
||||
|
||||
public void Configure()
|
||||
{
|
||||
CenteredScreen settingsScreen = new CenteredScreen(200, 20, ConsoleColor.Black, Color)
|
||||
{
|
||||
TabPoint = 0,
|
||||
Title = "Lemonade - Settings"
|
||||
#if DEBUG
|
||||
+ "[R to redraw]"
|
||||
#endif
|
||||
};
|
||||
Panel scr = settingsScreen.ContentPanel;
|
||||
scr.ForeColor = ConsoleColor.DarkGray;
|
||||
|
||||
Label playerLabel = new Label("Players");
|
||||
playerLabel.Point = new Point(scr.Size.Width / 2 - playerLabel.Content.Length / 2, 3);
|
||||
scr.Controls.Add(playerLabel);
|
||||
|
||||
Slider playerSlider = new Slider {MinValue = 1, Value = 2, Size = new Size(100, 1)};
|
||||
playerSlider.Point = new Point(scr.Size.Width / 2 - playerSlider.Size.Width / 2, 4);
|
||||
scr.Controls.Add(playerSlider);
|
||||
|
||||
Label difficultyLabel = new Label("Difficulty");
|
||||
difficultyLabel.Point = new Point(scr.Size.Width / 2 - difficultyLabel.Content.Length / 2, 7);
|
||||
scr.Controls.Add(difficultyLabel);
|
||||
|
||||
Slider difficulty = new Slider {Value = 5, Size = new Size(100, 1)};
|
||||
difficulty.Point = new Point(scr.Size.Width / 2 - difficulty.Size.Width / 2, 8);
|
||||
scr.Controls.Add(difficulty);
|
||||
|
||||
CheckBox colorBox = new CheckBox("Color") {Checked = true};
|
||||
colorBox.Point = new Point(scr.Size.Width / 2 - (colorBox.Content.Length + 4) / 2, 12);
|
||||
colorBox.CheckedChanged += (screen, args) =>
|
||||
{
|
||||
settingsScreen.Color = colorBox.Checked;
|
||||
};
|
||||
#if DEBUG
|
||||
settingsScreen.Input += (screen, args) => { if (args.Info.Key == ConsoleKey.R) DiffDraw.Draw(Color, true); };
|
||||
#endif
|
||||
scr.Controls.Add(colorBox);
|
||||
|
||||
Button okButton = new Button("OK");
|
||||
okButton.Point = new Point(scr.Size.Width / 2 - okButton.Content.Length / 2, 16);
|
||||
scr.Controls.Add(okButton);
|
||||
|
||||
bool visible = true;
|
||||
okButton.Click += (screen, args) => visible = false;
|
||||
settingsScreen.Close += (screen, args) => visible = false;
|
||||
|
||||
settingsScreen.Render();
|
||||
while (visible)
|
||||
{
|
||||
settingsScreen.ReadInput();
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
PlayerCount = playerSlider.Value;
|
||||
DifficultyFactor = difficulty.Value / 10f;
|
||||
Color = colorBox.Checked;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,103 @@
|
|||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Drawing;
|
||||
using CC_Functions.Commandline.TUI;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
public class TransactionScreen
|
||||
public class TransactionScreen : CenteredScreen
|
||||
{
|
||||
public event OkDelegate Ok;
|
||||
public delegate void OkDelegate(int glasses, int price, int signs);
|
||||
|
||||
private readonly Label _infoLabel;
|
||||
private readonly Label _glassesLabel;
|
||||
private readonly Slider _glasses;
|
||||
private readonly Label _priceLabel;
|
||||
private readonly Slider _price;
|
||||
private readonly Label _signsLabel;
|
||||
private readonly Slider _signs;
|
||||
private readonly Label _infoLabelBottom;
|
||||
private PlayerState _player;
|
||||
private int _signCost;
|
||||
private int _lemonadeCost;
|
||||
public TransactionScreen(Settings set) : base(200, 20, ConsoleColor.Black, set.Color)
|
||||
{
|
||||
ContentPanel.ForeColor = ConsoleColor.DarkGray;
|
||||
|
||||
_infoLabel = new Label("[DAY 1]");
|
||||
_infoLabel.Point = new Point(ContentPanel.Size.Width / 2 - _infoLabel.Content.Length / 2, 0);
|
||||
ContentPanel.Controls.Add(_infoLabel);
|
||||
|
||||
_glassesLabel = new Label("How many glasses of lemonade do you wish to make?");
|
||||
_glassesLabel.Point = new Point(ContentPanel.Size.Width / 2 - _glassesLabel.Content.Length / 2, 2);
|
||||
ContentPanel.Controls.Add(_glassesLabel);
|
||||
|
||||
_glasses = new Slider {Size = new Size(100, 1)};
|
||||
_glasses.Point = new Point(ContentPanel.Size.Width / 2 - _glasses.Size.Width / 2, 3);
|
||||
_glasses.ValueChanged += (screen, args) => CalculateMax();
|
||||
ContentPanel.Controls.Add(_glasses);
|
||||
|
||||
_priceLabel = new Label("What price (in cents) do you wish to charge for lemonade?");
|
||||
_priceLabel.Point = new Point(ContentPanel.Size.Width / 2 - _priceLabel.Content.Length / 2, 6);
|
||||
ContentPanel.Controls.Add(_priceLabel);
|
||||
|
||||
_price = new Slider {Size = new Size(100, 1)};
|
||||
_price.Point = new Point(ContentPanel.Size.Width / 2 - _price.Size.Width / 2, 7);
|
||||
_price.ValueChanged += (screen, args) => CalculateMax();
|
||||
ContentPanel.Controls.Add(_price);
|
||||
|
||||
_signsLabel = new Label("How many advertising signs do you want to make?");
|
||||
_signsLabel.Point = new Point(ContentPanel.Size.Width / 2 - _signsLabel.Content.Length / 2, 10);
|
||||
ContentPanel.Controls.Add(_signsLabel);
|
||||
|
||||
_signs = new Slider {Size = new Size(100, 1)};
|
||||
_signs.Point = new Point(ContentPanel.Size.Width / 2 - _signs.Size.Width / 2, 11);
|
||||
_signs.ValueChanged += (screen, args) => CalculateMax();
|
||||
ContentPanel.Controls.Add(_signs);
|
||||
|
||||
_infoLabelBottom = new Label("Total Expenses: 0/0");
|
||||
_infoLabelBottom.Point = new Point(ContentPanel.Size.Width / 2 - _infoLabelBottom.Content.Length / 2, 14);
|
||||
ContentPanel.Controls.Add(_infoLabelBottom);
|
||||
|
||||
Button okButton = new Button("OK");
|
||||
okButton.Point = new Point(ContentPanel.Size.Width / 2 - okButton.Size.Width / 2, 16);
|
||||
okButton.Click += (sender, e) => Ok?.Invoke(_glasses.Value, 10, 0);
|
||||
ContentPanel.Controls.Add(okButton);
|
||||
|
||||
Close += (screen, args) => Ok?.Invoke(_glasses.Value, 10, 0);
|
||||
}
|
||||
|
||||
public void SetUp(PlayerState player, Settings settings, int playerIndex, int day, Weather weather, int signCost, int lemonadeCost)
|
||||
{
|
||||
TabPoint = 0;
|
||||
_signCost = signCost;
|
||||
_lemonadeCost = lemonadeCost;
|
||||
Title = $"Lemonade - Player {playerIndex + 1}/{settings.PlayerCount}";
|
||||
_player = player;
|
||||
_glasses.Value = 0;
|
||||
_price.Value = 0;
|
||||
_signs.Value = 0;
|
||||
CalculateMax();
|
||||
_infoLabel.Content = $"It is day {day}, the weather is {weather}";
|
||||
_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.Point = new Point(ContentPanel.Size.Width / 2 - _glassesLabel.Content.Length / 2, 2);
|
||||
_signsLabel.Content = $"How many advertising signs ({signCost}ct each) do you want to make?";
|
||||
_signsLabel.Point = new Point(ContentPanel.Size.Width / 2 - _signsLabel.Content.Length / 2, 10);
|
||||
}
|
||||
|
||||
private void CalculateMax()
|
||||
{
|
||||
int leftover = _player.Budget - CalculateExpenses();
|
||||
_glasses.MaxValue = (int)Math.Floor(leftover / (double)_lemonadeCost) + _glasses.Value;
|
||||
_price.MaxValue = 200;
|
||||
_signs.MaxValue = (int)Math.Floor(leftover / (double)_signCost) + _signs.Value;
|
||||
_infoLabelBottom.Content = $"Leftover: ${leftover / 100f}/${_player.Budget / 100f}";
|
||||
_infoLabelBottom.Point = new Point(ContentPanel.Size.Width / 2 - _infoLabelBottom.Content.Length / 2, 14);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
private int CalculateExpenses() => _lemonadeCost * _glasses.Value + _signCost * _signs.Value;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Lemonade
|
||||
{
|
||||
public class Weather
|
||||
{
|
||||
private static Random rnd = new Random();
|
||||
public override string ToString() => W.ToString().Replace('_', ' ');
|
||||
|
||||
public W W
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Factor < 0.2) return W.Rainy;
|
||||
if (Factor < 0.4) return W.Cloudy;
|
||||
if (Factor < 0.6) return W.Warm;
|
||||
if (Factor < 0.8) return W.Sunny;
|
||||
return W.Hot_and_dry;
|
||||
}
|
||||
}
|
||||
|
||||
public double Factor = rnd.NextDouble();
|
||||
}
|
||||
|
||||
public enum W
|
||||
{
|
||||
Rainy,
|
||||
Cloudy,
|
||||
Warm,
|
||||
Sunny,
|
||||
Hot_and_dry
|
||||
}
|
||||
}
|
Reference in New Issue