I am developing an application for training chess. The idea is to upload a file PGN Portable Game Notation ( no PNG is image format) , which is a file where the data of an item and also the moves are stored.
Each move can have zero , one or more variations . I declare a class to fill the tree and then to follow it.
Then the class that I created :
public class Movida
{
private int numeroMovida;
private string algebraicMove;
private int token;
private string comentario;
private List<Movida> variaciones = new List<Movida>();
public Movida(int numeroMovida, string algebraicMove, int token, string comentario, List<Movida> variaciones) {
this.numeroMovida = numeroMovida;
this.algebraicMove = algebraicMove;
this.token = token;
this.comentario = comentario;
this.variaciones = null;
}
public void agregarMovida(Movida movida) {
variaciones.Add(movida);
}
public List<Movida> obtenerVariaciones() {
return variaciones;
}
}
I think I need to make a function to enter fill the tree recursively , just to get moved back. Any help is appreciated.
Related
I am creating a BlackJack game and I'm currently having a problem displaying the card image needed on my list.
I have added all 52 card to my resource file and I can't seem to have them displayed in a PictureBox.
Am I going about the right way?
My Card class:
internal class Card
{
public int Value { get; set; }
public string Name { get; set; }
public string Image { get; set; }
public Card(int value, string name, string image)
{
Value = value;
Name = name;
Image = image;
}
}
Main Form:
public partial class Form1 : Form
{
static List<Card> myListOfCards = new List<Card>();
static List<Card> dealersHand = new List<Card>();
static List<Card> playersHand = new List<Card>();
private void startButton_Click(object sender, EventArgs e)
{
//Clubs
myListOfCards.Add(new Card(2, "Two of Clubs", "Resources._2C.png"));
}
}
I've spotted a potential issue. Your code uses "Resources._2C.png" as a literal, and the Card class deals with it as a string. One way or another an Image must be retrieved from the resources of the Assembly and I don't see any code that does that.
Try this change:
class Card
{
// METHOD 1
// CTor with Image
public Card(int value, string name, Image image)
{
Value = value;
Name = name;
Image = image;
}
// METHOD 2
// CTor with string
// The `BuildAction` property for the image files must
// be set to `EmbeddedResource` for this version to work.
public Card(int value, string name, string resource)
{
Value = value;
Name = name;
Image = Image.FromStream(
typeof(Card)
.Assembly
.GetManifestResourceStream(resource));
}
public int Value { get; }
public string Name { get; }
// Try making this an Image
public Image Image { get; }
}
In the MainForm:
The image can either be read from the Resource file by removing the quotes and the extension:
// METHOD 1
private void buttonCard1_Click(object sender, EventArgs e)
{
var card = new Card(1, "AceOfDiamonds", Resources.AceOfDiamonds);
pictureBox1.Image = card.Image;
}
OR if the string is used, it must be fully qualified:
// METHOD 2
private void buttonCard2_Click(object sender, EventArgs e)
{
// Get full names of available resources
Debug.WriteLine(
string.Join(
Environment.NewLine,
typeof(MainForm).Assembly.GetManifestResourceNames()));
var card = new Card(2, "EightOfSpades", "resources.Images.EightOfSpades.png");
pictureBox1.Image = card.Image;
}
Gets this in the PictureBox:
FYI: Here are the available embedded resources listed by the Debug.WriteLine:
I'm creating a simple distance calculator. I have a window form with 2 combo boxes. The first combobox has the default place which is the Place1 and the second combobox has the value of Place1,Place2 and Place3.
Here's my code in my class.
public class classDistance
{
public string Places { get; set; }
public int DistanceKm { get; set; }
public static void Hours() {
List<string> Cities = new List<string>();
Cities.Add("Place1");
Cities.Add("Place2");
Cities.Add("Place3");
List<int> DestinationKm = new List<int>();
DestinationKm.Add(10); // Place1 = 10Km
DestinationKm.Add(20); // Place2 = 20Km
DestinationKm.Add(30); // Place3 = 30Km
return;
}
}
//Place1 has the speed of 80kmph.
And when the user click the button in the Form, it will calculate the Hours from the method class classDistance
// Inside my form
public Form1()
{
InitializeComponent();
}
classDistance classname = new classDistance();
private void button1_Click(object sender, EventArgs e)
{
if(comboBox1.Text == "Place1"){
// call the method on the classname if the user click the button and calculate the hours
}
}
How can I do that?
Thank you in advance!
As you made method Hours() static, you can simply call it by the class without creating any instance, like that:
private void button1_Click(object sender, EventArgs e)
{
ClassDistance.Hours();
}
But now your method just fills the lists, not calculates hours actually.
UPD:
I think it's better off using dictionary for storing and getting data in your case:
var citiesDistance = new Dictionary<string, int>
{
{"Place1", 10},
{"Place2", 20},
{"Place3", 30}
};
Then, you can get appropriate value by the place's name, e.g.:
var name = "Place2";
var length = citiesDistance[name];
And after that, you can calculate hours, needed to get to the place:
var speed = 80;
var hours = length/speed;
Hope, I've understood your question correctly)
At the moment you have a list of places and a list of distances which aren't really related to each other.
What I would do is create a new class which contains both the place name and distance, e.g.:
public class Destination
{
public string Name {get;set;}
public int DistanceKm {get;set;}
// ctor
public Destination(String name, int distanceKm)
{
Name = name;
DistanceKm = distanceKm;
}
public int getHours (int speed)
{
// do your calculation for the number of hours here
return hours;
}
}
You can then populate the destination with it's name and distance via the constructor, and use the getHours method to return the number of hours based on the speed you pass into it.
You could also create a List if you were handling multiple destinations
This question already has an answer here:
How do I save an ArrayList to the application settings
(1 answer)
Closed 2 years ago.
I am writing a simple application - a kind of saper game in winforms in C#. My application already saves some information in application settings like the size or colour of buttons , but when i try to save an arraylist of my own structure I get a problem. The are no errors but the information is not saved for the next program execution.Ustawienia is a public static class including wyniki which is another form , and Properties.Settings.Default.scores is an ArrayList added in application settigs. I would be grateful if you have any idea what i am doing wrong and how to store the arraylist in app settings.
Here is the code:
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
if (Properties.Settings.Default.scores == null)
Properties.Settings.Default.scores = new System.Collections.ArrayList();
}
private void ok_click(object sender, EventArgs e)
{
Highscore higscore = new Highscore(Properties.Settings.Default.ktory, textBox1.Text, ustawienia.ile_wierszy, ustawienia.ile_kolumn, ustawienia.elapsed.Seconds);
Properties.Settings.Default.scores.Add( higscore);
Properties.Settings.Default.scores.Sort(new myComparer());
Properties.Settings.Default.ktory++;
Properties.Settings.Default.Save();
Highscore.show();
this.Close();
}
}
public class Highscore
{
public int nubmer;//w properties ktory=+1;
public string name;
int rows;
int columns;
public int time;
public Highscore(int _number, string _name, int _rows, int _columns, int _time)
{
number = _number;
name = _name;
rows = _rows;
columns = _columns;
time = _time;
}
public static void show()
{
ListView list = (ListView)ustawienia.wyniki.Controls.Find("listView1", true)[0];
list.Items.Clear();
foreach (Highscore e in Properties.Settings.Default.scores)
{
ListViewItem newItem = new ListViewItem(new[] { e.name, e.time.ToString(), e.rows.ToString()+"x"+e.columns.ToString() });
lista.Items.Add(newItem);
}
ustawienia.wyniki.Show();
}
}
public class myComparer:IComparer
{
int IComparer.Compare(Object x, Object y)
{
if (((Highscore)x).time < ((Highscore)y).time)
return 1;
else if (((Highscore)x).time > ((Highscore)y).time)
return -1;
else
{
return String.Compare(((Highscore)x).name,((Highscore)y).name);
}
}
}
}
In my experience, it was always a problem with trying to use the default Settings. For example, on Windows 8 the Default settings was saved in this folder pattern:
C:\Users\[username]\AppData\Local\[AssemblyName]\[AssemblyName].exe_Url_[random_string_of_characters]\1.0.0.0\user.config
However, in debug mode it would be .vhost.exe and then when testing locally it would be just .exe. Then if the version increased it would change the path again.
Eventually I gave up on trying to figure out which Settings file was being used, and trying to force it to save to a different (cleaner) folder. Instead, I switched to using a custom settings class and using XmlSerializer. It's not worth the headache.
I am using Visual Studio to create a Windows Forms C# project and am trying to set up an array of a type class, and have the entries in the array correspond to the constructor string for the class. I am using an array with an index of a variable, which increases each time that a new class instance is added to the array.
I am running into the problem of the index call is outside the bounds of the array. Additionally, I am not sure that my class variables are being set for each instance. Can anyone point me in the right direction? Below is my code:
public partial class MainMenu : Form
{
//int that will be used to alter the index of the array
public static int acctcount = 1;
//array of class Account
Account[] accounts = new Account[acctcount];
public MainMenu()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//check through each element of the array
for (int i = 0; i < accounts.Length; i++)
{
string stringToCheck = textBox1.Text;
foreach(Account x in accounts)
{
//check to see if entered name matches any element in the array
if (x.Name == stringToCheck)
{
//set variables in another form so that we are using the class variables for only that class
Variables1.selectedAccount = x.Name;
//is this calling the CheckBalance of the instance?
Variables1.selectedCheckBalance = Account.CheckBalance;
//same thing?
Variables1.selectedSaveBalance = Account.SaveBalance;
//switch to form
AccountMenu acctMenu = new AccountMenu();
this.Hide();
acctMenu.Show();
}
else
{
/*insert new instance of Account
the index element should be 0, since acctcount is set to 1
and we are subtracting 1 from the acctcount
we are using the string from the textbox1.Text as the constructor
for the new instance*/
accounts [acctcount-1] = new Account(stringToCheck);
//increase the index of the array by 1
acctcount += 1;
}
}
}
}
}
class Account
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
private static int acctNum = 0;
public static int AcctNumber
{
get
{
return acctNum;
}
set
{
acctNum = value;
}
}
//initialize the CheckBalance value to 100.00
private static decimal checkBalance = 100.00M;
public static decimal CheckBalance
{
get
{
return checkBalance;
}
set
{
checkBalance = value;
}
}
public Account(string Name)
{
this.Name = Name;
}
private static decimal saveBalance = 100.00M;
public static decimal SaveBalance
{
get
{
return saveBalance;
}
set
{
saveBalance = value;
}
}
}
The problem with the reported exception is [most likely] the line accounts[acctcount-1] as it will throw an IndexOutOfBounds exception when acctcount is >= 2 (eg. accounts[1]), as happens after the first button click and increment of acctcount. The array however, only has one element as it was created with accounts = new Account[acctcount]; - arrays in C# do not grow/resize.
The simplest and best immediate fix is to use a List (see Collections (C#)) instead of an array; Lists can grow dynamically. Then the code becomes:
// (remove the "acctcount" field as it is no longer useful)
List<Account> accounts = new List<Account>();
// ..
accounts.Add(new Account(stringToCheck));
As pointed out by Trevor, remove the static modifier in the Accounts class; otherwise the member data will be incorrectly shared (ie. each account will have the same balances!) and "overwrite" each other. If the use of static is an attempt to "pass back" the data from the form see How to return a value from a Form in C#? for a more viable solution. The same use of a public property can be used to pass an (Account) object into a form.
The exception is thrown when the button is clicked more than once.
You created an array of size 1, the second time you click the button and it tries to add an element at index 2, the index is already out of bounds.
Arrays do not grow in size as you add new items.
As pointed out, you should use a collection, like List<T>
If you wanted to keep using arrays, everytime you add a new item, you need to create a new array of bigger size, copy the elements of the old array to the new array, and reference the old array to the new array. You can also create an array of a bigger size and only create a new array when it's full. Which is basically what the .Net collections already implement.
As always, it all depends on what your needs and requirements are.
this is not long story!! just it seems to be long ;)
in my app I have user access, it means access to a button relate to its user access scope.
in winform layer: I have a form, it shows all of the determined buttons' name in partitioned checkedListboxes. I dont want fill the form manually. I want create checkedListboxes by code. to get their items'text, I have below planing:
clssMenu_Item: I can save name and text property of one button in this class.
public class clssMenu_Item
{
public string name;
public string text;
}
clssMenu_List: it give me 2D generic List<clssMenu_Item>. all of the buttons in one form will be in a object of this class.
public class clssMenu_List
{
public clssMenu_List ()
{
// I dont know how fill private variables
}
#region private variables
private List<clssMenu_Item> _main ; // buttons in main form
private List<clssMenu_Item> _accountancy; //buttons in accountancy form
private List<clssMenu_Item> _management; //buttons in management form
#endregion
#region public properties
public List<clssMenu_Item> main
{ get { return _main; } }
public List<clssMenu_Item> accountancy
{ get { return _accountancy; } }
public List<clssMenu_Item> management
{ get { return _management; } }
#endregion
}
the buttons in each forms have a common character in their Name property. For example all of the determined buttons in Main form are started with ''Mbtn'', so there isn't any same buttons' Name between forms.
now I dont know how fill private variables in clssMenu_List. then I could use it in my facade layer.
thanks for your attention my friend!! please help me to solve it
I would create a separated helper class that extracts all buttons from a form.
public static class FormHelper
{
public static Button[] GetButtonsFromForm(Form form)
{
// ...
}
}
I would create properties instead of fields:
public class clssMenu_Item
{
public string Name {get;set;}
public string Text {get;set;}
}
A method to create menu_items:
public IEnumerable<clssMenu_Item> GetMenuItemsFromForm(Form form)
{
// convert the buttons to menu_items
return from button in FormHelper.GetButtonsFromForm(form);
select new clssMenu_Item { Name = button.Name, Text = button.Text };
}
Next I would add all buttons to the right list.
public void Fill()
{
clssMenu_List lst = new clssMenu_List();
clssMenu_List.main.AddRange(GetMenuItemsFromForm(mainForm));
clssMenu_List.accountancy.AddRange(GetMenuItemsFromForm(accountancyForm));
clssMenu_List.management.AddRange(GetMenuItemsFromForm(managementForm));
}
Don't forget to create the list in you class:
private List<clssMenu_Item> _main = new List<classMenu_Item>(); // buttons in main form
private List<clssMenu_Item> _accountancy = new List<classMenu_Item>(); //buttons in accountancy form
private List<clssMenu_Item> _management = new List<classMenu_Item>(); //buttons in management form
Personally:
I would store them in a dictionary because you can access them by name. And I would not create properties of List-types. I'd rather create Add/Remove methods.