实例介绍
【实例简介】模拟一副扑克牌,根据点数、花色等分组、筛选为例子,详细讲解linq中筛选之后的集合到底是引用类型还是值类型,如何才能正确使用筛选后的集合和其中的元素。
压缩的是一个项目文件,运行时,需要自己新建解决方案,我用的是VS2017。如果版本低于这个的话,只要把其中的program.cs文件中内容复制到自己新建的解决方案中,也可以运行。
【实例截图】
【核心代码】
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Poker
{
class Program
{
static void Main(string[] args)
{
test07();
Console.ReadLine();
}
/// <summary>
/// 根据点数分组,每个组按照点数大小排序,每个组里面的内容,再根据color排序
/// </summary>
static void test01() {
var cards = Card.GetPack();
Card.Shuffle(cards);
//cards = Card.RandomN(cards,40);
var a1 = from n in cards
group n by n.points into d1
orderby d1.Key descending
select new
{
key = d1.Key,
value = d1.OrderByDescending(p => p.color),
number=d1.Count()//小组里面有几张牌
};
foreach (var b1 in a1)
{
foreach (var d1 in b1.value)
{
Console.Write(d1.name);
}
Console.WriteLine();
}
}
static void test02() {
var card1 = Card.GetPack_BlackJack().First(p => p.name.Equals("红桃A"));
var card2 = Card.GetPack_BlackJack().First(p => p.name.Equals("红桃K"));
var card3 = Card.GetPack_BlackJack().First(p => p.name.Equals("黑桃3"));
var playerCards = new List<Card>();
playerCards.Add(card1);
playerCards.Add(card2);
playerCards.Add(card3);
var sss= Card.GetPack_BlackJack().Except(playerCards, new CardBlackJackComparer());
sss = sss.OrderBy(p => p.color).ThenBy(p => p.points);
foreach (var b1 in sss)
{
Console.Write(b1.name " ");
}
}
static void test03()
{
//var a1 = from n in dsds1
// group n by new { name1 = n.bankerCards[0].name, name2 = n.bankerCards[1].name, name3 = n.bankerCards[2].name } into d1
// select new
// {
// key = d1.Key,
// Count = d1.Count()
// };
}
/// <summary>
/// 测试,list是一个引用对象,引用传递,是可以改变整个list的属性的
/// </summary>
static void test04() {
var t1 = Card.GetPack_BlackJack();
test05(t1);
var s = t1;
}
static void test05(List<Card> c1)
{
//c1.ForEach(p => p.points = p.points 100);
c1.Where(p => p.points == 5).ToList().ForEach(p => p.points = p.points 1000);
c1.AddRange(Card.GetPack_BlackJack());
}
/// <summary>
/// 测试 排序
/// 1.orderby总结,就是linq里面的一个方法,每次调用,都以list为参数,运行一次,
/// 会产生一个结果,就是排序之后的list,这个过程对原来的list也就是参数没有影响,
/// 如果你不获取这个结果,那么结果就没有了。
///
/// 2.修改自身与修改副本,比如传一个引用到一个函数里,普通的情况,是可以修改这个引用的里面的情况,
/// 但是改不了引用本身,要是改本身,得在外面改,而如果是ref的情况下,是可以的
/// </summary>
static void test06()
{
var t1 = Card.GetPack_BlackJack();
List<Card> s = null;
//test061(t1);
//test065(t1);
//s = t1;
//test064(ref t1);
//s = t1;
//test063(ref t1);
//s = t1;
//test062(t1);
//s = t1;
//t1=test062(t1);
//s = t1;
//test066(ref t1);
//s = t1;
test068(t1);
s = t1;
test067(t1);
s = t1;
}
/// <summary>
/// 假排序,因为传递了一个形参,改变形参,没用
/// </summary>
/// <param name="c1"></param>
static void test061(List<Card> t1)
{
t1 = t1.OrderBy(p => p.color).ThenBy(p => p.points).ToList();
}
/// <summary>
/// 假排序,同样是形参,改变形参没用,出了这个函数,还是没有排序的
/// </summary>
/// <param name="t1"></param>
static void test065(List<Card> t1)
{
var ss=t1.OrderBy(p => p.color).ThenBy(p => p.points).ToList().First();
var dd = ss;
}
/// <summary>
/// 真排序,关键在于取得了返回值,
/// </summary>
/// <param name="c1"></param>
static List<Card> test062(List<Card> t1)
{
t1 = t1.OrderBy(p => p.color).ThenBy(p => p.points).ToList();
return t1;
}
/// <summary>
/// 真排序,首先传递的 不是形参,是真的,可以改变这个list的指向的,
/// 而在里面,真的把这个指向了排号之后的东西
/// </summary>
/// <param name="t1"></param>
static void test063(ref List<Card> t1)
{
t1 = t1.OrderBy(p => p.color).ThenBy(p => p.points).ToList();
}
/// <summary>
/// 假排序,虽然是真参数,但是结果没有获取
/// </summary>
/// <param name="t1"></param>
static void test064(ref List<Card> t1)
{
t1.OrderBy(p => p.color).ThenBy(p => p.points).ToList();
}
/// <summary>
/// 真改了,从此以后 这个list就是空了
/// </summary>
/// <param name="t1"></param>
static void test066(ref List<Card> t1)
{
t1 = null;
}
/// <summary>
/// 真改了,从此以后 这个list本身不是空,但是每一个项是空的了
/// </summary>
/// <param name="t1"></param>
static void test067(List<Card> t1)
{
for (int i = 0; i < t1.Count;i )
{
t1[i] = null;
}
}
/// <summary>
/// 没有改 这个p是一个形参,改形参没用,只是形参指向空
/// 不像上一个 t1[i] 不是形参,是实参,而这个P 是形参
/// </summary>
/// <param name="t1"></param>
static void test068(List<Card> t1)
{
t1.ForEach(p => p = null);
}
/// <summary>
/// 这个LIST是上面所说的了,但是里面具体的东西,比如用where筛选出来的一个子list
/// 那个这个LIST和原始的LIST中有相同的对象,这个是值引用还是复制的,
/// 这两个list中的对象,其实是共有的,比如你该了where 里面的每个对象的值,那个总的对应的对象,也都改变
/// </summary>
/// <param name="t1"></param>
static void test07()
{
var cards = Card.GetPack();
var t1 =cards.Where(p => p.points == 2).ToList();
foreach (var d1 in t1)
{
d1.pointsName = "已经修改了";
}
foreach (var d1 in cards)
{
Console.Write(d1.pointsName);
}
Console.WriteLine();
}
}
/// <summary>
/// 扑克类
/// color colorName points pointsName都是初始化的时候设置的,
///
///具体设置规则,可以选择
/// </summary>
public class Card
{
/// <summary>
/// 一副牌的唯一标记,数量
/// </summary>
public int number;
/// <summary>
/// 3, 2, 1, 0
/// 黑桃>红桃>梅花>方块
/// </summary>
public int color;
/// <summary>
/// 花色,红桃、黑桃
/// </summary>
public string colorName;
/// <summary>
/// 2为2,3为3,J为11,Q为12,K为13,A为14
/// </summary>
public int points;
/// <summary>
/// 就是JKQA2\3
/// </summary>
public string pointsName;
/// <summary>
/// 返回比如说红桃3
/// </summary>
public string name
{
get { return this.colorName this.pointsName; }
}
/// <summary>
/// 构造方法
/// 默认构造方法,
/// 0 1 2 3
/// 方块、梅花、红桃、黑桃
/// 2 3 K A
/// 2 3 13 14
/// </summary>
/// <param name="number"></param>
public Card(int i)
{
this.number = i;
if (i % 4 == 0)
{
this.color = 0;
this.colorName = "方块";
}
else if (i % 4 == 1)
{
this.color = 1;
this.colorName = "梅花";
}
else if (i % 4 == 2)
{
this.color = 2;
this.colorName = "红桃";
}
else
{
this.color = 3;
this.colorName = "黑桃";
}
if (i % 13 == 0)
{
this.points = 3;
this.pointsName = "3";
}
else if (i % 13 == 1)
{
this.points = 4;
this.pointsName = "4";
}
else if (i % 13 == 2)
{
this.points = 5;
this.pointsName = "5";
}
else if (i % 13 == 3)
{
this.points = 6;
this.pointsName = "6";
}
else if (i % 13 == 4)
{
this.points = 7;
this.pointsName = "7";
}
else if (i % 13 == 5)
{
this.points = 8;
this.pointsName = "8";
}
else if (i % 13 == 6)
{
this.points = 9;
this.pointsName = "9";
}
else if (i % 13 == 7)
{
this.points = 10;
this.pointsName = "10";
}
else if (i % 13 == 8)
{
this.points = 11;
this.pointsName = "J";
}
else if (i % 13 == 9)
{
this.points = 12;
this.pointsName = "Q";
}
else if (i % 13 == 10)
{
this.points = 13;
this.pointsName = "K";
}
else if (i % 13 == 11)
{
this.points = 14;
this.pointsName = "A";
}
else if (i % 13 == 12)
{
this.points = 2;
this.pointsName = "2";
}
}
/// <summary>
/// 比如梅花10,方块7,红桃A,黑桃K
/// 红心 黑心 草花 钻石
/// </summary>
/// <param name="name"></param>
public Card(string name)
{
switch (name.Substring(0, 2))
{
case "红桃": this.color = 0; this.colorName = "红桃"; break;
case "红心": this.color = 0; this.colorName = "红桃"; break;
case "黑桃": this.color = 1; this.colorName = "黑桃"; break;
case "黑心": this.color = 1; this.colorName = "黑桃"; break;
case "方块": this.color = 2; this.colorName = "方块"; break;
case "钻石": this.color = 2; this.colorName = "方块"; break;
case "方角": this.color = 2; this.colorName = "方块"; break;
case "方片": this.color = 2; this.colorName = "方块"; break;
case "梅花": this.color = 3; this.colorName = "梅花"; break;
case "草花": this.color = 3; this.colorName = "梅花"; break;
case "花子": this.color = 3; this.colorName = "梅花"; break;
}
if (name.Length == 4)
{
this.points = 10;
this.pointsName = "10";
}
else
{
switch (name.Substring(2, 1))
{
case "2": this.points = 2; this.pointsName = "2"; break;
case "3": this.points = 3; this.pointsName = "3"; break;
case "4": this.points = 4; this.pointsName = "4"; break;
case "5": this.points = 5; this.pointsName = "5"; break;
case "6": this.points = 6; this.pointsName = "6"; break;
case "7": this.points = 7; this.pointsName = "7"; break;
case "8": this.points = 8; this.pointsName = "8"; break;
case "9": this.points = 9; this.pointsName = "9"; break;
case "J": this.points = 11; this.pointsName = "J"; break;
case "Q": this.points = 12; this.pointsName = "Q"; break;
case "K": this.points = 13; this.pointsName = "K"; break;
case "A": this.points = 1; this.pointsName = "A"; break;
}
}
}
/// <summary>
/// 没有大小王的,52张
/// points和color如下:
/// 0 1 2 3
/// 方块 梅花 红桃 黑桃
/// 2 3 ……10 J Q K A
/// 2 3 ……10 11 12 13 14
/// </summary>
/// <returns></returns>
public static List<Card> GetPack()
{
var resut = new List<Card>();
for (int i = 1; i <= 52; i )
{
Card pokerCard = new Card(i);
resut.Add(pokerCard);
}
return resut;
}
/// <summary>
/// 取得一副21点扑克,
/// JQK的points为10,A为11
/// </summary>
/// <returns></returns>
public static List<Card> GetPack_BlackJack()
{
var resut = Card.GetPack();
//JQK
resut.Where(p => p.points == 11 || p.points == 12 || p.points == 13).ToList().ForEach(p => p.points = 10);
//A
resut.Where(p => p.points == 14).ToList().ForEach(p => p.points = 11);
return resut;
}
/// <summary>
/// 洗牌
/// </summary>
/// <param name="pokerCards"></param>
/// <returns></returns>
public static void Shuffle(List<Card> pokerCards)
{
Random random = new Random();
int times = random.Next(0, pokerCards.Count * 3);//交换次数
Card templs = null;
for (int i = 0; i < times; i )
{
int t1 = random.Next(0, pokerCards.Count);
int t2 = random.Next(0, pokerCards.Count);
var c1 = pokerCards.ElementAt(t1);
var c2 = pokerCards.ElementAt(t2);
pokerCards[t1] = c2;
pokerCards[t2] = c1;
}
}
/// <summary>
/// 随机抽取一张牌
/// </summary>
/// <param name="pokerCards"></param>
/// <returns></returns>
public static Card RandomOne(List<Card> pokerCards)
{
Random ran = new Random();
int ranKey = ran.Next(0, pokerCards.Count);
Card a1 = pokerCards.ElementAt(ranKey);
pokerCards.RemoveAt(ranKey);
return a1;
}
/// <summary>
/// 随机抽取n张牌
/// </summary>
/// <param name="pokerCards"></param>
/// <returns></returns>
public static List<Card> RandomN(List<Card> pokerCards, int n)
{
List<Card> results = new List<Card>();
while (n > 0)
{
results.Add(Card.RandomOne(pokerCards));
n--;
}
return results;
}
}
/// <summary>
/// BlackJack比较器
/// </summary>
public class CardBlackJackComparer : IEqualityComparer<Card>
{
public bool Equals(Card x, Card y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (x.name.Equals(y.name))
{
return true;
}
else {
return false;
}
}
public int GetHashCode(Card obj)
{
int CardName =obj.name.GetHashCode();
return CardName;
}
}
/// <summary>
/// 结构体,百家乐扑克
/// </summary>
public struct Card_B {
/// <summary>
/// 一副牌的唯一标记,数量
/// </summary>
public int number;
/// <summary>
/// 3, 2, 1, 0
/// 黑桃>红桃>梅花>方块
/// </summary>
public int color;
/// <summary>
/// 花色,红桃、黑桃
/// </summary>
public string colorName;
/// <summary>
/// 2为2,3为3,J为11,Q为12,K为13,A为14
/// </summary>
public int points;
/// <summary>
/// 就是JKQA2\3
/// </summary>
public string pointsName;
/// <summary>
/// 返回比如说红桃3
/// </summary>
public string name
{
get { return this.colorName this.pointsName; }
}
/// <summary>
/// 构造方法
/// 百家乐扑克,点数为
/// 0 1 2 3
/// 方块、梅花、红桃、黑桃
///
/// 2 3 10 K A
/// 2 3 0 0 1
/// </summary>
/// <param name="number"></param>
public Card_B(int i)
{
this.number = i;
if (i % 4 == 0)
{
this.color = 0;
this.colorName = "方块";
}
else if (i % 4 == 1)
{
this.color = 1;
this.colorName = "梅花";
}
else if (i % 4 == 2)
{
this.color = 2;
this.colorName = "红桃";
}
else
{
this.color = 3;
this.colorName = "黑桃";
}
if (i % 13 == 0)
{
this.points = 3;
this.pointsName = "3";
}
else if (i % 13 == 1)
{
this.points = 4;
this.pointsName = "4";
}
else if (i % 13 == 2)
{
this.points = 5;
this.pointsName = "5";
}
else if (i % 13 == 3)
{
this.points = 6;
this.pointsName = "6";
}
else if (i % 13 == 4)
{
this.points = 7;
this.pointsName = "7";
}
else if (i % 13 == 5)
{
this.points = 8;
this.pointsName = "8";
}
else if (i % 13 == 6)
{
this.points = 9;
this.pointsName = "9";
}
else if (i % 13 == 7)
{
this.points = 0;
this.pointsName = "10";
}
else if (i % 13 == 8)
{
this.points = 0;
this.pointsName = "J";
}
else if (i % 13 == 9)
{
this.points = 0;
this.pointsName = "Q";
}
else if (i % 13 == 10)
{
this.points = 0;
this.pointsName = "K";
}
else if (i % 13 == 11)
{
this.points = 1;
this.pointsName = "A";
}
else if (i % 13 == 12)
{
this.points = 2;
this.pointsName = "2";
}
else {//结构体必须被赋值
this.points = 0;
this.pointsName = "0";
}
}
/// <summary>
/// 没有大小王的,52张
/// points和color如下:
/// 0 1 2 3
/// 方块 梅花 红桃 黑桃
/// 2 3 ……10 J Q K A
/// 2 3 ……0 0 0 0 1
/// </summary>
/// <returns></returns>
public static List<Card_B> GetPack_B()
{
var resut = new List<Card_B>();
for (int i = 1; i <= 52; i )
{
Card_B pokerCard = new Card_B(i);
resut.Add(pokerCard);
}
return resut;
}
}
/// <summary>
/// 百家乐扑克比较器
/// </summary>
public class BaccaratComparer : IEqualityComparer<Card_B>
{
public bool Equals(Card_B x, Card_B y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (x.number==y.number)
{
return true;
}
else
{
return false;
}
}
public int GetHashCode(Card_B obj)
{
int CardName = obj.number.GetHashCode();
return CardName;
}
}
/// <summary>
/// 结构体,21点扑克
/// </summary>
public struct Card_J
{
/// <summary>
/// 一副牌的唯一标记,数量
/// </summary>
public int number;
/// <summary>
/// 3, 2, 1, 0
/// 黑桃>红桃>梅花>方块
/// </summary>
public int color;
/// <summary>
/// 花色,红桃、黑桃
/// </summary>
public string colorName;
/// <summary>
/// 2为2,3为3,J为10,Q为10,K为10,A为11
/// </summary>
public int points;
/// <summary>
/// 就是JKQA2\3
/// </summary>
public string pointsName;
/// <summary>
/// 返回比如说红桃3
/// </summary>
public string name
{
get { return this.colorName this.pointsName; }
}
/// <summary>
/// 构造方法
/// 百家乐扑克,点数为
/// 0 1 2 3
/// 方块、梅花、红桃、黑桃
///
/// 2 3 10 K A
/// 2 3 0 0 1
/// </summary>
/// <param name="number"></param>
public Card_J(int i)
{
this.number = i;
if (i % 4 == 0)
{
this.color = 0;
this.colorName = "方块";
}
else if (i % 4 == 1)
{
this.color = 1;
this.colorName = "梅花";
}
else if (i % 4 == 2)
{
this.color = 2;
this.colorName = "红桃";
}
else
{
this.color = 3;
this.colorName = "黑桃";
}
if (i % 13 == 0)
{
this.points = 3;
this.pointsName = "3";
}
else if (i % 13 == 1)
{
this.points = 4;
this.pointsName = "4";
}
else if (i % 13 == 2)
{
this.points = 5;
this.pointsName = "5";
}
else if (i % 13 == 3)
{
this.points = 6;
this.pointsName = "6";
}
else if (i % 13 == 4)
{
this.points = 7;
this.pointsName = "7";
}
else if (i % 13 == 5)
{
this.points = 8;
this.pointsName = "8";
}
else if (i % 13 == 6)
{
this.points = 9;
this.pointsName = "9";
}
else if (i % 13 == 7)
{
this.points = 10;
this.pointsName = "10";
}
else if (i % 13 == 8)
{
this.points = 10;
this.pointsName = "J";
}
else if (i % 13 == 9)
{
this.points = 10;
this.pointsName = "Q";
}
else if (i % 13 == 10)
{
this.points = 10;
this.pointsName = "K";
}
else if (i % 13 == 11)
{
this.points = 11;
this.pointsName = "A";
}
else if (i % 13 == 12)
{
this.points = 2;
this.pointsName = "2";
}
else
{//结构体必须被赋值
this.points = 0;
this.pointsName = "0";
}
}
/// <summary>
/// 没有大小王的,52张
/// points和color如下:
/// 0 1 2 3
/// 方块 梅花 红桃 黑桃
/// 2 3 ……10 J Q K A
/// 2 3 ……0 0 0 0 1
/// </summary>
/// <returns></returns>
public static List<Card_J> GetPack_J()
{
var resut = new List<Card_J>();
for (int i = 1; i <= 52; i )
{
Card_J pokerCard = new Card_J(i);
resut.Add(pokerCard);
}
return resut;
}
}
/// <summary>
/// 21点扑克比较器
/// </summary>
public class BlackJackComparer : IEqualityComparer<Card_J>
{
public bool Equals(Card_J x, Card_J y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (x.number == y.number)
{
return true;
}
else
{
return false;
}
}
public int GetHashCode(Card_J obj)
{
int CardName = obj.number.GetHashCode();
return CardName;
}
}
/// <summary>
/// 21点扑克,只有点数和name两个属性
/// </summary>
public class Card21
{
/// <summary>
/// 2为2,3为3,J为10,Q为10,K为10,A为11
/// </summary>
public int points;
/// <summary>
/// 就是JKQA2\3
/// </summary>
public string name;
/// <summary>
/// 构造方法
/// 默认构造方法,
/// 0 1 2 3
/// 方块、梅花、红桃、黑桃
/// 2 3 K A
/// 2 3 13 14
/// </summary>
/// <param name="number"></param>
public Card21(string name)
{
switch (name)
{
case "2": this.points = 2; this.name = "2"; break;
case "3": this.points = 3; this.name = "3"; break;
case "4": this.points = 4; this.name = "4"; break;
case "5": this.points = 5; this.name = "5"; break;
case "6": this.points = 6; this.name = "6"; break;
case "7": this.points = 7; this.name = "7"; break;
case "8": this.points = 8; this.name = "8"; break;
case "9": this.points = 9; this.name = "9"; break;
case "10": this.points = 10; this.name = "10"; break;
case "J": this.points = 10; this.name = "J"; break;
case "Q": this.points = 10; this.name = "Q"; break;
case "K": this.points = 10; this.name = "K"; break;
case "A": this.points = 11; this.name = "A"; break;
}
}
}
/// <summary>
///百家乐扑克,只有点数和name两个属性
/// </summary>
public class Card0
{
/// <summary>
/// 2为2,3为3,J为10,Q为10,K为10,A为11
/// </summary>
public int points;
/// <summary>
/// 就是JKQA2\3
/// </summary>
public string name;
/// <summary>
/// 构造方法
/// 默认构造方法,
/// 0 1 2 3
/// 方块、梅花、红桃、黑桃
/// 2 3 K A
/// 2 3 13 14
/// </summary>
/// <param name="number"></param>
public Card0(string name)
{
switch (name)
{
case "2": this.points = 2; this.name = "2"; break;
case "3": this.points = 3; this.name = "3"; break;
case "4": this.points = 4; this.name = "4"; break;
case "5": this.points = 5; this.name = "5"; break;
case "6": this.points = 6; this.name = "6"; break;
case "7": this.points = 7; this.name = "7"; break;
case "8": this.points = 8; this.name = "8"; break;
case "9": this.points = 9; this.name = "9"; break;
case "10": this.points = 10; this.name = "10"; break;
case "J": this.points = 10; this.name = "J"; break;
case "Q": this.points = 10; this.name = "Q"; break;
case "K": this.points = 10; this.name = "K"; break;
case "A": this.points = 1; this.name = "A"; break;
}
}
}
}
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论