C# for students book exercise 10.2 (Book by Douglas Bell) - c#

I am reading this book to self teach myself C#. However, I ran across a problem that I just can't figure out a way to tackle.
The question asks me:
Write a piece of program that remembers the value and compares them as a class. This class has a method NewValue and properties LowestValue and HighestValue.
I understand the question but it asks me to use a track bar which I can't seem to understand how can i store the minimum/maximum value that was previously selected on the trackbar.
My class looks like this:
class AmplifierDisplay
{
private int Low, High;
public AmplifierDisplay()
{
Low = 0;
High = 0;
}
public void NewValue()
{
Low = Math.Min(Low, High);
High = Math.Max(Low, High);
}
public int LowestValue
{
get
{
return Low;
}
set
{
Low = value;
}
}
public int HighestValue
{
get
{
return High;
}
set
{
High = value;
}
}
}

It sounds like you'll need two things:
1) A Comparer implementation to work out the difference between two measurements
2) A Memento pattern implementation to provide a history of the values
Upon each move event, store a memento in some kind of structure such as a List or a Queue. This "NewValue" class looks like a basis for the Memento anyway.
See Comparer and Memento

I found the answer!!! :D
Here is the class code:
class AmplifierDisplay
{
private int Low, High;
public AmplifierDisplay()
{
Low = 0;
High = 0;
}
public void NewValue(int newValue)
{
Low = Math.Min(Low, newValue);
High = Math.Max(High, newValue);
}
public int LowestValue
{
get
{
return Low;
}
set
{
Low = value;
}
}
public int HighestValue
{
get
{
return High;
}
set
{
High = value;
}
}
}
This is the code in the main program:
AmplifierDisplay amplify = new AmplifierDisplay();
private int newValue;
public Chapter10Ex2()
{
InitializeComponent();
amplify.HighestValue = 0;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
newValue = trackBar1.Value;
}
private void MouseUp(object sender, MouseEventArgs e)
{
amplify.NewValue(newValue);
lblMinMax.Text = amplify.LowestValue.ToString() + " , " + amplify.HighestValue.ToString();
}

Related

CS1503 Argument 1: cannot convert from 'Poc.Core.Player' to 'Poc.Interfaces.IScheduleable'

sorry im newish to programming so this may be an easy solvable problem that im not knowledgeable enough to know how to fix
Im using this tutorial for a simple dungeon crawler https://bitbucket.org/FaronBracy/roguesharpv3tutorial/src/master/
when it came to implementing the behaviors of the kobolds (mutants in my project) i would get an error saying 'Argument 1: cannot convert from 'Poc.Core.(Player/monster)" to "Poc.Interface.ISchedule"
this was happening on the addplayer void, addmonster void, and removemonster void in the DungeonMap.cs and twice on the ActivateMonsters void in CommandSystem.cs
i would appreciate it so much if someone could help me fix this problem
problem voids:
public void AddPlayer(Player player)
{
Game.Player = player;
SetIsWalkable(player.X, player.Y, false);
UpdatePlayerFieldOfView();
**Game.SchedulingSystem.Add(player);**
}
public void AddMonster(Monster monster)
{
_monsters.Add(monster);
// After adding the monster to the map make sure to make the
cell not walkable
SetIsWalkable(monster.X, monster.Y, false);
**Game.SchedulingSystem.Add( monster );**
}
public void RemoveMonster(Monster monster)
{
_monsters.Remove(monster);
SetIsWalkable(monster.X, monster.Y, true);
**SchedulingSystem.Remove(monster);**
}
public void ActivateMonsters()
{
IScheduleable scheduleable = Game.SchedulingSystem.Get();
if (scheduleable is Player)
{
IsPlayerTurn = true;
**Game.SchedulingSystem.Add(Game.Player);**
}
else
{
Monster monster = scheduleable as Monster;
if (monster != null)
{
monster.PerformAction(this);
**Game.SchedulingSystem.Add(monster);**
}
ActivateMonsters();
}
}
then my Scheduling System code
namespace Poc.Systems
{
public class SchedulingSystem
{
private int _time;
private readonly SortedDictionary<int, List<IScheduleable>> _scheduleables;
public SchedulingSystem()
{
_time = 0;
_scheduleables = new SortedDictionary<int, List<IScheduleable>>();
}
public void Add(IScheduleable scheduleable)
{
int key = _time + scheduleable.Time;
if (!_scheduleables.ContainsKey(key))
{
_scheduleables.Add(key, new List<IScheduleable>());
}
_scheduleables[key].Add(scheduleable);
}
public void Remove(IScheduleable scheduleable)
{
KeyValuePair<int, List<IScheduleable>> scheduleableListFound
= new KeyValuePair<int, List<IScheduleable>>(-1, null);
foreach (var scheduleablesList in _scheduleables)
{
if (scheduleablesList.Value.Contains(scheduleable))
{
scheduleableListFound = scheduleablesList;
break;
}
}
if (scheduleableListFound.Value != null)
{
scheduleableListFound.Value.Remove(scheduleable);
if (scheduleableListFound.Value.Count <= 0)
{
_scheduleables.Remove(scheduleableListFound.Key);
}
}
}
public IScheduleable Get()
{
var firstScheduleableGroup = _scheduleables.First();
var firstScheduleable = firstScheduleableGroup.Value.First();
Remove(firstScheduleable);
_time = firstScheduleableGroup.Key;
return firstScheduleable;
}
// Get the current time (turn) for the schedule
public int GetTime()
{
return _time;
}
{
_time = 0;
_scheduleables.Clear();
}
}
}
Make sure that your Actor class, which Player and Monster inherit from, is implementing IScheduleable:
public class Actor : IActor, IDrawable, IScheduleable
{
// ... Previous Actor code omitted
// IScheduleable
public int Time
{
get
{
return Speed;
}
}
}

Bubbling events from child to parent (overal progress)

I have a problem which i don't know how to solve.
I have some classes (Processors) that fires an event with progress information ( Percentage of how far it is). There are multiple processors that do this and the top Processor (Engine) which calls them all needs to send information to the end user on its progress.
If i don't know beforehand how many items will be processed by each processor how can i give the user some good feedback on how far the process is?
Take a look at the following simplified example
NetFiddle
class Program {
static void Main(string[] args) {
var p = new Program();
p.Run();
}
private void Run() {
var engine = new Engine();
engine.UpdateProgress += Engine_UpdateProgress;
engine.Process();
Console.ReadLine();
}
private void Engine_UpdateProgress(object sender, UpdateProgressEventArgs e) {
Console.WriteLine($"{e.UpdateDateTime} - Caller: {e.Caller}, Percentage: {e.Percentage}");
}
}
public class Engine {
private readonly ProcessorA _processorA;
private readonly ProcessorB _processorB;
private readonly ProcessorC _processorC;
private readonly ProcessorD _processorD;
public event EventHandler<UpdateProgressEventArgs> UpdateProgress;
public Engine() {
_processorA = new ProcessorA();
_processorB = new ProcessorB();
_processorC = new ProcessorC();
_processorD = new ProcessorD();
//Handle events
_processorA.UpdateProgress += ProcessorA_UpdateProgress;
_processorB.UpdateProgress += ProcessorA_UpdateProgress;
_processorC.UpdateProgress += ProcessorA_UpdateProgress;
_processorD.UpdateProgress += ProcessorA_UpdateProgress;
}
private void ProcessorA_UpdateProgress(object sender, UpdateProgressEventArgs e) {
OnUpdateProgress(e);
}
public void Process() {
_processorA.Process();
_processorB.Process();
_processorC.Process();
_processorD.Process();
}
protected virtual void OnUpdateProgress(UpdateProgressEventArgs e) {
UpdateProgress?.Invoke(this, e);
}
}
public class ProcessorA : Processor {
private readonly ProcessorA_A _processorA_A;
public ProcessorA() {
_processorA_A = new ProcessorA_A();
//Handle events
_processorA_A.UpdateProgress += ProcessorA_A_UpdateProgress;
}
public void Process() {
_processorA_A.Process();
}
private void ProcessorA_A_UpdateProgress(object sender, UpdateProgressEventArgs e) {
OnUpdateProgress(e);
}
}
public class ProcessorB : Processor {
public void Process() {
for (int i = 0; i <= 100; i++) {
var args = new UpdateProgressEventArgs() { Caller = nameof(ProcessorB), Percentage = i, UpdateDateTime = DateTime.Now};
//Do some work
Thread.Sleep(r.Next(50,250));
OnUpdateProgress(args);
}
}
}
public class ProcessorC : Processor {
public void Process() {
for (int i = 0; i <= 100; i++) {
var args = new UpdateProgressEventArgs() { Caller = nameof(ProcessorC), Percentage = i, UpdateDateTime = DateTime.Now };
//Do some work
Thread.Sleep(r.Next(50, 250));
OnUpdateProgress(args);
}
}
}
public class ProcessorD : Processor {
public void Process() {
for (int i = 0; i <= 100; i++) {
var args = new UpdateProgressEventArgs() { Caller = nameof(ProcessorD), Percentage = i, UpdateDateTime = DateTime.Now };
//Do some work
Thread.Sleep(r.Next(50, 250));
OnUpdateProgress(args);
}
}
}
public class ProcessorA_A : Processor {
public void Process() {
for (int i = 0; i <= 100; i++) {
var args = new UpdateProgressEventArgs() { Caller = nameof(ProcessorA_A), Percentage = i, UpdateDateTime = DateTime.Now };
//Do some work
Thread.Sleep(r.Next(50, 250));
OnUpdateProgress(args);
}
}
}
public class Processor : IProcessor {
protected Random r = new Random();
public event EventHandler<UpdateProgressEventArgs> UpdateProgress;
protected virtual void OnUpdateProgress(UpdateProgressEventArgs e) {
UpdateProgress?.Invoke(this, e);
}
}
public interface IProcessor {
event EventHandler<UpdateProgressEventArgs> UpdateProgress;
}
public class UpdateProgressEventArgs {
public int Percentage { get; set; }
public string Caller { get; set; }
public DateTime UpdateDateTime { get; set; }
}
Just sending the progress from child to parent won't do the trick obviously. I hope someone can help me find a solution for this. Or if someone has another brilliant solution :)
Thanks in advance
Engine could maintain a private list of "the last completeness" of each process. In a Dictionary more than likely.
if we extend your Engine class to have this.
private Dictionary<IProcessor, int> _lastReportedPercentage = new Dictionary<IProcessor, int>();
and in the constructor where all your child processors are defined, set them all to 0.
public Engine()
{
//your other stuff
_lastReportedPercentage[_processorA] = 0;
_lastReportedPercentage[_processorB] = 0;
_lastReportedPercentage[_processorC] = 0;
_lastReportedPercentage[_processorD] = 0;
}
in your Event handler for the child processes do something like this:
private void ProcessorA_UpdateProgress(object sender, UpdateProgressEventArgs e)
{
_lastReportedPercentage[(IProcessor)sender] = e.Percentage;
var totalCompleteness = (int)Math.Floor(_lastReportedPercentage.Values.Sum() / _lastReportedPercentages.Values.Count);
OnUpdateProgress(new UpdateProgressEventArgs() { Caller = nameof(Engine), Percentage = totalCompleteness, UpdateDateTime = DateTime.Now });
}
You will then be reporting, from your Engine, the total completeness of all tasks.
There are some obvious design flaws to this, but you get the idea. It can be extended for a variable number of Processors if they're loaded from not-the-constructor, etc. but this should give you the desired output you'd want.
I would suggest having each processor keep a count of how many items it has completed, and how many items it has remaining.
This way the engine receives updates whenever an item is completed, as well as when an item is added to the processor.
As in Skintkingle's answer, you would then store the last received update from each processor within the engine.
You can then let the engine decide on the best way to put this information across. Something as simple as total completed / total remaining would work well.

Using property setting to make additions and retrieval

In my program, I am making currency addition from a for...loop. It is working fine. But I am not sure if what has been done is correct and in accordance with C#.
class Program {
private double _amount;
public double amount {
get {
return _amount;
}
set {
_amount = value;
}
}
static void Main(string[] args) {
Program p = new Program();
for (int i = 1000; i < 1300; i++) {
double y = 30.00;
double x = y + p._amount;
p._amount = x;
}
Console.WriteLine(p._amount.ToString());
Console.ReadLine();
}
}
I have reduced the size of the code. In effect, however, there are several if clauses within the for...loop which I do the calculations.
I would like to thank anyone who could point out any inconsistency with C# coding principles.
The first thing is to use meaningful names, so program could be given a more
meaningful name.
Modularise your code (create a separate class from your program) and use the recommended coding practices by MSDN for C#.
class Calculation
{
public double Amount { get; set; }
public double run(double y)
{
// No need to start at 1000.
for(int i = 0; i < 300; i++)
{
Amount += y;
}
return Amount;
}
}
class Program
{
static void Main(string[] args)
{
Calculation calculation = new Calculation();
// pass your variable as a parameter into a class function.
var y = 30.0;
Console.WriteLine(calculation.run(y).ToString());
// Console.ReadLine(); use control F5 to prevent console window from closing.
}
}
C# Coding Conventions (C# Programming Guide)
I would recommend changing this code:
public double amount
{
get
{
return _amount;
}
set
{
_amount = value;
}
}
with this:
public double getamount()
{
return _amount;
}
public void setamount(int value)
{
_amount = value;
}

C# is it possible to store like classes into a collection?

Tried to title my post as best I could, but here goes.
I have 5 classes for various "effect" animation stuff that can be done to an animation (alpha change, color change, position change, rotation change, scale change). They are all the same aside from variable types. They all use an abstract class for methods that could be shared between them all along with methods that are override in the derived classes.
I have a class that is for handling all the animations of a game object called AnimationHandler. What it does is store all the effect animations (along with the sprite animations) for my game's objects and handling them.
What I want to do is store all the effects into one dictionary that is then used to handle all changes to an animation for that object. I was wondering if it was possible to do or if it would be just easier to have 5 separate dictionaries to handle each effect separately?
The issue that I'm trying to figure out is how to access the variables that aren't in the abstract class.
Here is the sample code for my base class and a derived class:
abstract class EffectAnimation
{
protected EffectInfo Info;
public EffectInfo info
{
get
{ return Info; }
}
protected EffectType TypeOfEffect;
public EffectType typeofeffect
{
get
{ return TypeOfEffect; }
}
public abstract void NewAnimation();
public void Update(double time)
{
AnimationDone(time);
if (!info.Done)
{
if (UtilityAnimation.ReadyForNextFrame(time, Info.FrameLength))
{
Info.NextFrameTime = time + Info.FrameLength;
ChangeValue();
}
}
}
public void Start(double time)
{
Info.StartTime = time;
Info.NextFrameTime = time + Info.FrameLength;
}
public abstract void ChangeValue();
public abstract void Clamp();
protected abstract void AnimationDone(double time);
}
class AlphaAnimation : EffectAnimation
{
private float Change;
public float change
{
get
{ return Change; }
set
{ Change = value; }
}
private float End;
public float end
{
get
{ return End; }
set
{ End = value; }
}
private float Total;
public float total
{
get
{ return Total; }
set
{ Total = value; }
}
public void NewAnimation(EffectInfo stuff, float starting, float ending, float partialtotal)
{
Total = starting + partialtotal;
Info = stuff;
End = ending;
Info.Initialize();
Change = UtilityAnimation.MakeFadeAmount(stuff.AnimationLength, starting, ending, stuff.FPS);
}
public void ChangeValue()
{ Total += Change; }
private void Clamp()
{
if (Change > 0) // animation is positive
{
if (Total > End)
{
Total = End;
}
}
else // animation is negative
{
if (Total < End)
{
Total = End;
}
}
}
private void AnimationDone(double time)
{
Clamp();
if ((Total == End) && (time >= Info.DoneTime()))
{ Info.Done = true; }
}
}
What you ask for (accessing for instance change of AlphaAnimation via a reference of type EffectAnimation) is impossible without reflection or checking for the actual type. That being said, if possible, the design should be changed such that the desired effect of the animation can be triggered without knowing its type. This can be difficult depending on the case; in some cases it might make no sense altogether.
This is a possible solution;
List<EffectAnimation> animations = new List<EffectAnimation>();
animations.Add(new AlphaAnimation());
EffectAnimation item = animations[0];
if(item is AlphaAnimation)
{
AlphaAnimation alphaItem = item as AlphaAnimation;
float total = alphaItem.Total;
float change = alphaItem.Change;
}
This is basically just casting it to the right class and then you can easily access the properties you need. You can still add all your animations to the same list - just make sure to check if it is the right one when you take one out.

Get an object out of a mixed type collection

Hi I'm new to OOP and I need help on a little problem.
I used a collection called Monsters to store 3 types of object. Spiders, Farmers, Gollum(irrelevant).
My collection as an indexer but when I use it to get an object out of the collection the object is typeless but I really need to TypeCast my next opperation.
private void Form1_Load(object sender, EventArgs e)
{
CurrentOpponent Opponent = new CurrentOpponent();
Gollum myGollum = new Gollum();
AngryFarmer myFarmer = new AngryFarmer();
Ugly_Spider mySpider = new Ugly_Spider();
myMonsters.AddGollum(myGollum);
myMonsters.AddFarmer(myFarmer);
myMonsters.AddUgly(mySpider);
progressBar1.Increment(100);
progressBar2.Increment(100);
Monster myCurrentOpponent = Opponent.randomEncounter();
//textBox1.Text = (this is where i need the type for a cast)myCurrentOpponent.name
}
Here is the randomEncounter where i extract the object
class CurrentOpponent
{
public Monster randomEncounter()
{
Random _random = new Random();
int opp = _random.Next(4);
return myMonsters[opp];
}
And finally the indexer wich returns a monster (parent of all 3 monster types)
public Monster this[int xxx]
{
get
{
return (Monster)List[xxx];
}
}
Help would be really appreciated..!!
Thanks in advance
Ideally, AngryFarmer, Ugly_Spider and Gollum should all inherit from Monster:
public class AngryFarmer : Monster
{
// ...
}
// etc.
You could then just use a List<Monster>:
myMonsters = new List<Monster>();
myMonsters.Add(new AngryFarmer()); // works because AngryFarmer is a kind of Monster
This will allow you to use polymorphism.
you need to use interfaces...... IMonster..... IMonster then has a name
then make all your monsters implement IMonster
and just have a List of IMonsters
you may wanna try it by using interfaces also! have a look...
public interface IMonster
{
String Name { get; }
Int32 Health { get; set; }
}
public class Spider : IMonster
{
public Spider()
{
_health = 100;
}
public string Name
{
get { return "Spider"; }
}
private int _health;
public int Health
{
get { return _health; }
set { _health = value; }
}
}
public class Gollum : IMonster
{
public Gollum()
{
_health = 250;
}
public string Name
{
get { return "Gollum"; }
}
private int _health;
public int Health
{
get { return _health; }
set { _health = value; }
}
}
class Program
{
static void Main(string[] args)
{
List<IMonster> monsters = new List<IMonster>()
{
new Gollum(),
new Spider()
};
IMonster randomMonster = GetRandomMonster(monsters);
Console.WriteLine(randomMonster.Name + "/" + randomMonster.Health);
}
private static IMonster GetRandomMonster(List<IMonster> monsters)
{
//Your code for getting a random monster goes here!
throw new NotImplementedException();
}
}
I like very much this approach... Imagine you have an element on your game that initially is not exactly a monster. Say it is a random element on your game that after a given event it becomes a monster that your Hero (say a game like heroes of mighty and magic) have to fight with. If you decided to add this feature long time after you created the game, it would become harmful/difficult/risky to change it, as this element might have already be inheriting from another class. If you were using interfaces you would simply implement it on this entity and it would promptly be capable of behaving like any other IMonster in your game. It means that this random entity would be able to be passed as a param to the method Fight(IHero hero, IMonster monster);
Ideally, AngryFarmer, Ugly_Spider and Gollum should all inherit
from Monster
I have learn your problem like the problem in the Tetris game:
1/ You have Monsters like I have Shapes.
2/ Each kind of Monster have it own properties (Health, Magic Point,...) and behaviours (attack, run, cast spell,..) like the Blocks have properties (color, position, state,..) and
behaviours (go down, rotate right, rotate left,...)
In the scene of the game you want to random a Monster that have the specific properties and behaviours, like I want to random a Shape. If it is your problem you can try my code:
public abstract class CMonster
{
int _HP;
int _MP;
//..and something like this
public int HP
{
get { return this._HP; }
set { this._HP=value;}
}
public int MP
{
get { return this._MP; }
set { this._MP = value; }
}
public abstract void Run();
public abstract void Attach();
public abstract void CastSpell();
}
public class CUgly_Spider : CMonster
{
public CUgly_Spider()
{
this.MP = 100;//your value here
this.HP = 100;//your value here
}
public override void Attach()
{
//your implemetation here
}
public override void Run()
{
//your implemetation here
}
public override void CastSpell()
{
//your implemetation here
}
}
public class CGollum : CMonster
{
public CGollum()
{
this.MP = 100;//your value here
this.HP = 100;//your value here
}
public override void Attach()
{
//your implemetation here
}
public override void Run()
{
//your implemetation here
}
public override void CastSpell()
{
//your implemetation here
}
}
class Test
{
private void InitTheGame()
{
CMonster curMonster=null;
Random rnd = new Random();
//sample random
if ((rnd.Next() % 2) == 0)
{
curMonster = new CGollum();
}
else
{
curMonster = new CUgly_Spider();
}
curMonster.Run();//when (rnd.Next() % 2) == 0 then the Gollum is doing else the Ugly_Spider
curMonster.Attach();//when (rnd.Next() % 2) == 0 then the Gollum is doing else the Ugly_Spider
curMonster.CastSpell();//when (rnd.Next() % 2) == 0 then the Gollum is doing else the Ugly_Spider
}
}
I hope that can help you.

Categories

Resources