Reputation: 139
I am new to c# and attempting to do it the right way. I have searched stackoverflow and consulted tutorials and books re 'sorting class objects' but have yet to find anything that works for me, despite struggling with LISTS, INUMERATORS and COMPARATORS. To help me learn c# I am attempting to replicate an old board game. It includes Cards that need to be sorted or shuffled on the start of a new game. I'm getting the card data via a stored procedure from SQL Server because I am trying to get to grips with that as well. How can I simply sort my card class objects and RETURN them from my function below? Am I even going about this task in the best way? Below is my 'PirateCard' class. Many thanks.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Collections;
namespace Buccaneer
{
public class PirateCard : Card
{
public PirateCard()
{
}
public PirateCard[] initCards()
{
string spName = "sp_select_cards_by_type";
int cardCount = 1;
db DB = new db();
DataTable dt = new DataTable();
Dictionary<string, string> spParams = new Dictionary<string, string>();
spParams.Add("@Type", "PIRATE");
dt = DB.executeSelectStoredProcedureWithParams(spName, spParams);
PirateCard[] pirateCards = new PirateCard[dt.Rows.Count + 1];
List<int> sortNumber = shuffle();
Console.WriteLine(sortNumber.Count);
foreach (DataRow row in dt.Rows)
{
pirateCards[cardCount] = new PirateCard();
pirateCards[cardCount].Type = row["fldtype"].ToString();
pirateCards[cardCount].Number = row["fldno"].ToString();
pirateCards[cardCount].SortNumber= sortNumber.ElementAt(cardCount - 1);
pirateCards[cardCount].IncentiveType = row["fldincentivetype"].ToString();
pirateCards[cardCount].Value = row["fldvalue"].ToString();
pirateCards[cardCount].PlayWithin = row["fldplaywith"].ToString();
pirateCards[cardCount].Text = row["fldtext"].ToString();
Console.WriteLine(pirateCards[cardCount].Number + ":" + pirateCards[cardCount].SortNumber);
cardCount++;
}
Console.WriteLine(DB.RecordCount + " pirate cards were found.");
// SHUFFLE OR SORT CARDS on .SortNumber here...
// ???
return pirateCards;
}
public List<int> shuffle()
{
Random randNum = new Random();
List<int> numbers = new List<int>();
while (numbers.Count < ApplicationGlobals.numberOfPirateCards)
{
int num = randNum.Next(1, ApplicationGlobals.numberOfPirateCards + 1);
if (numbers.Contains(num))
{
}
else
{
numbers.Add(num);
Console.WriteLine(num + " Numbers allocated so far " + numbers.Count);
}
}
Console.WriteLine(numbers.Count + " random numbers allocated");
return numbers;
}
}
}
Upvotes: 0
Views: 249
Reputation: 54887
You can sort the cards using the LINQ OrderBy
extension method. I'm assuming you want your cards sorted based on their SortNumber
property.
return pirateCards.OrderBy(card => card.SortNumber).ToArray();
Edit: On second thoughts, you should do away with your shuffle
method (and SortNumber
property), and use the first extension method provided from this answer, which is based on the Fisher–Yates shuffle. You can call it using:
return pirateCards.Shuffle();
Upvotes: 2
Reputation: 30042
You can save a lot of time by using "LinQ to SQL Classes"
that will convert your database tables to classes. Then you can sort and group your array of objects in simple code.
Upvotes: 0
Reputation: 22481
If you want to stick with the array, there are various overloads of the Array.Sort method. some take a Comparison as a parameter, e.g.:
Array.Sort(pirateCards, (x, y) => x.SortNumber - y.SortNumber);
By the way, your array is one element to large; you should initialize it as follows to avoid a NullReferenceException when sorting:
PirateCard[] pirateCards = new PirateCard[dt.Rows.Count];
Also, cardCount
needs to be initilized with a value of 0 as arrays start with 0 in .NET.
Upvotes: 0