斗地主洗牌算法的题目,哪儿还可以优化?

问题描述

publicclassPoker{publicstringColor{get;set;}publicstringCard{get;set;}publicintValue{get;set;}}

publicclassPokerCard{privateDictionary<string,List<Poker>>_poker=newDictionary<string,List<Poker>>();publicDictionary<string,List<Poker>>Role=null;privatevoidFillPoker(){_poker=newDictionary<string,List<Poker>>{{"方块",newList<Poker>{newPoker{Color="方块",Card="3",Value=3},newPoker{Color="方块",Card="4",Value=4},newPoker{Color="方块",Card="5",Value=5},newPoker{Color="方块",Card="6",Value=6},newPoker{Color="方块",Card="7",Value=7},newPoker{Color="方块",Card="8",Value=8},newPoker{Color="方块",Card="9",Value=9},newPoker{Color="方块",Card="10",Value=10},newPoker{Color="方块",Card="J",Value=11},newPoker{Color="方块",Card="Q",Value=12},newPoker{Color="方块",Card="K",Value=13},newPoker{Color="方块",Card="A",Value=14},newPoker{Color="方块",Card="2",Value=15}}},{"红桃",newList<Poker>{newPoker{Color="红桃",Card="3",Value=3},newPoker{Color="红桃",Card="4",Value=4},newPoker{Color="红桃",Card="5",Value=5},newPoker{Color="红桃",Card="6",Value=6},newPoker{Color="红桃",Card="7",Value=7},newPoker{Color="红桃",Card="8",Value=8},newPoker{Color="红桃",Card="9",Value=9},newPoker{Color="红桃",Card="10",Value=10},newPoker{Color="红桃",Card="J",Value=11},newPoker{Color="红桃",Card="Q",Value=12},newPoker{Color="红桃",Card="K",Value=13},newPoker{Color="红桃",Card="A",Value=14},newPoker{Color="红桃",Card="2",Value=15}}},{"黑桃",newList<Poker>{newPoker{Color="黑桃",Card="3",Value=3},newPoker{Color="黑桃",Card="4",Value=4},newPoker{Color="黑桃",Card="5",Value=5},newPoker{Color="黑桃",Card="6",Value=6},newPoker{Color="黑桃",Card="7",Value=7},newPoker{Color="黑桃",Card="8",Value=8},newPoker{Color="黑桃",Card="9",Value=9},newPoker{Color="黑桃",Card="10",Value=10},newPoker{Color="黑桃",Card="J",Value=11},newPoker{Color="黑桃",Card="Q",Value=12},newPoker{Color="黑桃",Card="K",Value=13},newPoker{Color="黑桃",Card="A",Value=14},newPoker{Color="黑桃",Card="2",Value=15}}},{"梅花",newList<Poker>{newPoker{Color="梅花",Card="3",Value=3},newPoker{Color="梅花",Card="4",Value=4},newPoker{Color="梅花",Card="5",Value=5},newPoker{Color="梅花",Card="6",Value=6},newPoker{Color="梅花",Card="7",Value=7},newPoker{Color="梅花",Card="8",Value=8},newPoker{Color="梅花",Card="9",Value=9},newPoker{Color="梅花",Card="10",Value=10},newPoker{Color="梅花",Card="J",Value=11},newPoker{Color="梅花",Card="Q",Value=12},newPoker{Color="梅花",Card="K",Value=13},newPoker{Color="梅花",Card="A",Value=14},newPoker{Color="梅花",Card="2",Value=15}}},{"Joker",newList<Poker>{newPoker{Color="Joker",Card="SmallJoker",Value=16},newPoker{Color="Joker",Card="BigJoker",Value=16}}}};}publicvoidShuffleCard(){FillPoker();varrandom=newRandom();Role=newDictionary<string,List<Poker>>();for(vari=0;i<51;i++){//ToDo从4种花色加Joker中随机抽取一种没分配完的花色varcolour=_poker.Where(x=>x.Value.Count!=0).Select(x=>x.Key).ToArray();varselectColor=colour[random.Next(colour.Length)];//ToDo从选定的花色中随机抽取一张没有分配过的牌varselectValue=_poker[selectColor][random.Next(_poker[selectColor].Count)];if((i+1)%3==0){if(Role.ContainsKey("角色C:"))Role["角色C:"].Add(selectValue);elseRole.Add("角色C:",newList<Poker>{selectValue});}elseif((i+1)%2==0){if(Role.ContainsKey("角色B:"))Role["角色B:"].Add(selectValue);elseRole.Add("角色B:",newList<Poker>{selectValue});}else{if(Role.ContainsKey("角色A:"))Role["角色A:"].Add(selectValue);elseRole.Add("角色A:",newList<Poker>{selectValue});}//ToDo移除已被分配的牌_poker[selectColor].Remove(selectValue);}//ToDo取出未分配的牌,存入底牌_poker=_poker.Where(x=>x.Value.Count!=0).ToDictionary(x=>x.Key,y=>y.Value);foreach(vartin_poker.SelectMany(item=>item.Value)){if(Role.ContainsKey("底牌"))Role["底牌"].Add(t);elseRole.Add("底牌",newList<Poker>{t});}}}

调用staticvoidMain(string[]args){varpokerCard=newPokerCard();pokerCard.ShuffleCard();Console.Write("角色A:");pokerCard.Role["角色A:"].OrderBy(x=>x.Value).ToList().ForEach(x=>Console.Write(x.Color+x.Card+""));Console.WriteLine("rn");Console.Write("角色B:");pokerCard.Role["角色B:"].OrderBy(x=>x.Value).ToList().ForEach(x=>Console.Write(x.Color+x.Card+""));Console.WriteLine("rn");Console.Write("角色C:");pokerCard.Role["角色C:"].OrderBy(x=>x.Value).ToList().ForEach(x=>Console.Write(x.Color+x.Card+""));Console.WriteLine("rn");Console.Write("底牌:");pokerCard.Role["底牌"].OrderBy(x=>x.Value).ToList().ForEach(x=>Console.Write(x.Color+x.Card+""));Console.WriteLine("rn");Console.ReadLine();}

结果

解决方案

解决方案二:
看见算法,进来膜拜一下~~
解决方案三:
不要给每个人随机发牌你应该随机打乱整个牌的次序,然后之后就按顺序发牌就好了
解决方案四:
引用2楼Z65443344的回复:

不要给每个人随机发牌你应该随机打乱整个牌的次序,然后之后就按顺序发牌就好了

引用2楼Z65443344的回复:

不要给每个人随机发牌你应该随机打乱整个牌的次序,然后之后就按顺序发牌就好了

我就没想到这样。而且我觉得那代码太长了
解决方案五:
staticvoidMain(string[]args){Func<int,string>getName=p=>{vars=new[]{"黑桃","红桃","梅花","方块"};varn=new[]{"A","2","3","4","5","6","7","8","9","10","J","Q","K"};returnp<52?s[p/13]+n[p%13]:p==52?"JokerSmallJoker":"JokerBigJoker";};varbuf=newbyte[54];using(varrnd=newRNGCryptoServiceProvider())rnd.GetBytes(buf);varps=Enumerable.Range(0,buf.Length).OrderBy(p=>buf[p]).Select((p,i)=>new{p,i}).GroupBy(t=>t.i>50?3:t.i%3,t=>t.p).OrderBy(g=>g.Key);varr=new[]{"角色A","角色B","角色C","底牌"};foreach(varginps){Console.Write(r[g.Key]+":");foreach(varping)Console.Write(getName(p)+"");Console.WriteLine("rn");}}

解决方案六:
不要随机发牌,应该在每轮发牌中加入权值,如果权值超过设定值,从没发出去的牌中挑一张和权值相匹配的牌。这样你才能给付费用户发更好的牌。
解决方案七:
varlist=newList(Poker);//数据填充list=list.OrderBy(r=>Guid.NewGuid()).ToList();//怎么发就随便你了直接一切三,跳着发,都可以
解决方案八:
staticstring[]PokerValues=newstring[]{"3","4","5","6","7","8","9","10","J","Q","K","A","2"};staticDictionary<byte,string>PokerColors=newDictionary<byte,string>(){{0,"方片"},{1,"红桃"},{2,"梅花"},{3,"黑桃"}};staticvoidR(){List<Poker>list=newList<Poker>();foreach(stringpinPokerValues){foreach(bytecinPokerColors.Keys){list.Add(newPoker(){Color=c,Value=p});}}list.Add(newPoker(){Color=5,Value="JQ"});//小鬼list.Add(newPoker(){Color=6,Value="JQ"});//大鬼list=list.OrderBy(p=>Guid.NewGuid()).ToList();Func<byte,string>colorFunc=(i)=>{switch(i){case5:return"小";case6:return"大";default:returnPokerColors[i];}};foreach(varpinlist){Console.Write(string.Format("Color:{0}Value:{1}",colorFunc(p.Color),p.Value));}}publicclassPoker{publicbyteColor{get;set;}publicstringValue{get;set;}}

只有初始化加打乱顺序的代码
解决方案九:
额,完全多余的写法1.54张牌没必要先分什么花色,就是1--52个数字,判定花色直接取和13商,牌点则是和13模.53,54为大小王2.54张牌直接乱序排序见6楼3.发牌先扣3张底牌,然后按index模3分组
解决方案十:
引用8楼wanghui0380的回复:

额,完全多余的写法1.54张牌没必要先分什么花色,就是1--52个数字,判定花色直接取和13商,牌点则是和13模.53,54为大小王2.54张牌直接乱序排序见6楼3.发牌先扣3张底牌,然后按index模3分组

好办法。

时间: 2024-11-27 11:26:11

斗地主洗牌算法的题目,哪儿还可以优化?的相关文章

[cocos2dx]斗地主制作之洗牌算法

做斗地主项目,洗牌算法是一个很重的一步,怎样"洗"的均匀,"洗"的随机,这是非常考究的,算法的优劣就直接会影响效果的好坏.这里我给出一个算法,将0-53这54个数字直接排序,经测试还挺随机的.这里要感谢@灰太龙的指导!这个算法是服务器端用于返回给客户端牌的算法,主要的思想就是不断的换牌,两牌交换位置,如果循环次数增大的话,随机性也会更强,洗牌的效果更好! Code: C#: using System; using System.Collections.Generic

[经典面试题]完美洗牌算法

题目 有个长度为2n的数组{a1,a2,a3,-,an,b1,b2,b3,-,bn},希望排序后{a1,b1,a2,b2,-.,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法. 来源 2013年UC的校招笔试题 思路一 第①步.确定b1的位置,即让b1跟它前面的a2,a3,a4交换: a1,b1,a2,a3,a4,b2,b3,b4 第②步.接着确定b2的位置,即让b2跟它前面的a3,a4交换: a1,b1,a2,b2,a3,a4,b3,b4 第③步.b3跟它前面的a4交换位

javascript随机之洗牌算法深入分析_javascript技巧

洗牌算法是我们常见的随机问题,在玩游戏.随机排序时经常会碰到.它可以抽象成这样:得到一个M以内的所有自然数的随机顺序数组. 在百度搜"洗牌算法",第一个结果是<百度文库-洗牌算法>,扫了一下里面的内容,很多内容都容易误导别人走上歧途,包括最后用链表代替数组,也只是一个有限的优化(链表也引入了读取效率的损失). 该文里的第一种方法,可以简单描述成:随机抽牌,放在另一组:再次抽取,抽到空牌则重复抽."抽到空牌则重复抽"这会导致后面抽到空牌的机会越来越大,显然

一步一步写算法(之洗牌算法)

原文:一步一步写算法(之洗牌算法) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     扑克牌洗牌是我们生活中比较喜欢玩的一个游戏.那么我们有没有什么办法自己设计一个扑克牌洗牌的方法呢?在c运行库当中有一个随机函数rand,它可以生成0~32767之间的任意数.那么有没有可能利用这么一个函数对我们扑克牌进行随即洗牌呢?     在这里我抛砖引玉一下,谈一谈自己目前已经看到的两个算法.欢迎朋友们谈一谈其他的方法.     (1)全局洗牌

一个简单有效的洗牌算法

装配脑袋兄在某个帖子中指出了一种有意思的洗牌算法,博主按照他的思路写了另外一种洗牌算法.下面是该洗牌算法的思路: 我们先看一下纸牌游戏.一幅纸牌由 52 张不同的纸牌组成,发牌时必须产生不重复的纸牌,而且洗牌过程必须公平,即 52! 中纸牌顺序应该等概率出现.很明显这种随机排列所产生的随机数必须均匀分布且独立.由此代码如下: using System; using System.Diagnostics; namespace Lucifer.CSharp.Sample { class Progra

JS随机洗牌算法之数组随机排序_javascript技巧

推荐阅读:JavaScript学习笔记之数组的增.删.改.查 JavaScript学习笔记之数组求和方法 JavaScript学习笔记之数组随机排序 洗牌算法是一个比较形象的术语,本质上让一个数组内的元素随机排列.举例来说,我们有一个如下图所示的数组,数组长度为 9,数组内元素的值顺次分别是 1~9: 从上面这个数组入手,我们要做的就是打乱数组内元素的顺序: 代码实现 维基百科上的 Fisher–Yates shuffle 词条对洗牌算法做了详细介绍,下面演示的算法也是基于其中的理论编写的: A

php实现简单洗牌算法_php技巧

如下所示: 复制代码 代码如下: <?php  /**   * 简单洗牌算法   */  $card_num=54; //牌数  print_r(wash_card($card_num));  function wash_card($card_num)  {      $cards=$tmp=array();      for($i=0;$i<$card_num;$i++){          $tmp[$i]=$i;      }      for($i=0;$i<$card_num;

洗牌算法

几乎所有的程序员都写过类似于"洗牌"的算法,也就是将一个数组随机打乱后输出,虽然很简单,但是深入研究起来,这个小小的算法也是大有讲究.我在面试程序员的时候,就会经常让他们当场写一个洗牌的函数,从中可以观察到他们对于这个问题的理解和写程序的基本功.     在深入讨论之前,必须先定义出一个基本概念:究竟洗牌算法的本质是什么?也就是说,什么样的洗牌结果是"正确"的?     云风曾经有一篇博文,专门讨论了这个问题,他也给出了一个比较确切的定义,在经过洗牌函数后,如果能够

JavaScript随机打乱数组顺序之随机洗牌算法_javascript技巧

假如有一个数组是这样子: var arr1 = ["a", "b", "c", "d"]; 如何随机打乱数组顺序,也即洗牌. 有一个比较广为传播的简单随机算法: function RandomSort (a,b){ return (0.5 - Math.random()); } 实际证明上面这个并不完全随机. 随便一搜网上太多这种东西了,看一下stackoverflow上的一个高分回答,答案出自github上. knuth-s