18. august 2009 - 21:22Der er
30 kommentarer og 1 løsning
Kode fejler
Hej
Er meget ny i C# og objektorienteret udvikling generelt! Kan nogle hjælpe mig med hvad der går galt?
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Yatzy { // DiceCup class // Represents DiceCup containing five dices // Methods: // Throw: Throws dices (whics are not hold) // GetDice(): Returns value of dice X // SetHold (DiceNo): SetsHold on dice number X // SetHoldToAll (): Sets all dices on hold // UnsetHold (DiceNo): UnHold dice number X // UnsetHoldAll (): No dices are on hold // Properties: // arrDices: Two dimensional array containg dice(s) and // hold value for each dice (0 = hold, 1 = throw) // Default is hold value set to 1 (throw)
class DiceCup { public Dice[] arrDices; public int NumberOfDices;
// Constructor: create x dices public DiceCup(int NumberOfDicesAA) { NumberOfDices = NumberOfDicesAA; Console.Write("NumberOfDices {0}",NumberOfDices);
arrDices = new Dice[NumberOfDices]; Console.Write("arrDices {0}", arrDices.Length); }
// Throws dices in cup public void ThrowDices() { for (int ArrLoop = 0; ArrLoop < NumberOfDices; ArrLoop++) { //arrDices[ArrLoop].SetHoldOnDic; arrDices[ArrLoop].ThrowDice(); } }
// Returns values of each dice in aray, starting from Dice1 public int[] GetDices() { int[] DicesInCup = new int[NumberOfDices]; for (int ArrLoop = 1; ArrLoop < NumberOfDices; ArrLoop++) //foreach (ArrLoop in arrDices) { Console.Write("ArrLoop {0}", ArrLoop); //DicesInCup[ArrLoop] = arrDices[ArrLoop].GetDice(); Console.Write(arrDices[ArrLoop].GetDice()); Console.ReadLine(); } return DicesInCup; }
// Hold all dices public void SetHoldToAll() { for (int ArrLoop = 0; ArrLoop < NumberOfDices; ArrLoop++) { //arrDices[ArrLoop].SetHoldOnDic; arrDices[ArrLoop].SetHoldOnDice(); } }
// UnsetHold on all dices public void UnSetHoldToAll() { for (int ArrLoop = 0; ArrLoop < NumberOfDices; ArrLoop++) { arrDices[ArrLoop].UnSetHoldOnDice(); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Yatzy { // Dice class // Represents one Dice // Methods: // ThrowDice: Assign random value between 1 - 6 to dice // GetDice: Returns value of current dice // Properties: // DiceValue Value af Dice // HoldDice True - dice cannot by thorn class Dice { private int DiceValue = 1; // Value of dice private bool HoldDice = false; // Set if dice can be thrown
public Dice() { this.ThrowDice(); }
public void ThrowDice() { Random random = new Random(); this.DiceValue = (random.Next(1, 6)); }
public int GetDice() { return (DiceValue); }
bool GetHoldStatus() { return this.HoldDice; }
public void SetHoldOnDice() { this.HoldDice = true; }
public void UnSetHoldOnDice() { this.HoldDice = false; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Yatzy { // DiceCup class // Represents DiceCup containing five dices // Methods: // Throw: Throws dices (whics are not hold) // GetDice(): Returns value of dice X // SetHold (DiceNo): SetsHold on dice number X // SetHoldToAll (): Sets all dices on hold // UnsetHold (DiceNo): UnHold dice number X // UnsetHoldAll (): No dices are on hold // Properties: // arrDices: Two dimensional array containg dice(s) and // hold value for each dice (0 = hold, 1 = throw) // Default is hold value set to 1 (throw)
class DiceCup { public Dice[] arrDices; public int NumberOfDices;
// Constructor: create x dices public DiceCup(int NumberOfDicesAA) { NumberOfDices = NumberOfDicesAA; Console.Write("NumberOfDices {0}",NumberOfDices);
arrDices = new Dice[NumberOfDices]; Console.Write("arrDices {0}", arrDices.Length); }
// Throws dices in cup public void ThrowDices() { for (int ArrLoop = 0; ArrLoop < NumberOfDices; ArrLoop++) { //arrDices[ArrLoop].SetHoldOnDic; arrDices[ArrLoop].ThrowDice(); } }
// Returns values of each dice in aray, starting from Dice1 public int[] GetDices() { int[] DicesInCup = new int[NumberOfDices]; for (int ArrLoop = 1; ArrLoop < NumberOfDices; ArrLoop++) //foreach (ArrLoop in arrDices) { Console.Write("ArrLoop {0}", ArrLoop); //DicesInCup[ArrLoop] = arrDices[ArrLoop].GetDice(); Console.Write(arrDices[ArrLoop].GetDice()); Console.ReadLine(); } return DicesInCup; }
// Hold all dices public void SetHoldToAll() { for (int ArrLoop = 0; ArrLoop < NumberOfDices; ArrLoop++) { //arrDices[ArrLoop].SetHoldOnDic; arrDices[ArrLoop].SetHoldOnDice(); } }
// UnsetHold on all dices public void UnSetHoldToAll() { for (int ArrLoop = 0; ArrLoop < NumberOfDices; ArrLoop++) { arrDices[ArrLoop].UnSetHoldOnDice(); } } } }
Det koster memory og performance at oprette et Random() objekt for hver Dice instans. Derfor bør du definere den som statisk, hvilket gør at der kun er een for hele dit program.
private static Random random = new Random();
Det er både hurtigere, og giver mindre RAM forbrug.
windcape: Som svar til din første kommentar ... selvf skal han tro vi er guder ... man skal have høje tanker om sig selv ... :-) og tro at man kan alt ... det kan man så senere finde ud af at man måske ikke kan :-)
Det er måske lige i overkanten at påstå at han koder helt forkert, fordi han ikke bruger ret mange properties.... Der er godt nok mange mennesker der mener at alt skal laves med properties, men jeg kan finde mange argumenter imod at bruge properties.
> Det er måske lige i overkanten at påstå at han koder helt forkert
At skrive getters/setters når C# har specifik syntaks til det, er ihvertfald "forkert". Der er defacto code-conventions osv. og da det ikke er Java vi koder i, bør vi benytter properties.
Pointen er bare at jeg kunne have besvaret spørgsmålet uden at skulle kompilere det selv, hvis han havde skrevet at han fik en InstanceNotFoundException på 'arrDices[ArrLoop].ThrowDice();' linjen.
Korrekt ... det kunne være bedre stillet hans sprøgsmål ...
Men i stedet for at skrive han koder helt forkert er min eneste pointe at du kunne kommentere at han nok burde læse om på Properties :-)
Nej, det er ikke din afdeling at være venlig venlig her... men måske vi kunne have en indflydelse på det.
og ja ... jeg er godt klar over din pointe ... fuldt forståeligt, men jeg må antage at du alligevel ikke har haft andet at give dig til siden du alligevel compiler det hele selv :-)
Men udover de første 2 posts ... så er resten jo ikke mindre end genialt for sprøger ... stor ros herfra :-)
Det er aldeles ligegyldigt for memory og CPU forbrug at man instantierer en instans af Random for hver Dice.
Det er en katastrofe for funktionaliteten at have en instans af Random for hver Dice. Man er næsten sikker på at få 5 ens. Og det er jo næppe hensigten.
Du sætter int = Dice i eksempel B. I tilfælde at det skulle have været dens Value, så er forskellen vel at du kun returnere værdierne af terningerne, som måske kan være en god ting.
Kan dog ikke fange pointen?
> Resultatet afhænger af hvornår du opretter Random objektet.
Jeg testede koden, og det giver nu stadigvæk forskellige værdier på terningerne.
Pointen er at ved at returnere en referance til den interne liste, saa bryder man delvist encapsulation. Kode udenfor DiceCup kan nemlig aendre i listen. Den originale kode (hvis den blev tilrettet til at virke) returnerede en kopi af data og havde derfor ikke dette ptoblem.
Med hensyn til Random - hvad giver foelgende hos dig:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading;
namespace Yatzy { class Program { static void Main(string[] args) { for(int i = 0; i < 5; i++) { DiceCup1 MyCup1 = new DiceCup1(5); Console.Write("Multi Random 1: "); foreach(Dice1 d in MyCup1.Dices) { Console.Write(" " + d.Value); } Console.WriteLine(); DiceCup2 MyCup2 = new DiceCup2(5); Console.Write("Multi Random 2: "); foreach(Dice2 d in MyCup2.Dices) { Console.Write(" " + d.Value); } Console.WriteLine(); DiceCup3 MyCup3 = new DiceCup3(5); Console.Write("Single Random : "); foreach(Dice3 d in MyCup3.Dices) { Console.Write(" " + d.Value); } Console.WriteLine(); Thread.Sleep(100); } Console.ReadLine(); } } class Dice1 { private int _value; public Dice1() { ThrowDice(); } public void ThrowDice() { Random random = new Random(); _value = random.Next(1, 6); } public int Value { get { return _value; } } } class DiceCup1 { private List<Dice1> _dices = new List<Dice1>(); public List<Dice1> Dices { get { return _dices; } }
public DiceCup1(int dices) { for(int i=0;i<dices;i++) { _dices.Add(new Dice1()); } } } class Dice2 { private Random random = new Random(); private int _value; public Dice2() { ThrowDice(); } public void ThrowDice() { _value = random.Next(1, 6); } public int Value { get { return _value; } } } class DiceCup2 { private List<Dice2> _dices = new List<Dice2>(); public List<Dice2> Dices { get { return _dices; } }
public DiceCup2(int dices) { for(int i=0;i<dices;i++) { _dices.Add(new Dice2()); } } } class Dice3 { private static Random random = new Random(); private int _value; public Dice3() { ThrowDice(); } public void ThrowDice() { _value = random.Next(1, 6); } public int Value { get { return _value; } } } class DiceCup3 { private List<Dice3> _dices = new List<Dice3>(); public List<Dice3> Dices { get { return _dices; } }
Ioevrigt er der i sig selv noget godt ved at returnere IList<> fremfor List<>, da det giver lidt frihed til at skifte implementation.
Det er traditionelt ikke en synsvinkel som man prioriterer i C# verdenen. Men I Java verdenen ville du faa bank for at lade en metode returnere ArrayList<> fremfor List<>.
Hej Alle Tak for de mange kommentarer og forslag til hvor jeg kan hente viden! Super. Vedr. min manglende beskrivelse af fejl - jeg fik ikke nogen descideret fejlmeddelelse! Fejlen opstod ved program afvikling, og der kom ikke noget fornuftigt. Men ja - jeg kunne godt have beskrevet det lidt bedre, det vil ske næste gang.
Endnu en gang tak til alle for deltagelsen i mit problem :-)
> Vedr. min manglende beskrivelse af fejl - jeg fik ikke nogen > descideret fejlmeddelelse! Fejlen opstod ved program afvikling
Oh, du havde ikke kompileret som debug? Min debugger i Visual Studio fortalte mig helst præcist hvad fejlen var, og hvor den var, ligeså snart jeg kørte programmet.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.