How can I create a list with a fixed set of entries.
Learning C# and doing an exercise to list all cards in a deck of cards(without jokers). Going to use two foreach loops to print them out.
However I cannot get a default list of the cards(I am overloading the method). Looking at the docs http://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx and some examples http://www.dotnetperls.com/list and each element is added in individually.
// from dotnet perls
class Program
{
static void Main()
{
List<string> dogs = new List<string>(); // Example List
dogs.Add("spaniel"); // Contains: spaniel
dogs.Add("beagle"); // Contains: spaniel, beagle
dogs.Insert(1, "dalmatian"); // Contains: spaniel, dalmatian, beagle
foreach (string dog in dogs) // Display for verification
{
Console.WriteLine(dog);
}
}
}
I have tried both the Add and Insert methods but cannot create my lists.
// my code
using System;
using System.Collections.Generic;
using System.Linq;
class Deck
{
static void Main()
{
List<string> deck = new List<string>();
deck.Insert("Ace", 2, 3, 4, 5, 6, 7, 8, 9, 10, "Jack", "Queen", "King");
List<string> colour = new List<string>();
colour.Add("Hearts", "Diamonds", "Spades", "Clubs");
foreach (string card in deck)
{
foreach(string suit in colour)
{
Console.Write(colour + " " + card);
}
}
}
}
List.Add or List.Insert doesn't take variable length parameters. You may need to use List.AddRange method.
List<string> deck = new List<string>();
deck.AddRange(new []{"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"});
List<string> colour = new List<string>();
colour.AddRange(new []{"Hearts", "Diamonds", "Spades", "Clubs"});
Also note that I've converted the numerical parameters to string as the list is List<string>, otherwise it won't compile.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm making a program to automate rolling initiative. I have most of it done, but I can't sort the outputs because it's a jagged array. I need the second column of each array in my jagged array to be sorted from highest to lowest.
using System;
using System.Linq;
namespace Auto_Initiative
{
class Program
{
static void Main(string[] args)
{
string[] encounter =
{
"Wizard", "18", "-2",
"Bard", "9", "3",
"Goblin 1", "16", "1",
"Goblin 2", "14", "1"
};
int[][] numbers = new int[encounter.Length / 3][];
int loop = 0;
for(int i = 0; i > encounter.Length; i += 3)
{
// Name number, real roll
numbers[loop] = new int[2] {i, Int32.Parse(encounter[i + 1]) + Int32.Parse(encounter[i + 2])};
}
Console.ReadKey();
}
}
}
One part of designing your software is choosing the right data structure for how you are planning to use it. Sometimes redundant data is required but we don't know what you are requirements are to make that decision. So as was mentioned by Sergey you should consider creating a custom class which I have shown an example of below. Also note that a string[] is not really a jagged array. By definition a jagged array has nested arrays of variable size. The data structure depicted above could be put in a regular string[][] and would not be jagged.
Object Oriented in Action
What you are looking for is stored in unitsSortedBySecondColumn.
class so65865986
{
static void Main(string[] args)
{
Encounter encounter = new Encounter
{
Units = new List<EncounterUnit> {
new EncounterUnit{
Name = "Wizard",
Column1 = 18,
Column2 = -2,
},
new EncounterUnit{
Name = "Bard",
Column1 = 9,
Column2 = 3,
},
new EncounterUnit{
Name = "Goblin 1",
Column1 = 16,
Column2 = 1,
},
new EncounterUnit{
Name = "Goblin 2",
Column1 = 14,
Column2 = 1,
},
},
};
var unitsSortedBySecondColumn = encounter.Units
.OrderBy(u => u.Column1)
.Select(u => new int[] { u.Column1, u.Column2 })
.ToArray();
}
}
class EncounterUnit
{
public string Name;
public int Column1; //Change name to whatever it means
public int Column2; //Change name to whatever it means
}
class Encounter
{
public List<EncounterUnit> Units;
}
Nested (but not Jagged) Array
class so65865986_nested_array
{
static void Main(string[] args)
{
string[][] encounter =
{
new string[] {"Wizard", "18", "-2" },
new string[] {"Bard", "9", "3" },
new string[] {"Goblin 1", "16", "1" },
new string[] {"Goblin 2", "14", "1" },
};
int[][] numbers = encounter
.Select(u => new int[] { int.Parse(u[1]), int.Parse(u[2]) })
.OrderBy(u => u[0])
.ToArray();
Console.ReadKey();
}
}
Other Notes
Also, another note. You don't need to use Int32 because it is recommended you use the aliases provided which in this case is int.
use this code:
string[] encounter =
{
"Wizard", "18", "-2",
"Bard", "9", "3",
"Goblin 1", "16", "1",
"Goblin 2", "14", "1"
};
int[,] numbers = new int[encounter.Length / 3, 3];
for (int i = 1; i < encounter.Length / 4; i++)
{
for (int j = 0; j < encounter.Length / 3; j += 1)
{
numbers[j, i] = Convert.ToInt32(encounter[i + (j * 3)]);
Console.Write(numbers[j, i] + " ");
}
Console.WriteLine(Environment.NewLine);
}
Console.ReadLine();
This question already has answers here:
Randomize a List<T>
(28 answers)
Closed 3 years ago.
I have string list of a deck of card the strings are as such, A-DIAMONDS, 2-CLUBS, etc.
I want to be able to generate 5 unique items from this list randomly.
I know how to do this in python with Random.sample(5) but in trying to find a solution in C#. everything seems to be generating a random, put it in a list, generate another random, check it against the list and it is working fine.
Is there a more compact way of doing this in C#?
Here is my full code after using Linq for shuffling.
class Program
{
static void Main(string[] args)
{
string [] cardValues = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
string [] cardSuites = { "HEARTS", "CLUBS", "DIAMONDS", "SPADES" };
List<string> deckOfCards = new List<string>();
foreach(string cardsuit in cardSuites)
{
foreach(string cardvalues in cardValues)
{
deckOfCards.Add(cardvalues + "-" + cardsuit);
}
}
for(int i = 0; i <= 10; i++)
{
List<string> pokerHand = new List<string>();
Random rand = new Random();
deckOfCards = deckOfCards.Select(x => new { card = x, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.card).ToList();
for(int x = 0; x < 5; x++)
{
pokerHand.Add(deckOfCards[x]);
}
Console.WriteLine(String.Join(", ", pokerHand));
}
Console.ReadLine();
}
}
}
Here is one way to shuffle using linq. The 5 random cards are the first 5 items in the list. :
class Program
{
static void Main(string[] args)
{
List<string> deck = new List<string>() {
"S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "ST", "SJ", "SQ", "SK", "SA",
"H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "HT", "HJ", "HQ", "HK", "HA",
"C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CT", "CJ", "CQ", "CK", "CA",
"D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DT", "DJ", "DQ", "DK", "DA"
};
Random rand = new Random();
deck = deck.Select(x => new { card = x, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.card).ToList();
}
}
You could use MoreLINQ. Simply install it from NuGet.
MoreLINQ gives you a Shuffle method. So you can do something like the following:
List<Card> deck = GetDeck();
List<Card> randomFiveCards = deck.Shuffle().Take(5).ToList();
A valid and efficient algorithm is to pick a random index between 0 and n-1 (where n is the number of cards), exchange the last card with the card at that index. Then pick a random index between 0 and n-2 and exchange second-last card with the card at that index.
Repeat other three times with n-3, n-4 and n-5 and your five randomly chosen cards will be at the end of the array.
I'm extremely new to coding, so the answer/s to this may be obvious. I have to make the card game War. I've created a list of strings like so for a part of the deck:
List<string> userDeck = new List<string>
{
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"Jack",
"Queen",
"King",
"Ace",
};
Is there a way I can instruct the computer that "Jack" will be greater than "10", "Queen" greater than "Jack", and so on? I'm not sure where or how I should do it.
OR, if you have any other suggestions as to how I should do this, please let me know. I have to be using a list. I initially made a list of integers instead, but I wasn't aware of an uncomplicated way to assign the names such as "Jack," "Queen," "King," etc. to them for display purposes.
Any help would be greatly appreciated.
Try to create a object called "Card". This object can contain more than a value. Eg:
public class MyCard
{
public string Name {get;set;}
public int Value {get;set;}
public MyCard(string name, int value)
{
this.Name = name;
this.Value = value;
}
}
After create this object, you will use this at your list.
List<MyCard> userDeck = new List<MyCard>();
You can fill the list this way:
usertDeck.Add(new MyCard("2", 1));
....
usertDeck.Add(new MyCard("K", 11));
So, to compare 2 cards, just check using the "Value" variable
The easiest way to refactor your code (to your requirements value per card) is to use Tuple's instead of string type in generic List as follow:
List<Tuple<int,string>> userDeck = new List<Tuple<int,string>>
{
new Tuple<int,string>(2,"2"),
new Tuple<int,string>(3,"3"),
new Tuple<int,string>(4,"4"),
new Tuple<int,string>(5,"5"),
new Tuple<int,string>(6,"6"),
new Tuple<int,string>(7,"7"),
new Tuple<int,string>(8,"8"),
new Tuple<int,string>(9,"9"),
new Tuple<int,string>(10,"10"),
new Tuple<int,string>(11,"Jack"),
new Tuple<int,string>(12,"Queen"),
new Tuple<int,string>(13,"King"),
new Tuple<int,string>(14,"Ace"),
};
Similar to Vincius's answer but with some changes for better usability:
enum Suit
{
Clubs = 1,
Diamonds = 2,
Hearts = 3,
Spades = 4
}
class Card
{
private static readonly Dictionary<string, int> rankMap = new Dictionary<string, int>()
{
{"2", 2 },
{"3", 3 },
{"4", 4 },
{"5", 5 },
{"6", 6 },
{"7", 7 },
{"8", 8 },
{"9", 9 },
{"10", 10 },
{"Jack", 11 },
{"Queen", 12 },
{"King", 13 },
{"Ace", 14 },
};
private Suit suit;
private string rank;
public Suit Suit => suit;
public string Rank => rank;
public int Value { get { return rankMap[rank]; } }
public Card(Suit s, string r)
{
suit = s;
rank = r;
}
}
The way you can use it:
Card c1 = new Card(1, "Jack"); // 1 is Clubs
Card c2 = new Card(4, "Queen"); // 4 is Spades
Console.WriteLine(c1.Value); // prints 11
Console.WriteLine(c2.Value); // prints 12
I've got 2 ArrayLists and i want to find common elements from those 2.
Example:
Arraylist 1 contains: "Cat", "Dog", "Phone", "Watch", "Monkey".
Arraylist 2 contains: "Dog", "Phone", "Chair".
As a result i want to have a method which returns : "Dog" and "Phone".
I've used an Array before and the intersect worked with the Array, but I'm using an ArrayList now.
Try this,
ArrayList list1 = new ArrayList{ "cat", "dog" ,"phone", "watch"};
ArrayList list2 = new ArrayList{ "pen", "cat", "dog", "lamp" };
var elements = Enumerable.Intersect(list1.ToArray(), list2.ToArray()).ToArray();
ArrayList result = new ArrayList(elements);
Hope helps,
You can try this:
ArrayList first = new ArrayList();
first.Add("Cat");
first.Add("Dog");
ArrayList second = new ArrayList();
second.Add("Dog");
second.Add("Phone");
ArrayList final = new ArrayList();
foreach (var i in first.Cast<string>().Intersect(second.Cast<string>()))
final.Add(i);
The resulting ArrayList is Dog
I would implement an extension method for Intersect, so you can use it just as you would for any other iterable collection:
public static class ArrayListExtensions
{
public static ArrayList Intersect(this ArrayList source, ArrayList other)
=> new ArrayList(source.ToArray().Intersect(other.ToArray()).ToArray());
}
Usage:
var first = new ArrayList(new[] { "Cat", "Dog", "Phone", "Watch", "Monkey" });
var second = new ArrayList(new[] { "Dog", "Phone", "Chair" });
var intersection = first.Intersect(second); // intersection is now an ArrayList
What is the best way to compare two lists based on values, order and the number of values. So all of the lists below should be different.
var list1 = new List<string> { "1", "2" };
var list2 = new List<string> { "2", "1" };
var list3 = new List<string> { "1", "2", "3" };
How about using SequenceEqual.
See http://ideone.com/yZeYRh
var a = new [] { "1", "2", "3" };
var b = new [] { "1", "2" };
var c = new [] { "2", "1" };
Console.WriteLine(a.SequenceEqual(b)); // false
Console.WriteLine(a.SequenceEqual(c)); // false
Console.WriteLine(c.SequenceEqual(b)); // false
It comes from the namespace System.Linq and can be used on any IEnumerable.
You can also pass it an IEqualityComparer to for example also do:
var d = new [] { "a", "B" };
var e = new [] { "A", "b" };
Console.WriteLine(d.SequenceEqual(e, StringComparer.OrdinalIgnoreCase)); // true
I like Zip for this, but you still need to manually compare Count.
lista.Count() ==listb.Count() && lista.Zip(listb, Equals).All(a=>a);