13x13 Grid Poker Hand Chart Windows窗体用户控件(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/a-13x13-grid-poker-hand-chart-windows-forms-user-c-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 10 分钟阅读 - 4552 个词 阅读量 013x13 Grid Poker Hand Chart Windows窗体用户控件(译文)
原文地址:https://www.codeproject.com/Articles/118658/A-13x13-Grid-Poker-Hand-Chart-Windows-Forms-User-C
原文作者:Gagey1971
译文由本站 robot-v1.0 翻译
前言
A simple .NET control to display the ‘standard’ 13x13 grid for two card poker hands.
一个简单的.NET控件,用于显示两个纸牌扑克手的"标准" 13x13网格.
介绍(Introduction)
我玩扑克和编写家庭酿造工具已有一段时间了,最近我开始为朋友写一些游戏,主要是教育和分析.我很快发现需要一个控件,该控件可以让我在标准13x13卡片图表中显示有关特定手牌的信息.(I have been playing poker and writing home brew tools for a while, and recently started writing some for friends, mostly educational and analytical. I soon found there was need for a control that would allow me to display information about specific hands, in the standard 13x13 card chart.) 而且由于这实际上很容易编写代码((And since this is actually pretty easy to code ()许多(much)比我最初想象的要容易),我会用它(easier than I first thought), and I will use it)很多(lots),编写通用的手形图表很有意义,我可以做任何想做的事.在我看来,其他人也可能会发现这种控件的用途,因此在这里我介绍一下.(, it made sense to code a generic hand chart that I could do pretty much whatever I wanted to. It occurred to me that others might find uses for such a control also, so here I present it.) 它是用C#编写的标准.NET Windows窗体控件.我发现在源代码级别使用它非常容易,并且在下面进行了介绍(基本上是剪切并粘贴到您的项目中).但是由于它没有添加到工具箱中(我对.NET用户控件没有太多的经验;如果有办法,我很想知道),因此需要手动将几行添加到所需的表单中要显示的图表.我还提供了仅包含预编译控件的类库DLL.(It is a standard .NET Windows Forms control, written in C#. I find using it at the source level is extremely easy, and described below (basically, cut and paste into your project). But as it is not added to the toolbox (I don’t have that much experience with .NET user controls; if there is a way, I would love to know), a few lines need to be added manually to the form you want the chart to appear in. I have also provided a Class Library DLL containing only the control, precompiled.) 这是(This is)不(not)旨在成为控件开发的最佳实践的一个例子,只是共享的有用控件.(meant to be an example of best-practices for control development, just a useful control to share.)
背景(Background)
不同的Hold’em起手牌的属性可以轻松紧凑地显示在13x13的网格上,例如在此控件中实现的网格.(Properties of different Hold’em starting hands are easily and compactly displayed on a 13x13 grid, such as implemented in this control.)
顶部图像显示了在设计时绘制的空白图表.底部的图表显示了图表,每个口袋对都涂有金色,并显示X.(The top image shows a blank chart, as drawn at design time; the bottom one shows the chart with each pocket pair coloured Gold, with an X displayed.) 大多数扑克玩家都熟悉这些网格.有关特定用法的示例,请参见HU Nash平衡推/折图表(Most poker players are familiar with these grids; for an example of specific usage, see the HU Nash Equilibrium Push/Fold charts) 这里(here) .(.) 对角线上方的所有像元代表适合的手,下方的那些像元不适合.(All cells above the diagonal represent suited hands, and those below unsuited.)
使用代码(Using the Code)
在工具箱中没有控件的情况下,向表单(或其他容器)添加图表是一个简单的三步过程!(Without the control in the Toolbox, adding a chart to a form (or other container) is a simple three step process!)
-
创建一个Windows窗体应用程序.(Create a Windows Forms application.)
-
引用DLL,(Reference the DLL,)要么(or)复制并粘贴两个文件(Copy and paste the two files)**PokerHandChart.cs(PokerHandChart.cs)**和(and)**PokerHandChart.Designer.cs(PokerHandChart.Designer.cs)**进入您的项目(在解决方案资源管理器中).(into your project (in the Solution Explorer).)
- 如果您复制代码,则可能需要添加对(If you copy the code, you may need to add a reference to)
System.Drawing
.(.)
- 如果您复制代码,则可能需要添加对(If you copy the code, you may need to add a reference to)
-
将以下代码添加到表单的(Add the following code to your form’s)**.Designer.cs(.Designer.cs)**文件-是的,有些地方需要标记为" Windows Form Designer生成的代码",通常这不是一个好主意,但这是将控件放置在窗体上的唯一方法-很好,无需进行所有安装,等等(我是在VS 2008 Express中写的)-它不支持用户控制项目,但是这种解决方案很简单.因此,这是代码:(file - Yes, some need to go in the region marked ‘Windows Form Designer generated code’, which is generally not a good idea, but it is the only way to place the control on the form - well, without all the installation, etc. (I wrote this in VS 2008 Express) - which doesn’t support User Control projects, but this solution is trivial. So, here is the code:) 声明一个类型的成员变量(Declare a member variable of type)
PokerHandChart
在班级上,将其余的放在(at the class level, and place the remainder in the)InitializeComponent()
方法,在现有代码下:(method, under the existing code:)
private PokerHandChartControl.PokerHandChart chart = null;
this.SuspendLayout();
// 1st and last line may already be there,
// so just place next 4 lines between
this.chart = new PokerHandChartControl.PokerHandChart();
this.chart.Location = new System.Drawing.Point(10, 120);
this.chart.Size = new System.Drawing.Size(200, 200); // (200, 100) wouldn't matter
this.Controls.Add(this.chart);
this.ResumeLayout(false);
注意(Note):大小的确切尺寸并不重要,因为控件会自动使其变成正方形-您现在可以在"表单设计器"中移动/调整控件的大小.(: The exact dimensions of size aren’t important as the control automatically makes itself into a square - you can now move/resize the control in the Form Designer.)
另外,添加此代码将(Also, adding this code will)不(not)将来会干扰添加到表单上的其他"标准"控件.您输入的密码(interfere with adding other ‘standard’ controls placed on the form in the future. This code you entered)将(will)在窗体上调整控件大小/移动时更改(并添加到)-这仅仅是在窗体上获取实例.控件会绘制一个空的13x13网格,每行/每行都标有一张卡片…完成此操作后,请切换至"设计"标签,以添加表格的形式(change (and be added to) when you resize/move the control on the form - this is just to get an instance on the form. The control draws an empty 13x13 grid with each row/col labelled with a card… Once this is done, switch to the Design tab for whichever form you just added the) PokerHandChart
到,您将看到一个空图表.现在,您可以移动图表控件并调整其大小,并注意它始终保持正方形.(to, and you will see an empty chart. You can now move and resize the chart control, and notice it always stays a square.)
注意(Note):使用图表大约为(: Using the chart is about as)简单(easy)可能是这样.(as it possibly could be.)
网格中的每个单元格都公开属性,以允许控制单元格的显示.每个单元格都有前景色和背景色,(Each cell in the grid exposes properties to allow the display of the cell to be controlled. Each cell has a foreground and background colour, and ‘) DisplayValue
' (一个简单的(’ (a simple) string
-但它应该适合单元格!),您也可以更改((- but it should fit within the cell!) which you can also change the font of ()注意(Note),仅列出名称,而不是此版本中的大小,也许以后再说;-)此外,每个单元格都有一个"(, name only, not size in this version, maybe later ;-)). Also, each cell has a ‘) Selected
标记,用于为您的应用程序选择手(即范围)-至少将用户或控件标记为已选择手.列出卡的标题还具有可配置的颜色和字体(同样,不是字体大小).(’ tag, for use in selecting hands for your application (i.e., a Range) - at least flagging hands as having been selected, by the user or the control. The headers listing the cards also have a configurable colour and font (again, not font size).)
标头行/列和每个单元格的字体大小是单元格大小的固定分数,因此将随图表的整体大小缩放.(Font sizes for both header row/column and each cell is a fixed fraction of the cell size, and as such will scale with the overall size of the chart.)
每个单元格值在图表中水平和垂直居中显示.(Each cell value is displayed centered both horizontally and vertically in the chart.)
通过以下方式访问这些属性(Access to these properties is via a) GridCell
公开属性的类.(class exposing the properties.)
我觉得使此图表控件特别易于使用的一个"功能"是每个单元格的索引器样式访问器(仅获取).共有三种不同的索引器方法.(One ‘feature’ I feel makes this chart control especially easy to work with is the indexer style accessor (get only) for each cell. There are three different indexer methods available.)
最简单的是使用(The simplest is to use a) string
包含手,因此,例如,要获取代表AK的单元格,我们可以使用(containing the hand, so for example, to get the cell representing AKs, we could use) this["AKs"]
-可能更简单!好吧,通常,我们要循环访问许多单元,这在第二个索引器非常有用的地方.它需要三个参数,即两个卡(如(- what could be easier! Well, often, we want to access many cells, often in a loop, and this is where the second indexer is very useful. It takes three parameters, being the two cards (as) char
s)和一个布尔值以指示适合性.同样,要访问AK,我们将使用(s) and a boolean value to indicate suitedness. So again, to access AKs, we would use) this['A', 'K', true]
.显然,(. Obviously, the) bool
口袋对将被忽略.另外,编码(is ignored for pocket pairs. Also, coding) this['K', 'A', true]
将返回非常相同(will return the very same) GridCell
像以前一样对象,因此该类使手"正常化".因此,对于本地访问许多单元格来说,(object as before, so the class ‘normalizes’ the hands. So for specially local access to many cells, a) this
访问器与一个(或两个)循环组合是最简单的方法.实际上,每个口袋对和合适的手提单元都可以通过几行代码进行访问(并且数组/枚举对此具有"排名"帮助).(accessor combined with a loop (or two) is the easiest way. In fact, every pocket pair and suited hand cell can be accessed in a few lines of code (and the array/enumeration ‘ranks’ help with this).)
foreach (char r1 in Hand.ranks)
foreach (char r2 in Hands.ranks)
if ( Hands.indexFor(r1) >= Hands.indexFor(r2) ) {
// So AA, AK but not KA,
//even though that would work it would
//visit most cells more than once, wasteful...
GridCell c = chart[r1, r2, suited];
c.DisplayValue = "11.5";
c.Foreground = Brushes.Blue;
c.CellFont = "Arial";
}
(使单元格显示为" 11.5",背景为蓝色.)((Make a cell display ‘11.5’ with a blue background.) [) Hands.indexFor(card)
是一种允许按等级比较卡片的方法.](is a method to allow comparison of cards by rank.])
最后,可以通过标准数字坐标访问单元,其中AA为(0,0),AK为(1,0),等等.我还没用过.(And finally, the cells can be accessed by standard numerical coordinates, with AA being (0,0), AKs (1, 0), etc. This is there for (semi)completeness; I haven’t used it yet.)
每个单元格都是在类中自动创建和维护的.开发人员所需要做的就是为它提供显示数据,例如颜色,以及一些文本或数字以放置在单元格中.(Each cell is created and maintained within the class automatically. All the developer needs to do is provide it with display data like colours, and some text or number to place in a cell.)
该控件还导出一个Click样式事件,该事件在用户单击一个单元格时触发.实际上(The control also exports a Click style event, fired when the user clicks on one of the cells. The actual) GridCell
对象将传递给任何已订阅的事件侦听器.(object is passed to any subscribed event listeners.)
chart.HandClickedEvent += HandClicked;
protected void HandClicked(object sender, GridCell hit_cell) { ... }
因此,该控件可以用于显示静态数据,也可以用于允许用户选择并选择指针/范围.(So the control can either be used to display static data, or be used to allow the user to select and choose hands/ranges.) 例如,对于所有口袋对和所有百老汇,都有一些枚举使选择这些组非常容易:(There are a few enumerations for example, for all pocket pairs, and all broadway that make selecting these groups very easy:)
foreach (string s in HandEnumerations.PocketPairs)
GridCell c = chart[s]; // Do something to each of these cells...
注意(Note):对图表进行任何更改后,"(: After any changes are made to the chart, ‘) UPDATE()
必须调用-在图表本身或包含的表单/容器上!(’ must be invoked - either on the chart itself or the containing form/container!)
唯一接受参数的枚举工厂方法是(The only enumeration factory methods which accept a parameter are the) SuitedConnector
/(/) SuitedGapper
,您可以在其中为手牌收集(如所有SC> 4?)和间距的下限提供下限.(, where you provide a lower bound for the hand collection (as in all SCs > 4?) and the distance of the gap.)
还可以使用枚举器和某些实用程序类(即,(Each cell can also be accessed sequentially using the enumerator, and some utility classes (i.e.,) HandEnumerations
)是为了方便起见.() are provided for convenience.)
请享用!(Enjoy!)
历史(History)
- 版本0.1.0-还没有,但是我计划扩展一些"帮助"类并添加我想到的所有功能;-)(Version 0.1.0 - None yet, but I plan to extend some of the ‘helper’ classes and add any features I think of ;-))
我想看看在对这个控件进行过多努力(不是我需要的)之前是否对此想法有很多回应,但是如果有足够的兴趣,我可以做很多事情(一些重构/重命名/扩展)显示…(例如,"(I wanted to see if there was much of a response to this idea before putting too much effort (other than what I require) into polishing this control, but there is plenty I can do (some refactoring/renaming/extending) if enough interest is shown… (for example, a ‘)
Clear()
‘方法现在显然不见了).因此,请回顾改进!(’ method is obviously missing now). So do look back for improvements!) 也许您可以将功能请求保留为注释?(Perhaps you could leave feature requests as comments?)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# .NET Windows user-controls Gridview 新闻 翻译