发牌程序实现方法的探讨!

fankun 2005-05-15 01:12:53
有3个问题,
第一,牌的调用:1,调用系统的card.dll文件,好象还有个库文件可以调用,可惜我不知道,希望各位大虾教教我,另外就是自己找到52张图片,但是不知道有没有效率更高的调用.
第二,在洗牌的时候是任意交换两张牌位置效率高,还是从新随机排列52张牌的顺序效率高.以及,有没有什么更好的洗牌方法.
第三,在发牌的时候,比如四位玩家,同时发牌和循环发牌要分别怎么实现,发牌的延迟动画怎么做,怎样实现系统不会发出两张相同的牌,也就是说怎么记录发出去的牌和剩下的牌?
...全文
217 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
fankun 2005-05-17
  • 打赏
  • 举报
回复
TO: 回复人: hamadou(闵峰)
我所说的模拟人洗牌是指一般人的洗牌习惯,先随机排列一副牌,再把这副牌从中间分开然后互相错开,重复3~7次, 可以达到最佳的洗牌效果.
另外,在cards.dll中好象有几个函数可以调用,不用重新用DRAWING类绘制牌面吧,这个我还不是很清楚,我有空去查资料????
hamadou 2005-05-17
  • 打赏
  • 举报
回复
还有就是你说的画出图形的问题,你的一副牌(他对应一个数组,该数组假定已经洗牌过了),那么我们从数组的第0个位置开始取牌,获得这张牌的数字和花色,把数字drawstring上去,把图片drawimage上去(这些图片需要已经得到,你可以去找找图标),有时还要有边框。如果是背景,就涂成灰色等。大概思路就是如此。
hamadou 2005-05-17
  • 打赏
  • 举报
回复
呵呵,模拟人洗牌,怎么模拟,难道要把每个人的洗牌习惯对应的方法都加进去吗?
其实,你如果想实现交换两张牌的顺序,或者上牌的方法,都可以通过尽可能多地加入方法来实现。
fankun 2005-05-16
  • 打赏
  • 举报
回复
在洗牌的时候如何达到比较好的随机效果,
楼上的所说的就是把牌的循序随机打乱,也就是从新生成一个随机数列,不过这种随机效果不是很好.过于随机,如果能都模拟人洗牌就好了
另外你说的调用system.drawing类来绘制牌面,这点我就有些不懂了,望指教,
调用系统的cards.dll后,是否要重新绘制牌面
hamadou 2005-05-16
  • 打赏
  • 举报
回复
当然,还有些其他的属性和方法,你要根据需要自己来丰富你的类!
hamadou 2005-05-16
  • 打赏
  • 举报
回复
这个问题在比较多的书中都有提及:
一般来看牌有花色和数字组成,你要设计几个类。
card类,也就是牌。它的基本属性要有花色和数字。
cardcollection类(名字不固定,就是一副牌),属性就是就是数量啊什么的,方法有洗牌(洗牌的过程可以看作如下过程:生成4个花色,13中数字(从A到K)做乘积的牌,4X13=52张。然后放在一个集合里,随机地从集合里取得一张牌(现有牌的集合要-1)放入另一个集合,循环如此知道集合中没有牌为止。将新的集合再指定个原集合,那么这个集合的牌就洗完了)。发牌:就是从集合中取得一张牌,你可以每次都从0开始取得。集合中的牌要-1。
至于最后的实现,还需要一个用户控件,它的onpaint方法要重写,你要画出牌的样子来,包括轮廓和花色和数字,以及正反面。翻牌的事件,还有就是游戏的结束与开始的控制。
总之,大概的思路是如此。希望可以给你些帮助!
yyyb 2005-05-16
  • 打赏
  • 举报
回复
用随机函数搞!
52张牌 对应1-52
MyValue = CInt(Int((52 * Rnd()) + 1))‘随机生成的1-52之间的数字

剩下的就不难了吧!!

另外Rnd()函数本身有些地方要注意:每次都是一样的 要情空一下
具体看MSDN吧
fankun 2005-05-16
  • 打赏
  • 举报
回复
谢谢,不过我c#还不是很熟练呵呵……,谢谢各位给的思路
fankun 2005-05-16
  • 打赏
  • 举报
回复
晕死,
N长的代码,有没有简短一点的
pupo 2005-05-16
  • 打赏
  • 举报
回复
/// <summary>
/// Draw roated a card using an angle.
/// </summary>
/// <param name="upperLeft">Top-left location to start drawing the card.</param>
/// <param name="angle">Angle from horizontal -ve is CCW, +ve is CW.</param>
/// <param name="cardIndex">Index of card to draw.</param>
public void DrawRotatedCard( Point upperLeft, int angle, int cardIndex )
{
// Create bitmap big enough for just one card.
using( Bitmap offScreenBitmap = new Bitmap( DefaultWidth, DefaultHeight ) )
{
// Draw card onto internal bitmap before rotation.
//
InternalDrawCard( offScreenBitmap, new Point(0,0), cardIndex );

// Must release HDC before drawing using the .NET Graphics object.
ReleaseDC();

// Convert Angle to Radians
double radAngle = ((angle / 180.0) * Math.PI);

Point upperRight = new Point( upperLeft.X + (int)(DefaultWidth * Math.Cos(radAngle)),
upperLeft.Y + (int)(-DefaultWidth * Math.Sin(radAngle)) );
Point lowerLeft = new Point( upperLeft.X + (int)(DefaultHeight * Math.Sin(radAngle)),
upperLeft.Y + (int)(DefaultHeight * Math.Cos(radAngle)) );

// Use destination point to render image
Point[] destinationPoints = { upperLeft, upperRight, lowerLeft };
//
// Draw image onto the graphic surface using destination point as a guide.
//
graphicsSurface.DrawImage( offScreenBitmap, destinationPoints );
}
}
#endregion

#region Static Helpers
/// <summary>
/// Helper that converts a given Card's rank, suit, mode into the card index.
/// </summary>
/// <param name="suit">Suit to draw.</param>
/// <param name="rank">Rank of card.</param>
/// <returns></returns>
public static int ToCardIndex( CardSuit suit, CardRank rank )
{
int cardNo = -1;

switch( mode )
{
case 0: /*CardMode.RankCollated*/
cardNo = ((int)rank)*4+((int)suit);
break;

case 1: /* CardMode.SuitCollated */
cardNo = 1+((int)rank)+13*((int)suit);
break;

default:
cardNo = 0;
break;
}
return cardNo;
}

/// <summary>
/// Helper that converts card's background image index into card index.
/// </summary>
/// <param name="back"></param>
/// <returns></returns>
public static int ToCardIndex( CardBack back )
{
return (int)back;
}

/// <summary>
/// Helper that converts card index to Suit of Card.
/// </summary>
/// <param name="cardIndex">Card's index.</param>
/// <returns></returns>
public static CardSuit SuitFromCardIndex( int cardIndex )
{
if( mode == (int)CardMode.SuitCollated && (cardIndex >= 1 && cardIndex <= 52))
{
return (CardSuit)((cardIndex-1) / 13);
}
else if( mode == (int)CardMode.RankCollated && (cardIndex >= 0 && cardIndex <= 51) )
{
return (CardSuit)(cardIndex % 4 );
}
else
{
throw new ApplicationException("Suite only valid to SuitCollated, RankCollated modes.");
}
}

/// <summary>
/// Helper that converts card index to Rank of Card.
/// </summary>
/// <param name="cardIndex"></param>
/// <returns></returns>
public static CardRank RankFromCardIndex( int cardIndex )
{
if( mode == (int)CardMode.SuitCollated && (cardIndex >= 1 && cardIndex <= 52))
{
return (CardRank)((cardIndex-1) % 13);
}
else if( mode == (int)CardMode.RankCollated && (cardIndex >= 0 && cardIndex <= 51) )
{
return (CardRank)(cardIndex / 4 );
}
else
{
throw new ApplicationException("Rank only valid to SuitCollated, RankCollated modes.");
}
}
#endregion


private int cardWidth;

public int CardWidth
{
get
{
return cardWidth;
}

}

private int cardHeight;

public int CardHeight
{
get
{
return cardHeight;
}

}
}

#region Native Methods
internal class NativeMethods
{
private NativeMethods() {}

/* public Interface to cards.dll */
[DllImport("cards.dll")]
public static extern bool cdtInit( ref int width, ref int height );

[DllImport("cards.dll")]
public static extern void cdtTerm();

[DllImport("cards.dll")]
public static extern bool cdtDraw( IntPtr hdc,
int x,
int y,
int card,
int mode,
long color );

[DllImport("cards.dll")]
public static extern bool cdtDrawExt( IntPtr hdc,
int x,
int y,
int dx,
int dy,
int card,
int type,
long color );

[DllImport("cards.dll")]
public static extern bool cdtAnimate( IntPtr hdc,
int cardback,
int x,
int y,
int frame );
}
#endregion
}
pupo 2005-05-16
  • 打赏
  • 举报
回复
#region Internal Helpers
/// <summary>
/// Make sure that the internally kept HDC is released, if it has been obtained from the graphics surface.
/// </summary>
private void ReleaseDC()
{
if( HasDC() )
{
this.graphicsSurface.ReleaseHdc(this.graphicsDC);
this.graphicsDC = IntPtr.Zero;
}
}

/// <summary>
/// Make sure that we has a HDC to use, claim from graphics surface if we have not.
/// </summary>
private void EnsureDC()
{
if( !HasDC() )
{
this.graphicsDC = this.graphicsSurface.GetHdc();
}
}

/// <summary>
/// Check if the HDC has been obtained from the graphics surface.
/// </summary>
/// <returns></returns>
private bool HasDC()
{
return this.graphicsDC != IntPtr.Zero;
}

#endregion

/// <summary>
/// Called just before using the card drawing functions.
/// </summary>
/// <param name="graphicsSurface">Graphics object on which the cards are to be drawn.</param>
public void Begin( Graphics graphicsSurface )
{
this.graphicsSurface = graphicsSurface;
this.graphicsDC = IntPtr.Zero;
}

/// <summary>
/// Called after card drawing has been complete to relase claimed resources.
/// </summary>
public void End()
{
ReleaseDC();
this.graphicsSurface = null;
}

/// <summary>
/// Used to return the last return value from a card's DLL call.
/// </summary>
public bool LastReturnValue
{
get { return lastReturnValue; }
}

#region Drawing Functions
/// <summary>
/// Draws a card in a given mode with specified suit and rank.
/// </summary>
/// <param name="topLeft">Top left location to start drawing the card.</param>
/// <param name="cardIndex">Card index (dependant on mode), use the ToCardIndex</param>
public void DrawCard( Point topLeft, int cardIndex )
{
EnsureDC();
lastReturnValue = NativeMethods.cdtDraw( this.graphicsDC, topLeft.X, topLeft.Y, cardIndex, mode, BorderMask );
}

/// <summary>
/// Draws a card with a given background
/// </summary>
/// <param name="topLeft">Top left location to start drawing the card.</param>
/// <param name="cardBack">Background image index. See CardBack enumeration.</param>
public void DrawCardBack( Point topLeft, CardBack cardBack )
{
EnsureDC();
lastReturnValue = NativeMethods.cdtDraw( this.graphicsDC, topLeft.X, topLeft.Y, (int)cardBack, (int)CardMode.SuitCollated, BorderMask );
}

/// <summary>
/// Draws a frame of an animated background.
/// </summary>
/// <param name="topLeft">Top left location to start drawing the card.</param>
/// <param name="cardBack">Background image index. see CardBack enumeration.</param>
/// <param name="frameNo">Frame of animation to draw.</param>
public void DrawCardBack( Point topLeft, CardBack cardBack, int frameNo )
{
EnsureDC();
lastReturnValue = NativeMethods.cdtAnimate( this.graphicsDC, (int)cardBack, topLeft.X, topLeft.Y, frameNo );
}

/// <summary>
/// Draw a card as if it was selected.
/// </summary>
/// <param name="topLeft">Top-left location to start drawing the card.</param>
/// <param name="cardIndex">Index of card to draw.</param>
public void DrawHighlightedCard( Point topLeft, int cardIndex )
{
EnsureDC();
lastReturnValue = NativeMethods.cdtDraw( this.graphicsDC, topLeft.X, topLeft.Y, cardIndex, (int)CardMode.Highlight, BorderMask );
}

/// <summary>
/// Draw empty card.
/// </summary>
/// <param name="topLeft">Top-left location to start drawing the card.</param>
/// <param name="color">Colour to draw empty card.</param>
public void DrawEmptyCard( Point topLeft, Color color )
{
EnsureDC();
lastReturnValue = NativeMethods.cdtDraw( this.graphicsDC, topLeft.X, topLeft.Y, 1, (int)CardMode.Ghost, (long)color.ToArgb() );
}

/// <summary>
/// Draw an extruded card.
/// </summary>
/// <param name="topLeft">Top-left location to start drawing the card.</param>
/// <param name="bottomRight">Bottom-right location to start drawing card.</param>
/// <param name="cardIndex">Index of card to draw.</param>
public void DrawExtrudedCard( Point topLeft, Point bottomRight, int cardIndex )
{
EnsureDC();
Size d = new Size(bottomRight.X-topLeft.X,bottomRight.Y-topLeft.Y);
lastReturnValue = NativeMethods.cdtDrawExt( this.graphicsDC, topLeft.X, topLeft.Y, d.Width, d.Height, cardIndex, mode, BorderMask );
}

/// <summary>
/// Internal version of the DrawCard routine which renders card to a bitmap.
/// </summary>
/// <param name="offScreenBitmap">Bitmap on which to draw image.</param>
/// <param name="topLeft">Top-left location to start drawing the card.</param>
/// <param name="cardIndex">Index of the card to draw.</param>
private void InternalDrawCard( Bitmap offScreenBitmap, Point topLeft, int cardIndex )
{
// Make sure IDisposable's Dispose method is called even on a Exception.
using( Graphics bitmapGraphics = Graphics.FromImage(offScreenBitmap) )
{
IntPtr deviceContextHandle = IntPtr.Zero;
try
{
// Get a reference to the Win32 HDC
deviceContextHandle = bitmapGraphics.GetHdc();
// Draw card image onto bitmap.
lastReturnValue = NativeMethods.cdtDraw( deviceContextHandle, topLeft.X, topLeft.Y, cardIndex, mode, BorderMask );
}
finally
{
if( deviceContextHandle != IntPtr.Zero )
{
// Release HDC if it was claimed.
bitmapGraphics.ReleaseHdc(deviceContextHandle);
}
}
}
}

/// <summary>
/// Draw rotated a card using 3-point model.
/// </summary>
/// <param name="upperLeft">destination for the upper-left point of the original</param>
/// <param name="upperRight">destination for the upper-right point of the original</param>
/// <param name="lowerLeft">destination for the lower-left of the original</param>
/// <param name="cardIndex">Index of the card to draw.</param>
public void DrawRotatedCard( Point upperLeft, Point upperRight, Point lowerLeft, int cardIndex )
{
// Create bitmap big enough for just one card.
using( Bitmap offScreenBitmap = new Bitmap( DefaultWidth, DefaultHeight ) )
{
// Draw card onto internal bitmap before rotation.
//
this.InternalDrawCard( offScreenBitmap, new Point(0,0), cardIndex );

// Must release HDC before drawing using the .NET Graphics object.
ReleaseDC();

// Use destination point to render image
Point[] destinationPoints = { upperLeft, upperRight, lowerLeft };
//
// Draw image onto the graphic surface using destination point as a guide.
//
graphicsSurface.DrawImage( offScreenBitmap, destinationPoints );
}
}

pupo 2005-05-16
  • 打赏
  • 举报
回复
/*
* cardsdll wrapper class
* Downloaded from www.publicjoe.co.uk
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the author(s) be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely.
*/

using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Cards
{
/// <summary>
///
/// </summary>
public enum CardSuit : int
{
Clubs = 0,
Diamond = 1,
Hearts = 2,
Spades = 3
}

/// <summary>
///
/// </summary>
public enum CardRank : int
{
Ace = 0,
Two = 1,
Three = 2,
Four = 3,
Five = 4,
Six = 5,
Seven = 6,
Eight = 7,
Nine = 8,
Ten = 9,
Jack = 10,
Queen = 11,
King = 12
}

/// <summary>
///
/// </summary>
public enum CardBack : int
{
Crosshatch = 53, /* XP = CROSSHATCH */
Weave1 = 54, /* XP = SKY */
Weave2 = 55, /* XP = MINERAL */
Robot = 56, /* XP = FISH */
Flowers = 57, /* XP = FROG */
Vine1 = 58, /* XP = MOONFLOWER */
Vine2 = 59, /* XP = ISLAND */
Fish1 = 60, /* XP = SQUARES */
Fish2 = 61, /* XP = MAGENTA */
Shells = 62, /* XP = SANDDUNES */
Castle = 63, /* XP = SPACE */
Island = 64, /* XP = LINES */
CardHand = 65, /* XP = TOYCARS */
Unused = 66, /* XP = UNUSED */
X = 67, /* XP = THE_X */
O = 68 /* XP = THE_0 */
}

/// <summary>
/// Mode
/// </summary>
public enum CardMode : int
{
RankCollated = 0, // card number starts from 0
SuitCollated = 1, // card number offset by 1 for blank card.

Highlight = 2, /* Same as FaceUp except drawn inverted */
Ghost = 3, /* Draw a ghost card -- for ace piles */
Remove = 4, /* draw background specified by color */
InvisibleGhost = 5, /* ? */
DeckX = 6, /* Draw X */
DeckO = 7 /* Draw O */
}

/// <summary>
/// Card
/// </summary>
public class Card : IDisposable
{
// Internal constants e.g. Magic Numbers.

/// <summary>
/// Default width used by card's DLL.
/// </summary>
internal const int DefaultWidth = 71;
/// <summary>
/// Default height used by card's DLL.
/// </summary>
internal const int DefaultHeight = 97;
/// <summary>
/// Default border mask value.
/// </summary>
internal const int BorderMask = 0x00FFFFFF;

/// <summary>
/// .NET Graphics surface used for drawing.
/// </summary>
private Graphics graphicsSurface;

/// <summary>
/// Win32 HDC surface use for Win32 drawing.
/// </summary>
private IntPtr graphicsDC;

/// <summary>
/// Last value from the card's DLL.
/// </summary>
private bool lastReturnValue;

/// <summary>
/// Is this instance current being disposed?
/// </summary>
private bool disposed;



/// <summary>
/// Current Mode to draw Card
/// </summary>
private static int mode;
public int Mode
{
get { return mode; }
set { mode = value; }
}

/// <summary>
/// Constructor which initialise access to the card's DLL.
/// </summary>
public Card()
{
cardWidth = DefaultWidth;
cardHeight = DefaultHeight;
mode = (int)CardMode.RankCollated;
NativeMethods.cdtInit(ref cardWidth, ref cardHeight);
}

#region Implementation: IDisposable & Finaliser
/// <summary>
/// Instance finaliser for the class for unmanaged resources.
/// </summary>
~Card()
{
Dispose(false);
}

/// <summary>
/// Called by caller's when the instance is finished with.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Internal dispose function which release managed and unmanaged resources.
/// </summary>
/// <param name="disposing">true iff managed and unmanaged are being disposed of else unmanaged only.</param>
private void Dispose( bool disposing )
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false, only the following code is executed.
if( this.graphicsSurface != null && this.graphicsDC != IntPtr.Zero)
{
this.graphicsSurface.ReleaseHdc( this.graphicsDC );
this.graphicsDC = IntPtr.Zero;
}
NativeMethods.cdtTerm();

// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
if( graphicsSurface != null )
{
graphicsSurface.Dispose();
}
}
}
this.disposed = true;
}
#endregion

fankun 2005-05-15
  • 打赏
  • 举报
回复
哎,自己顶吧

16,553

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧