C#/C ++ CLI微型国际象棋(Huo Chess)(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/c-c-cli-micro-chess-huo-chess-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 48 分钟阅读 - 23721 个词 阅读量 0C#/C ++ CLI微型国际象棋(Huo Chess)(译文)
原文地址:https://www.codeproject.com/Articles/20736/C-C-CLI-Micro-Chess-Huo-Chess
原文作者:Palavos
译文由本站 robot-v1.0 翻译
前言
An article about Huo Chess, a chess program in C++ and C# that attempts to be smaller in size than the Commodore-era Microchess
有关Huo Chess(C ++和C#中的国际象棋程序)的一篇文章,其尺寸试图小于Commodore时代的Microchess
- 下载Huo_Chess_v0.991_all_editions(VS2017)(Download Huo_Chess_v0.991_all_editions (VS2017))
- 下载Huo Chess v0.990-所有版本(VS2015/2017)(Download Huo Chess v0.990 - All editions (VS2015/2017))
- 下载Huo Chess v0.980-所有版本(VS2015)(Download Huo Chess v0.980 - All editions (VS2015))
- 下载Huo Chess v0.980-Windows 8 Edition(测试版)(Download Huo Chess v0.980 - Windows 8 edition (beta))
- 下载Huo Chess v0.971-所有版本(VS2013/2015)(Download Huo Chess v0.971 - All editions (VS2013/ 2015))
- 下载Huo Chess 0.961 C#(VS2012)(Download Huo Chess 0.961 C# (VS2012))
- 使用GUI下载Huo Chess 0.961 C#(VS2012)(Download Huo Chess 0.961 C# with GUI (VS2012))
- 下载Huo Chess 0.95 C#(VS2012)-57 KB(Download Huo Chess 0.95 C# (VS2012) - 57 KB)
- 下载带有GUI的Huo Chess 0.95 C#(VS2012)-179 KB(Download Huo Chess 0.95 C# with GUI (VS2012) - 179 KB)
- 下载Huo Chess 0.93版本(VS 2010)(Download Huo Chess 0.93 editions (VS 2010))
- 下载Huo Chess 0.82版本(VS 2008)(Download Huo Chess 0.82 editions (VS 2008))
- 下载Huo Chess 0.722及更低版本(Download Huo Chess 0.722 and older versions)
- 下载Huo Chess Opening Book Editor 0.1(Download Huo Chess Opening Book Editor 0.1)
- 下载Opening_Book-1.24 KB(Download Opening_Book - 1.24 KB)
火棋(GUI版)(Huo Chess (GUI edition))
新闻(News)
2019-02-18:(2019-02-18:)Huo Chess Java版本v0.991已发布.参考主要(Huo Chess v0.991 Java edition was released. Refer to the main) 象棋页面(Huo Chess page) 在(at the) 和谐哲学(Harmonia Philosophica) 有关更多信息的门户.(portal for more on that.) 2019-02-12:(2019-02-12:)Huo Chess v0.991发布.算法中的许多改进.增加了打开功能.该版本还包括一个Developers Edition,其中包含思考过程的详细日志.(Huo Chess v0.991 is released. Many improvements in the algorithm. Added opening capability. The release includes also a Developers Edition with detailed logs of the thinking process.) 2018-08-01(2018-08-01:)Huo Chess v0.990开发完成.新版本处理代码中的各种问题,并在国际象棋引擎中具有更新的逻辑.(Huo Chess v0.990 development is completed. The new version deals with various issues in the code and features an updated logic in the chess engine.) 2015-09-04:(2015-09-04:)Huo Chess Windows 8版本已上载.该版本具有最少的用户交互功能.较新的版本即将推出…(Huo Chess Windows 8 version was uploaded. The version has minimal user interaction capabilities. Newer versions will soon follow…) 2015-09-04:(2015-09-04:)Huo Chess v0.980已更新:已上载有关CheckMove的修复程序,该修复程序有错误,由于此错误,计算机才能进行非法移动.由于此修补程序是在非常接近新版本发布的状态下上传的,因此版本号没有更改.感谢Peter Bateman指出了错误! (这被称为回归测试,但经常被忽略…)(Huo Chess v0.980 was updated: A hotfix was uploaded regarding CheckMove which had a bug due to which the computer made illegal moves. The version number has not changed since the hotfix was uploaded very close to the release of the new version. Thanks to Peter Bateman for pointing the bug out! (it’s called regression testing and too often it is neglected…))
概要(Summary)
Huo Chess是一个开源的国际象棋程序(Huo Chess is an open source chess program of just)45(45)KB(KB)大小(此大小是指没有GUI的0.991 C#控制台应用程序版本).该计划的目标是多重的:要实现卓越的代码结构和算法效率,以创建最小的象棋程序,该象棋程序可以像棋一样发挥作用,(最重要的)是为想学习如何开发棋类的人提供教育参考.国际象棋程序.(in size (this size refers to the 0.991 C# console application edition without GUI). The goal of the program is multifold: To achieve excellence in code structure and algorithm efficiency so as to create the smallest chess program which plays decent chess and (most importantly) to serve as an educational reference for people who want to learn how to develop a chess program.) 关于该计划的教育目的,必须注意以下几点:(Regarding the educational purpose of the program, the following points must be noted:)
-
来源(The source)代码被严重注释(code is heavily commented)使读者了解自己所见.变量具有全名(例如,StartingColumn,ThinkingDepth,MovingPiece),并且没有应用快捷方式来模糊代码.代码中的所有内容都是(so that the reader understands what he sees. The variables have full names (e.g. StartingColumn, ThinkingDepth, MovingPiece) and there are no shortcuts applied to obscure the code. Everything in the code is)干净漂亮,每个人都容易理解(clean and nice so that it easy for everyone to understand)思维过程(the thinking process)
-
我分析了(I analyzed and)记录思考过程(documented the thinking process)本文中有关计算机的内容,以使每个人都很清楚.积分(of the computer in this article so as to make it clear for everyone. Points for)未来可能的改进(possible future improvements)在下面也进行了说明,以便每个人都可以为将来的版本做出贡献.注释中提交了对控制台应用程序的小型" GUI"的重要贡献,现在它是一个单独的版本(包含在与创建它的人有关的分发文件中).(are also noted below so that everyone can contribute to future versions. An important contribution for a small-size “GUI” for the console application was submitted in the comments and is now a separate edition (included in the files distributed with reference to the guy who created it of course).)
-
该程序包含一组(The program contains a set of)各种日志(various logs)易于激活(只需在程序的#Log或#WriteLog区域中取消注释相对行).这些日志生成文本文件,这些文件详细显示了象棋引擎算法的工作方式. (只要您有时间和耐心阅读它们,它们的确是冗长而详尽的)(which are easy to activate (simply uncomment the relative lines in the #Log or #WriteLog areas in the program). These logs generate text files which show how the chess engine algorithm works in detail. (provided that you have the time and patience to read them, they are truly long and detailed))
-
一系列的 “(A series of “)如何开发国际象棋程序(How to develop a chess program)“已作为该项目的一部分创建.该系列旨在展示如何为经验不足的用户提供逐步指导的国际象棋程序(如标题所示.).您可以从” Hello world"应用程序中学习程序设计!深入学习,并在一定时间里学会游泳!(不用担心,最糟糕的事情是没有编译的应用程序).找到第一课(” has been created as part of the project. The series intends to show how to develop a chess program (as the title implies…) with step-by-step guidance for the inexperienced user. There is no point in trying to start from “Hello world” applications in order to learn programming! Go in the deep and in the time you will learn how to swim! (no worries, the worst thing that can happen is to have an application that does not compile). You can find the first lesson “) 如何为假人开发国际象棋程序(How to develop a chess program for dummies) 在Harmonia Philosophica门户网站上也可以找到.有关如何在一天之内用Java编写演示象棋程序的非常简短的教程也可以找到.(” at Harmonia Philosophica portal. A very short tutorial on how to program a demo chess program in one day in Java can also be found) 这里(here) .(.) 该程序是使用Microsoft Visual Studio 2017开发的.(以前的版本在Visual Studio 2013和2015中创建).当前存在四个版本:(The program was developed with Microsoft Visual Studio 2017. (previous versions were created in Visual Studio 2013 and 2015). Four editions currently exist:)
-
具有GUI的Huo Chess 0.991(Huo Chess 0.991 with GUI)
-
火棋0.991 cs(Huo Chess 0.991 cs)
-
带有图形的Huo Chess 0.991 CS(Huo Chess 0.991 cs with graphics)
-
Huo Chess 0.991开发人员版本(Huo Chess 0.991 Developers version) 参考主要(Refer to the main) 象棋页面(Huo Chess page) 在(at the) 和谐哲学(Harmonia Philosophica) 该程序最新动态的门户.(portal for the program’s latest developments.) 0.991版亮点(Version 0.991 highlights) 新版本的Huo Chess(v0.991)体积较小(与以前的版本一样),并且功能强大.带有Windows Forms用户界面的正式版大小为77 KB,带有棋盘用户界面(UI)版的控制台应用程序为48 KB,没有棋盘UI版本的控制台应用程序为45 KB.在当前版本(Huo Chess v0.990 – C#)中,最多可以想到3个半动作Kakos-Minimax版,并且有开本的能力.(The new version of Huo Chess (v0.991) is small in size (as all the previous ones) and much more capable. The official edition with Windows Forms user interface is 77 KB in size, the Console application with a chessboard User Interface (UI) edition is 48 KB and the Console application with no chessboard UI edition is 45 KB in size. In its current version (Huo Chess v0.990 – C#) can think up to 3 half-moves [Kakos-Minimax edition] (e.g. 2 half-moves for white and 1 half-move for black pieces when computer plays with White) and has an opening book capability.) MinMax思维算法的问题已修复,现在计算机可以在每种情况下进行逻辑移动(至少在它认为的3个半移动深度内).添加了深度为5个半动作的思考功能,但未激活(必须将Thinking_Depth更改为4才能发生;请注意,思考从动作0开始).再次添加了打开书功能(此功能已存在,但在0.980版中已删除)(必须在"打开书"文件夹中有位置才能使用它).(Issues with the MinMax thinking algorithm are fixed and now the computer makes logical moves in every circumstance (at least for the depth of 3 half-moves in which it thinks). Capability of thinking at depth of 5 half-moves is added but not activated (must change Thinking_Depth to 4 for that to happen; note that thinking starts from move 0). Opening book capability has been added again (this capability existed but was removed in version 0.980) (must have positions in the “Opening Book” folder to use it).) 除上述内容外,还创建了一个Developers Edition,其中包括用于调试(用于教学目的)的思维机制的分析日志.可以轻松激活或停用日志. (注意:请记住检查日志的大小并在需要时将其删除!它们的大小可能会显着增加).此版本还朝着向用户界面显示计算机所考虑的变体迈出了一步.(Additional to the above, a Developers Edition has been created, which includes analytic logs of the thinking mechanism for debugging (for teaching purposes). The logs can be easily activated or deactivated. (Attention: Remember to check the size of the logs and delete them when needed! They can grow in size significantly) This edition also takes a small step towards showing the variant which the computer thinks to the user interface.) 打开书编辑器是单独分发的(请参见下载列表).与编辑器一起,分发文件中还包含一些示例打开书位置的库.(The Opening Book editor is distributed separately (see the list of Downloads). Along with the editor, a library of some sample opening book positions is also included in the distribution files.) Huo Chess下象棋,并成功绘制了Microchess,这是Commodore时代的第一批Microchess(请参见下面的Huo Chess Games存档).它的算法基于蛮力分析,同时利用了MiniMax算法.它可以用于研究国际象棋程序的基础逻辑或作为自己的国际象棋程序的基础.正如我已经提到的,源代码是(Huo Chess plays decent chess and has managed to draw Microchess, the first microchess from the Commodore era (see the Huo Chess Games Archive below). Its algorithm is based on brute-force analysis while utilizing the MiniMax algorithm. It can be used to study the underlying logic of a chess program or as a basis for your own chess program. As I already mentioned, the source code is)用英语进行大量评论并易于定制(heavily commented in English and easily customizable),因为所有变量都有不同且易于理解的名称.源代码正在不断改进,并根据<代码项目开放许可>进行分发.在本文中,我还将分析其编程逻辑,重点是计算机"思维"内部的一般流程,从最初对棋盘的扫描到最终决定下棋的动作.欢迎任何意见!(, since all variables have distinct and understandable names. The source code is continually improving and is distributed under The Code Project Open License. In this article, I also analyze its programming logic, with emphasis on the general flow inside the computer’s “mind,” from the initial scanning of the chessboard up to the final decision on which move to play. Any comments are welcome!)
介绍(Introduction)
编程时最重要的是什么?是程序设计吗?是?如果为"是”,那么为什么今天的每个程序都大于123876 GB,并且需要120987 MB的RAM才能运行?为什么每个新项目和程序(默认情况下)都比以前的版本大而速度慢?答案很简单:由于计算机速度的提高,实际上没有人关心优化代码结构和软件设计,因为新处理器肯定会使最终用户的程序看起来不错.在准将计算机时代,内存是相当有限的.这就是为什么程序员试图使代码小而高效的原因.这样就产生了Microchess,这是一种非常有效的小型国际象棋程序(如名称" micro"(在希腊语中意为"小"的意思)),它能够以当时计算机中可用的几KB大小下棋.(What is most important when you program? Is it the program design? Yes? If “yes,” then why is it that every program today is bigger than 123876 GB and requires 120987 MB of RAM to run? Why is every new project and program — by default — larger in size and slower in speed than the previous version? The answer is simple: because of the increasing speed of computers, no one actually cares about optimizing the code structure and the software design, since the new processor will definitely make the program look fine for the end user. During the time of Commodore computers, memory was rather limited. That is why programmers tried to make the code small and efficient. This resulted in Microchess, which was a very efficient, small (as the name “micro,” which means “small” in Greek, implies) chess program that was able to play chess in the few KB available in computers of that time.)
我的成就(What I Accomplished)
在上述驱动下,我开始在CLI C ++ v8.0中开发程序(使用Visual Studio 2008 Express Edition,而现在在Visual Studio 2015/2017中开发了最新版本)来下棋是为了减小体积(Micro)chess,甚至小于Commodore时代的Microchess.现在,还存在一种使用C#编程语言的版本和一种具有图形用户界面的版本(您可以在此处找到它们进行下载).我出于个人原因将其命名为" Huo Chess".该程序下象棋,但不幸的是,如果与Garry Kasparov一起下棋,可能会失败.目前大小(Driven by the above, I started developing a program in CLI C++ v8.0 (with Visual Studio 2008 Express Edition, while now the latest edition is developed in Visual Studio 2015/2017) to play chess with the intention of making a small in size (Micro)chess, even smaller than the Commodore-era Microchess. Now, one version in C# programming language and one version with Graphical User Interface also exist (you can find them here for downloading). I named it “Huo Chess” for personal reasons. The program plays decent chess, but unfortunately will probably lose if it plays with Garry Kasparov. Its size is currently)45 KB(45 KB)(在C#控制台版本v0.991中,这是对以前的v0.961版本(55 KB的很大改进!)),而Microchess在C语言中的相应仿真为56 KB.((in the C# console edition v0.991, which is a big improvement from the previous v0.961 version which was 55 KB!), while the respective emulation of Microchess in C is 56 KB.)但是,必须注意的是,用纯汇编语言编写的原始Microchess大约为1 KB,这是我相信没有人能比拟的!(However, it must be noted that the original Microchess, written in pure Assembly, was about 1 KB…something that I believe no one will ever match!)在与Microchess的比赛中,0.4版成功绘制了Microchess(请参阅以下Huo Chess Games Archive部分).我没有时间让Huo Chess v0.991再次与Microchess对抗,但是我有一天会…(In matches against Microchess, version 0.4 has managed to draw Microchess (see below the section of Huo Chess Games Archive). I did not have the time to put Huo Chess v0.991 to play against Microchess again but I will some day…)
如何自定义-优化程序(How to Customize - Optimize the Program)
该程序有一个(The program has an)开本能力(opening book capability),这意味着任何人都可以使用Huo Opening Book Editor通过在各自的文件夹Huo Chess Opening Book(应该与可执行文件位于同一目录)中添加自己的打开动作数据来优化程序.(, which means that anyone can optimize the program by adding his/her own opening moves data in the respective folder Huo Chess Opening Book (which should be in the same directory with the executable) with Huo Opening Book Editor.)
您还可以添加更多(You can also add more)思维深度(thinking depth)通过添加新功能(capability, by adding new) AnalyzeMove
函数(如针对每个新的思维深度层的Analyze_Move_2_ComputerMove,Analyze_Move_4_ComputerMove等),并针对(functions (like Analyze_Move_2_ComputerMove, Analyze_Move_4_ComputerMove, etc. for each new thinking depth layer) and make the necessary adjustments to the)过滤器(filters)应用于分析的动作(需要这些来提高程序的速度–请参阅(applied to the moves analyzed (these are needed to increase the speed of the program – see) FindAttackers / FindDefenders
).().)
您还可以通过更改以下选项来优化Huo Chess的思维方式(You can also optimize the way Huo Chess thinks by changing the) CountScore
功能(以及计算机(或其人类对手)的使用方式)(function and the way the computer (or its human opponent))珍惜碎片(values the pieces)或者(or the)棋盘位置(chessboard position).例如,如果您在(. For example, if you change the score of the Queen in the) CountScore
从功能(function from) 9
至(to) 12
,那么HY将积极进攻对手的女王/王后,同时更加努力地捍卫自己的女王/王后.例如,您还可以对带有开口的菜鸟杆进行评分,以使其获得更高的评分,从而使计算机可以更好地利用它的菜鸟杆并尝试接管它们.(, then the HY will play aggressively to attack the opponent’s queen and at the same time try harder to defend its own queen. You can also — for example — give a high scoring to the existence of an opening column with a rook controlling it, so as to make the computer play more with its rooks and try to take over columns with them.)
任何反馈都欢迎使用"开幕书"或(Any FEEDBACK is WELCOME with better configurations of the Opening Book or the) CountScore
功能实际上是系统的心脏!(functions which are actually the heart of the system!)
0.991版的当前局限性和改进思路(Current limitations of version 0.991 and thoughts for improvements)
当前版本(v0.991)的思考深度设置为3个半动作(这对应于代码中的Thinking_Depth =2;请记住,思维始于动作0).这是因为完全爆发的MiniMax算法非常占用内存,而且非常耗时.您可以将思考深度设置为4(Thinking_Depth变量需要一个偶数,因为计算机分析的目的是在计算机转弯时"结束"),以使计算机思考的深度为5个半角.那么程序将运行慢得多.我将在下一个版本中优化代码.(The current version (v0.991) is set to a thinking depth of 3 half-moves (this corresponds to Thinking_Depth = 2 in the code; remember that thinking starts with move 0). This is because the full blown MiniMax algorithm is very memory intensive and time consuming. You can set the thinking depth to 4 (an even number is required for the Thinking_Depth variable because the analysis of the computer is designed to “end” at the computer’s turn) to make the computer think at a depth of 5 half-moves, but then the program will run much slower. I will optimize the code for that in a next version.) 注意:(Note:)在以前的版本(v0.961)中,当您将ThinkingDepth变量设置为4时,程序崩溃,导致内存不足.发生这种情况的原因是数组的大小限制保留了每个节点的分数(即计算机分析的每个可能位置) ).自0.971版以来,此问题已得到解决:我为每个级别的思维都创建了不同的数组,以便更快并克服了数组大小的限制.解决此问题的另一种方法是将过滤器应用于算法,以使它不会花费时间和资源来分析每一个可能的动作(In the previous version (v0.961) the program crashed Out of Memory when you set the ThinkingDepth variable to 4. This happened because of the size limits of the array which holded the scores of each node (i.e. of each possible position the computer analyzes). This has been resolved since version 0.971: I created different arrays for every level of thinking so that it is faster and overcome the array-size limitations. Another way out of this is to apply filters to the algorithm so that it does not spend time and resources analyzing every posible move)[可能的未来改进]([possible future improvement]).所有这些都是对下一个即将发布的版本的想法…(. All these are thoughts for the next upcoming version…)
下一个版本(Next versions)
下一个版本的Huo Chess已经存在潜在的改进,可以在下面找到:(There is already a list of potential improvements for the next version of Huo Chess, which can be found below:)
- 通过改善"外围"功能(例如CheckForBlackMate,ElegxosNomimotitas等)来减小尺寸.(Reduce size by improving ‘peripheral’ functions (like CheckForBlackMate, ElegxosNomimotitas et cetera).)
- 通过考虑每个分支的平均分数来提高MiniMax算法的效率. (代码已经到位,但已注释掉)(Increase efficiency of MiniMax algorithm, by taking into account the average score of each branch. (code already in place, but commented out))
- 增加神经网络功能:通过使MiniMax算法的关键点(ComputerMove中每个节点级别分析的不等式)依赖于存储在外部配置文件中的值,并通过每次更新这些文件,可以在非常原始的级别上实现玩游戏(如果游戏获胜,则增加"得分";如果导致失败,则减少"得分").这仍处于初步阶段,但是我将尝试在下一版本中准备好相对的Developer版本(不影响大小).(Add neural network capability: This will be achieved at a very primitive level by having key points of the MiniMax algorithm (the inequalities at each node level analysis in ComputerMove) being dependent of values stored in external configuration files and by updating those files every time a game is played (increase ‘score’ if the game is a win, decrease if it resulted in defeat). This is still in preliminary stage, but I will try to have a relative Developer edition ready in the next version (without compromising the size).)
- 改进CountScore功能,以考虑到棋盘的位置,是否在开始等情况下两次移动同一块棋子.(Improve CountScore function, to take into account the position of the chessboard, whether you move the same piece twice in the opening et cetera.) 一个(An)Java中的Huo Chess版本(Huo Chess version in Java)也正在进行中.您可以在Harmonia Philosophica门户上找到Huo Chess v0.990的Java版本.这将是该应用程序的Android端口的基础.(is also under way. You can find the Java version of Huo Chess v0.990 at the Harmonia Philosophica portal. This will be the basis for an Android port of the application.)
I.国际象棋算法分析(版本0.971-0.991)(I. Chess Algorithm Analysis (versions 0.971 - 0.991))
该程序实现了MiniMax算法. Huo Chess考虑了材料的使用,而其代码中则隐含了一些位置战略游戏的暗示.更具分析性:程序开始思考时,它将扫描棋盘以找到棋子的位置(请参阅ComputerMove函数),然后尝试执行所有可能的动作.它分析了这些移动,直至达到我定义的思考深度(通过ComputerMove-> Analyze_Move_1_HumanMove-> Analyze_Move_2_ComputerMove路径),测量了所有可能的移动变量所达到的最终位置的得分(请参见CountScore函数),并且-最终-选择了移动从得分的角度来看,这是最有前途的位置(ComputerMove函数).(The program implements the MiniMax algorithm. Huo Chess plays with the material in mind, while its code has some hints of positional strategic playing embedded. More analytically: When the program starts thinking, it scans the chessboard to find where its pieces are (see ComputerMove function) and then tries all possible moves it can make. It analyzes these moves up to the thinking depth I have defined (via the ComputerMove -> Analyze_Move_1_HumanMove -> Analyze_Move_2_ComputerMove path), measures the score (see CountScore function) of the final position reached from all possible move variants and – finally – chooses the move that leads to the most promising (from a score point of view) position (ComputerMove function).)
C#v0.990 Kakos-Minimax算法摘要(C# v0.990 Kakos-Minimax algorithm summary)
高层次(A high-level)概要(summary)进展如下:(of the progress is as follows:)
ComputerMove
:扫描棋盘.检查危险方块.进行所有可能的移动. (不包括根据特定标准为"愚蠢"的举动)(: Scans the chessboard. Checks for dangerous squares. Makes all possible moves. (excluding moves which are “stupid” based on spefici criteria))CheckMove
:存储移动的初始值并进行一些其他检查(例如进行检查)(: Stores the initial values of the move and makes some additional checks (e.g. for check))- 如果未达到思考深度=>致电Analyze_Move_1_HumanMove(If thinking depth not reached => call Analyze_Move_1_HumanMove) ``
- Analyze_Move_1_HumanMove:检查人类对手的所有可能答案(Analyze_Move_1_HumanMove: Checks all possible answers of the human opponent)
- 如果未达到思考深度=>致电Analyze_Move_2_ComputerMove(If thinking depth not reached => call Analyze_Move_2_ComputerMove)
- Analyze_Move_2_ComputerMove:扫描棋盘,并在下一思考级别对计算机进行所有可能的移动(Analyze_Move_2_ComputerMove: Scans the chessboard and makes all possible moves for the computer at the next thinking level)
- 如果思考深度达到=>,请在"(If thinking depth reached => record the score of the final position in the Nodes of the)
MiniMax
算法(algorithm) - 算法继续进行,直到扫描了所有可能的移动(The algorithm continues until all possible moves are scanned)
- 的(The)
MiniMax
最后,通过对思维树节点的分析,使用该算法来计算最佳移动(algorithm is finally used to calculate the best move via the analysis of the thinking tree Nodes) 您可以(You can)取消注释日志编写代码(uncomment the log writting code)(请参阅#region WriteLog,#region NodesLogBEFORE和#region NodesLogAFTER),以查看计算机思考的进度,同时计算机思考将在思考过程中创建的各个.txt文件.((see #region WriteLog, #region NodesLogBEFORE and #region NodesLogAFTER) to see the progress of the computer thought while the computer thinks in the respective .txt files that will be created as the result of the thinking process.) 一个非常(A very)有用的Word文档以及Huo Chess思维过程的文档(useful Word document with the documentation of the Huo Chess thinking process)还在v0.990完整文件包中分发(请参见本文顶部).(is also distributed in the v0.990 full files pack (see at the top of this article).)
国际象棋引擎逻辑(v0.990)(Chess engine logic (v0.990))
v0.990的工作方式的更详细的摘要如下所示.(A more detailed summary of the way v0.990 works can be seen below.)
如果人类先玩=> EnterMove(If human plays first => EnterMove)
(否则,ComputerMove直接从((else ComputerMove is called directly from)Main_Console()(Main_Console()))()) 对于人类对手进入的举动^(For the move entered by the human opponent…)
-
检查搬家的合法性(Check legality of the move)
-
检查伴侣(Check for mate)
-
检查是否有检查活动(Check if there is check active)
-
储存移动的座标(Store move’s coordinates)
-
存储人为移动的价值(Store the value of the piece human moves)
-
存储该作品的移动坐标[Human_last_move_target_rank/column](Store the coordinates of where that piece moved [Human_last_move_target_rank/column])
电脑移动(ComputerMove)[Move_Analyzed =0]([Move_Analyzed = 0])
#region InitializeNodes //Initialize all nodes
#region StoreInitialPosition //Store initial position
#region OpeningBookCheck //OPENING BOOK CHECK
#region DangerousSquares //CHECK FOR DANGEROUS SQUARES
// Initialize variables
对于每一个可能的举动(For each possible move) {({) //检查动作是否愚蠢(// Check if the move is stupid)
#region CheckStupidMove
If Move < 5 and you move the knight to the edges => Stupid move etc…
+ Store moving piece’s value
#endregion CheckStupidMove
如果不是愚蠢的和目的地广场不危险=> …(If not stupid & Destination square not dangerous => …)
if ((ThisIsStupidMove.CompareTo("N") == 0) && (Skakiera_Dangerous_Squares[(m_FinishingColumnNumber - 1), (m_FinishingRank - 1)] == 0))...
致电CheckMove(Call CheckMove)
CheckMove(Skakiera_Thinking, m_StartingRank, m_StartingColumnNumber, m_FinishingRank, m_FinishingColumnNumber, MovingPiece);
<调用CheckMove(Skakiera_Thinking)>到:(<Call CheckMove(Skakiera_Thinking)> to:)
- 检查此举的合法性(Gr.Nomimotita)和有效性(Gr.Orthotita)(Check legality (Gr. Nomimotita) and validity (Gr. Orthotita) of the move)
- 检查伴侣(此操作尚未完成!必须添加!)(Check for mate (This is not done! Must add it!))
- 检查是否有检查活动(Check if there is check active) //如果首先分析了移动:将移动存储到*** _ HY变量中(以便将初始移动保留在某处)(*// If move analyzed in the first: Store move to ***_HY variables (so as to keep the initial move somewhere)*)
if (((m_OrthotitaKinisis == true) && (m_NomimotitaKinisis == true)) && (Move_Analyzed == 0)) => ...
如果此举有效…(If the move is valid…)
if ((m_OrthotitaKinisis == true) && (m_NomimotitaKinisis == true))
//行动(// Do the move)
ProsorinoKommati = Skakiera_Thinking[(m_FinishingColumnNumber - 1), (m_FinishingRank - 1)];
Skakiera_Thinking[(m_StartingColumnNumber - 1), (m_StartingRank - 1)] = "";
Skakiera_Thinking[(m_FinishingColumnNumber - 1), (m_FinishingRank - 1)] = MovingPiece;
电脑移动后检查分数(Check the score after the computer move)
if (Move_Analyzed == 0) then...
NodeLevel_0_count++;
Temp_Score_Move_0 = CountScore(Skakiera_Thinking, humanDangerParameter);
if (Move_Analyzed == 2) then...
NodeLevel_2_count++;
Temp_Score_Move_2 = CountScore(Skakiera_Thinking, humanDangerParameter);
// Store the best move score at this level
if ((m_PlayerColor.CompareTo("Black") == 0) && (Temp_Score_Move_0 > bestScoreLevel0))
{
bestScoreLevel0 = Temp_Score_Move_0;
}
//检查您是否可以吃掉搬家的那块人!(// Check if you can eat back the piece of the human which moved!)
if ((m_FinishingColumnNumber == Human_last_move_target_column)
&& (m_FinishingRank == Human_last_move_target_row)
&& (ValueOfMovingPiece <= ValueOfHumanMovingPiece))
{
Best_Move_StartingColumnNumber = m_StartingColumnNumber;
Best_Move_StartingRank = m_StartingRank;
Best_Move_FinishingColumnNumber = m_FinishingColumnNumber;
Best_Move_FinishingRank = m_FinishingRank;
possibility_to_eat_back = true;
}
检查吃的可能性(Check possibility to eat)
If there is a possibility to eat a piece of the opponent, then there is no need to analyze any further...
如果想(If thinkin)g深度未达到,调用下一级分析(g depth not reached, call next level of analysis)
if ((Move_Analyzed < Thinking_Depth) && (possibility_to_eat_back == false) && (possibility_to_eat == false))
{
Move_Analyzed = Move_Analyzed + 1;
for (i = 0; i <= 7; i++)
{
for (j = 0; j <= 7; j++)
{
Skakiera_Move_After[(i), (j)] = Skakiera_Thinking[(i), (j)];
}
}
Who_Is_Analyzed = "Human";
Analyze_Move_1_HumanMove(Skakiera_Move_After);
}
//撤消移动(// Undo the move)
Skakiera_Thinking[(m_StartingColumnNumber0 - 1), (m_StartingRank0 - 1)] = MovingPiece0;
Skakiera_Thinking[(m_FinishingColumnNumber0 - 1), (m_FinishingRank0 - 1)] = ProsorinoKommati0;
}(}) …(…) }(})
Analyze_Move_1_HumanMove(Analyze_Move_1_HumanMove)[Move_Analyzed =1]([Move_Analyzed = 1])
分析所有可能的动作(Analyze all possible moves) {({) //如果此举动有效且合法…(// If the move is valid and legal…)
if ((m_OrthotitaKinisis == true) && (m_NomimotitaKinisis == true)) then...
// Do the move
ProsorinoKommati = Skakiera_Human_Thinking_2[(m_FinishingColumnNumber - 1), (m_FinishingRank - 1)];
Skakiera_Human_Thinking_2[(m_StartingColumnNumber - 1), (m_StartingRank - 1)] = "";
Skakiera_Human_Thinking_2[(m_FinishingColumnNumber - 1), (m_FinishingRank - 1)] = MovingPiece;
//移动后测量分数(// Measure score AFTER the move)
NodeLevel_1_count++;
Temp_Score_Move_1_human = CountScore(Skakiera_Human_Thinking_2, humanDangerParameter);
//在此级别存储最佳移动(// Store the best move at this level)
if ((m_PlayerColor.CompareTo("Black") == 0) && (Temp_Score_Move_1_human < bestScoreLevel1))
{
bestScoreLevel1 = Temp_Score_Move_1_human;
}
如果未达到思考深度,请致电下一级分析(If thinking depth not reached, call next level of analysis)
if (Move_Analyzed < Thinking_Depth) && (Temp_Score_Move_1_human better than bestScoreLevel1)
{
Move_Analyzed = Move_Analyzed + 1;
Who_Is_Analyzed = "HY";
if (Move_Analyzed == 2)
Analyze_Move_2_ComputerMove(Skakiera_Move_After);
else if (Move_Analyzed == 4)
Analyze_Move_4_ComputerMove(Skakiera_Move_After);
else if (Move_Analyzed == 6)
Analyze_Move_6_ComputerMove(Skakiera_Move_After);
}
//撤消移动(// Undo the move)
Skakiera_Human_Thinking_2[(m_StartingColumnNumber1 - 1), (m_StartingRank1 - 1)] = MovingPiece1;
Skakiera_Human_Thinking_2[(m_FinishingColumnNumber1 - 1), (m_FinishingRank1 - 1)] = ProsorinoKommati1;
}(}) //返回先前的分析深度(// Return to previous depth of analysis)
Move_Analyzed = Move_Analyzed - 1;
Who_Is_Analyzed = "HY";
Analyze_Move_2_ComputerMove(Analyze_Move_2_ComputerMove)[Move_Analyzed =2]([Move_Analyzed = 2]) 检查所有可能的动作(Check all possible moves) {({) //如果此举动有效且合法…(// If the move is valid and legal…)
if ((m_OrthotitaKinisis == true) && (m_NomimotitaKinisis == true))
{({) //行动(// Do the move)
ProsorinoKommati = Skakiera_Thinking_HY_2[(m_FinishingColumnNumber - 1), (m_FinishingRank - 1)];
Skakiera_Thinking_HY_2[(m_StartingColumnNumber - 1), (m_StartingRank - 1)] = "";
Skakiera_Thinking_HY_2[(m_FinishingColumnNumber - 1), (m_FinishingRank - 1)] = MovingPiece;
//检查计算机移动后的分数.(// Check the score after the computer move.)
NodeLevel_2_count++;
Temp_Score_Move_2 = CountScore(Skakiera_Thinking_HY_2, humanDangerParameter);
//在此级别存储最佳分数(// Store the best score at this level)
if ((m_PlayerColor.CompareTo("Black") == 0) && (Temp_Score_Move_2 > bestScoreLevel2))
{
bestScoreLevel2 = Temp_Score_Move_2;
}
如果未达到思考深度,请致电下一级分析…(If thinking depth not reached, call next level of analysis…)
if (Move_Analyzed < Thinking_Depth)
{
Move_Analyzed = Move_Analyzed + 1;
Who_Is_Analyzed = "Human";
// Check human move
if (Move_Analyzed == 1)
Analyze_Move_1_HumanMove(Skakiera_Move_After);
else if (Move_Analyzed == 3)
Analyze_Move_3_HumanMove(Skakiera_Move_After);
else if (Move_Analyzed == 5)
Analyze_Move_5_HumanMove(Skakiera_Move_After);
}
//如果您已达到定义的分析深度…(// If you have reached the defined depth of analysis…)
if (Move_Analyzed == Thinking_Depth)
{
// [MiniMax algorithm - skakos]
// Record the node in the Nodes Analysis array (to use with MiniMax algorithm) skakos
NodesAnalysis0[NodeLevel_0_count, 0] = Temp_Score_Move_0;
NodesAnalysis1[NodeLevel_1_count, 0] = Temp_Score_Move_1_human;
NodesAnalysis2[NodeLevel_2_count, 0] = Temp_Score_Move_2;
NodesAnalysis3[NodeLevel_3_count, 0] = Temp_Score_Move_3_human;
// Store the parents (number of the node of the upper level)
NodesAnalysis0[NodeLevel_0_count, 1] = 0;
NodesAnalysis1[NodeLevel_1_count, 1] = NodeLevel_0_count;
NodesAnalysis2[NodeLevel_2_count, 1] = NodeLevel_1_count;
NodesAnalysis3[NodeLevel_3_count, 1] = NodeLevel_2_count;
}
注意:由于分析仅以ComputerMove函数结束,因此ThinkigDepth必须为偶数!(Note: Because the analysis ends only in ComputerMove functions, the ThinkigDepth must be an even number!) //撤消移动(// Undo the move) Skakiera_Thinking_HY_2 [(m_StartingColumnNumber2-1-,(m_StartingRank2-1))] =MovingPiece2;(Skakiera_Thinking_HY_2[(m_StartingColumnNumber2 - 1), (m_StartingRank2 - 1)] = MovingPiece2;) Skakiera_Thinking_HY_2 [(m_FinishingColumnNumber2-1-,(m_FinishingRank2-1))] =ProsorinoKommati2;(Skakiera_Thinking_HY_2[(m_FinishingColumnNumber2 - 1), (m_FinishingRank2 - 1)] = ProsorinoKommati2;) }(})
Move_Analyzed = Move_Analyzed - 1;
Who_Is_Analyzed = "Human";
电脑移动(ComputerMove)[续…-分析结束]([Continued… - The End of Analysis])
检查伴侣(Check for mate) //找到最佳移动:使用MiniMax算法(仅当吃掉一块对手的可能性为假时)(// Find the Best Move: Use MiniMax algorithm (only if possibility to eat a piece of the opponent is false))
if (possibility_to_eat_back == false)
{
// [MiniMax algorithm - skakos]
// Find node 1 move with the best score via the MiniMax algorithm.
int counter0, counter1, counter2;
// ------------------------------------------------------
// NodesAnalysis
// ------------------------------------------------------
// Nodes structure...
// [ccc, xxx, 0]: Score of node No. ccc at level xxx
// [ccc, xxx, 1]: Parent of node No. ccc at level xxx-1
// ------------------------------------------------------
int parentNodeAnalyzed = -999;
//v0.980: Remove
//parentNodeAnalyzed = -999;
for (counter2 = 1; counter2 <= NodeLevel_2_count; counter2++)
{
if (Int32.Parse(NodesAnalysis2[counter2, 1].ToString()) != parentNodeAnalyzed)
{
//parentNodeAnalyzedchanged = true;
parentNodeAnalyzed = Int32.Parse(NodesAnalysis2[counter2, 1].ToString());
NodesAnalysis1[Int32.Parse(NodesAnalysis2[counter2, 1].ToString()), 0] = NodesAnalysis2[counter2, 0];
}
if (NodesAnalysis2[counter2, 0] >= NodesAnalysis1[Int32.Parse(NodesAnalysis2[counter2, 1].ToString()), 0])
NodesAnalysis1[Int32.Parse(NodesAnalysis2[counter2, 1].ToString()), 0] = NodesAnalysis2[counter2, 0];
}
// Now the Node1 level is filled with the score data
parentNodeAnalyzed = -999;
for (counter1 = 1; counter1 <= NodeLevel_1_count; counter1++)
{
if (Int32.Parse(NodesAnalysis1[counter1, 1].ToString()) != parentNodeAnalyzed)
{
//parentNodeAnalyzedchanged = true;
parentNodeAnalyzed = Int32.Parse(NodesAnalysis1[counter1, 1].ToString());
NodesAnalysis0[Int32.Parse(NodesAnalysis1[counter1, 1].ToString()), 0] = NodesAnalysis1[counter1, 0];
}
if (NodesAnalysis1[counter1, 0] <= NodesAnalysis0[Int32.Parse(NodesAnalysis1[counter1, 1].ToString()), 0])
NodesAnalysis0[Int32.Parse(NodesAnalysis1[counter1, 1].ToString()), 0] = NodesAnalysis1[counter1, 0];
}
// Choose the biggest score at the Node0 level
// Check example at http://en.wikipedia.org/wiki/Minimax#Example_2
// Initialize the score with the first score and move found
double temp_score = NodesAnalysis0[1, 0];
Best_Move_StartingColumnNumber = Int32.Parse(NodesAnalysis0[1, 2].ToString());
Best_Move_StartingRank = Int32.Parse(NodesAnalysis0[1, 4].ToString());
Best_Move_FinishingColumnNumber = Int32.Parse(NodesAnalysis0[1, 3].ToString());
Best_Move_FinishingRank = Int32.Parse(NodesAnalysis0[1, 5].ToString());
for (counter0 = 1; counter0 <= NodeLevel_0_count; counter0++)
{
if (NodesAnalysis0[counter0, 0] > temp_score)
{
temp_score = NodesAnalysis0[counter0, 0];
Best_Move_StartingColumnNumber = Int32.Parse(NodesAnalysis0[counter0, 2].ToString());
Best_Move_StartingRank = Int32.Parse(NodesAnalysis0[counter0, 4].ToString());
Best_Move_FinishingColumnNumber = Int32.Parse(NodesAnalysis0[counter0, 3].ToString());
Best_Move_FinishingRank = Int32.Parse(NodesAnalysis0[counter0, 5].ToString());
}
}
}
行动吧(Do the move)
重画棋盘(Redraw the chessboard)
如果找不到动静=>辞职(If no move found => Resign)
将huo_DEBUG设置为true的Huo Chess 0.94:您可以看到计算机的想法并对其进行优化(Huo Chess 0.94 with huo_DEBUG set to true: you can see how computer thinks and optimize it)## 二. Huo Chess Thought Flow Minimax算法(II. Huo Chess Thought Flow [Minimax algorithm] (versions 0.971, 0.980))
下面,我分析国际象棋程序的思想流程.我将仅描述主要步骤和代码段,以说明计算机扫描棋盘,进行所有可能的动作并最终找到更好的动作的方式.函数名称以粗体显示,即(Below, I analyze the thought flow of the chess program. I will describe only the main steps and code segments, so as to show the way the computer scans the chessboard, conducts all possible moves and finally finds the better one. The function names appear in bold, i.e.) ComputerMove
-开始表示开始(- Start indicates the beginning of the) ComputerMove()
功能.请注意,由于我不断更改程序,因此某些代码段可能与分布式ZIP文件中的代码略有不同.看起来,“恒定beta"状态是当今的趋势.(function. Be aware that some code segments may be slightly different from the code in the distributed ZIP file since I continuously change the program. As it appears, the “constant beta” state is the trend nowadays.)
ComputerMove(开始)(ComputerMove (Start))
初始化节点(Initialize nodes) 店铺初始位置(Store initial position) 检查开本(Check opening book) 检查危险方块(Check dangerous squares) 分析所有可能的动作(Analyze all possible moves)
for (...)
{
MovingPiece = Skakiera_Thinking[(iii), (jjj)];
m_StartingColumnNumber = iii + 1;
m_FinishingColumnNumber = w + 1;
m_StartingRank = jjj + 1;
m_FinishingRank = r + 1;
// Store temporary move data in local variables, so as to use them in the Undo of the move at the end of this function (MovingPiece, m_StartingColumnNumber, etc variables are changed by next functions as well, so using them leads to problems)
MovingPiece0 = MovingPiece;
m_StartingColumnNumber0 = m_StartingColumnNumber;
m_FinishingColumnNumber0 = m_FinishingColumnNumber;
m_StartingRank0 = m_StartingRank;
m_FinishingRank0 = m_FinishingRank;
ProsorinoKommati0 = Skakiera_Thinking[(m_Finishi…)];
} (check all possible moves)
呼叫(Call)检查移动(CheckMove)(Skakiera_Thinking)执行一些检查((Skakiera_Thinking) to perform some checks)
检查移动(CheckMove)
- 存储移动的初始值(Store initial values of the move)
- 检查伴侣(Check for mate)
- 检查检查(Check for check)
- 检查移动的合法性和有效性(仅适用于ComputerMove!)(Check legality and validity of the move (only for ComputerMove!))
电脑移动(从CheckMove返回)(Computer move (back from CheckMove))
对于每一个可能的举动(For each possible move)
- 计数分数(Count score) 如果所分析的举动是正确且合法的,请执行并衡量其得分(If the move under analysis is correct and legal, do it and measure its score)
if ((m_OrthotitaKinisis == true) && (m_NomimotitaKinisis == true))
{
DO THE MOVE
// Measure score AFTER the move
if (Move_Analyzed == 0)
{
NodeLevel_0_count++;
Temp_Score_Move_0 = CountScore(Skakie…);
}
if (Move_Analyzed == 2)
{
NodeLevel_2_count++;
Temp_Score_Move_2 = CountScore(Skakie…);
}
if (Move_Analyzed == 4)
{
NodeLevel_4_count++;
Temp_Score_Move_4 = CountScore(Skakie…);
}
if (Move_Analyzed == 6)
{
NodeLevel_6_count++;
Temp_Score_Move_6 = CountScore(Skakie…);
}
如果您尚未深入思考,请调用下一级分析功能…(If you have not reached the thinking depth, call the next level analysis functions…)
- 增加节点数(Increase nodes count)
- 将分数存储在该节点上(Store the score at that node)
- 调用next函数进行更深入的搜索…(Call next function to search at a deeper level…)
if (Move_Analyzed < Thinking_Depth)
{
Move_Analyzed = Move_Analyzed + 1;
// Check human move (to find the best possible answer of the human
// to the move currently analyzed by the HY Thought process)
Who_Is_Analyzed = "Human";
if (Move_Analyzed == 1)
Analyze_Move_1_HumanMove(Skakiera_Move_After);
else if (Move_Analyzed == 3)
Analyze_Move_3_HumanMove(Skakiera_Move_After);
else if (Move_Analyzed == 5)
Analyze_Move_5_HumanMove(Skakiera_Move_After);
}
Analyze_Move_1_HumanMove(从ComputerMove调用)(Analyze_Move_1_HumanMove (called from ComputerMove))
for ... (check all possible moves)
{
// Store temporary move data in local variables, so as to use them in the Undo of the move at the end of this function (the MovingPiece, m_StartingColumnber, etc variables are changed by next functions as well, so using them leads to problems)
MovingPiece1 = MovingPiece;
m_StartingColumnNumber1 = m_StartingColumnNumber;
m_FinishingColumnNumber1 = m_FinishingColumnNumber;
m_StartingRank1 = m_StartingRank;
m_FinishingRank1 = m_FinishingRank;
ProsorinoKommati1 = Skakiera_Human_Thinking_2[(m_Fi...)];
如果此举是合法有效的…(If the move is legal and valid…)
if ((m_OrthotitaKinisis == true) && (m_NomimotitaKinisis == true))
行动吧(Do the move) 移动后测量分数(Measure score AFTER the move)
if (Move_Analyzed == 1)
{
NodeLevel_1_count++;
Temp_Score_Move_1_human = CountScore(Skakiera_Human_Thinking_2, humanDangerParameter);
}
if (Move_Analyzed == 3)
{
NodeLevel_3_count++;
Temp_Score_Move_3_human = CountScore(Skakiera_Human_Thinking_2, humanDangerParameter);
}
if (Move_Analyzed == 5)
{
NodeLevel_5_count++;
Temp_Score_Move_5_human = CountScore(Skakiera_Human_Thinking_2, humanDangerParameter);
}
如果未达到思考深度,请调用下一级思考功能…(If thinking depth not reached, call the next level thinking function…)
if (Move_Analyzed < Thinking_Depth)
{
// Call ComputerMove for the HY throught process to continue
Move_Analyzed = Move_Analyzed + 1;
Who_Is_Analyzed = "HY";
for (i = 0; i <= 7; i++)
{
for (j = 0; j <= 7; j++)
{
Skakiera_Move_After[(i), (j)] = Skakiera_Human_Thinking_2[(i), (j)];
}
}
if (Move_Analyzed == 2)
Analyze_Move_2_ComputerMove(Skakiera_Move_After);
else if (Move_Analyzed == 4)
Analyze_Move_4_ComputerMove(Skakiera_Move_After);
else if (Move_Analyzed == 6)
Analyze_Move_6_ComputerMove(Skakiera_Move_After);
}
Analyze_Move_2_ComputerMove(从Analyze_Move_1_HumanMove调用)(Analyze_Move_2_ComputerMove (called from Analyze_Move_1_HumanMove))
分析所有可能的动作(Analyze all possible moves)
for (...)
{
MovingPiece = Skakiera_Thinking_template[(iii), (jjj)];
m_StartingColumnNumber = iii + 1;
m_FinishingColumnNumber = w + 1;
m_StartingRank = jjj + 1;
m_FinishingRank = r + 1;
}
检查移动(Check the move)
- 合法吗(Is it legal?)
- 有效吗(Is it valid?) 如果此举是合法合法的…(If the move is valid and legal…)
if ((m_OrthotitaKinisis == true) && (m_NomimotitaKinisis == true))
行动吧(Do the move) 移动计算机后检查分数.(Check the score after the computer move.)
if (Move_Analyzed == 0)
{
NodeLevel_0_count++;
Temp_Score_Move_0 = CountScore(Skakiera_Thinking_HY_2, humanDangerParameter);
}
if (Move_Analyzed == 2)
{
NodeLevel_2_count++;
Temp_Score_Move_2 = CountScore(Skakiera_Thinking_HY_2, humanDangerParameter);
}
if (Move_Analyzed == 4)
{
NodeLevel_4_count++;
Temp_Score_Move_4 = CountScore(Skakiera_Thinking_HY_2, humanDangerParameter);
}
if (Move_Analyzed == 6)
{
NodeLevel_6_count++;
Temp_Score_Move_6 = CountScore(Skakiera_Thinking_HY_2, humanDangerParameter);
}
如果达到思考深度(If thinking depth is reached),在Nodes Analysis数组中记录节点(与MiniMax算法配合使用)(, record the nodes in the Nodes Analysis array (to use with MiniMax algorithm))
if (Move_Analyzed == Thinking_Depth)
{
// [MiniMax algorithm - skakos]
// Record the node in the Nodes Analysis array (to use with MiniMax algorithm) skakos
NodesAnalysis[NodeLevel_0_count, 0, 0] = Temp_Score_Move_0;
NodesAnalysis[NodeLevel_1_count, 1, 0] = Temp_Score_Move_1_human;
NodesAnalysis[NodeLevel_2_count, 2, 0] = Temp_Score_Move_2;
NodesAnalysis[NodeLevel_3_count, 3, 0] = Temp_Score_Move_3_human;
NodesAnalysis[NodeLevel_4_count, 4, 0] = Temp_Score_Move_4;
NodesAnalysis[NodeLevel_5_count, 5, 0] = Temp_Score_Move_5_human;
NodesAnalysis[NodeLevel_6_count, 6, 0] = Temp_Score_Move_6;
// Store the prnts (number of the node of the upper level)
NodesAnalysis[NodeLevel_0_count, 0, 1] = 0;
NodesAnalysis[NodeLevel_1_count, 1, 1] = NodeLevel_0_count;
NodesAnalysis[NodeLevel_2_count, 2, 1] = NodeLevel_1_count;
NodesAnalysis[NodeLevel_3_count, 3, 1] = NodeLevel_2_count;
NodesAnalysis[NodeLevel_4_count, 4, 1] = NodeLevel_3_count;
NodesAnalysis[NodeLevel_5_count, 5, 1] = NodeLevel_4_count;
NodesAnalysis[NodeLevel_6_count, 6, 1] = NodeLevel_5_count;
}
如果未达到思考深度,请调用下一个级别,依此类推…(If thinking depth is not reached, call the next level and so on…)
if (Move_Analyzed < Thinking_Depth)
{
Move_Analyzed = Move_Analyzed + 1;
for (i = 0; i <= 7; i++)
{
for (j = 0; j <= 7; j++)
{
Skakiera_Move_After[(i), (j)] = Skakiera_Thinking[(i), (j)];
}
}
Who_Is_Analyzed = "Human";
First_Call_Human_Thought = true;
// Check human move
if (Move_Analyzed == 1)
Analyze_Move_1_HumanMove(Skakiera_Move_After);
else if (Move_Analyzed == 3)
Analyze_Move_3_HumanMove(Skakiera_Move_After);
else if (Move_Analyzed == 5)
Analyze_Move_5_HumanMove(Skakiera_Move_After);
}
撤消移动(Undo the move) 返回上一级…(Return to previous level…)
Move_Analyzed = Move_Analyzed - 1;
Who_Is_Analyzed = "Human";
Analyze_Move_1_HumanMove(从Analyze_Move_2_ComputerMove返回)(Analyze_Move_1_HumanMove (back from Analyze_Move_2_ComputerMove))
撤消移动(Undo the move) 返回上一级…(Return to previous level…)
Move_Analyzed = Move_Analyzed - 1;
Who_Is_Analyzed = "HY";
ComputerMove(从Analyze_Move_1_HumanMove返回)(ComputerMove (back from Analyze_Move_1_HumanMove))
撤消移动(Undo the move)
Skakiera_Thinking[(m_StartingColumnNumber0 - 1), (m_StartingRank0 - 1)] = MovingPiece0;
Skakiera_Thinking[(m_FinishingColumnNumber0 - 1), (m_FinishingRank0 - 1)] = ProsorinoKommati0;
} (end of for loop)
查找是否有伴侣(Find if there is mate) 尽力而为!(DO THE BEST MOVE FOUND!) [MiniMax算法– skakos-START]([MiniMax algorithm – skakos - START]) 检查Minimax算法(Check Minimax algorithm) http://en.wikipedia.org/wiki/Minimax(http://en.wikipedia.org/wiki/Minimax) 该算法的工作原理!(for how the algorithm works!)
// -----------------------------------------------------
// NodesAnalysis
// -----------------------------------------------------
// Nodes structure...
// [ccc, xxx, 0]: Score of node No. ccc at level xxx
// [ccc, xxx, 1]: Parent of node No. ccc at level xxx-1
// -----------------------------------------------------
prntNodeAnalyzed = -999;
for (counter6 = 1; counter6 <= NodeLevel_6_count; counter6++)
{
if (Int32.Parse(NodesAnalysis[counter6, 6, 1].ToString()) != prntNodeAnalyzed)
{
prntNodeAnalyzed = Int32.Parse(NodesAnalysis[counter6, 6, 1].ToString());
NodesAnalysis[Int32.Parse(NodesAnalysis[counter6, 6, 1].ToString()), 5, 0] = NodesAnalysis[counter6, 6, 0];
}
if (NodesAnalysis[counter6, 6, 0] <= NodesAnalysis[Int32.Parse(NodesAnalysis[counter6, 6, 1].ToString()), 5, 0])
NodesAnalysis[Int32.Parse(NodesAnalysis[counter6, 6, 1].ToString()), 5, 0] = NodesAnalysis[counter6, 6, 0];
}
prntNodeAnalyzed = -999;
for (counter5 = 1; counter5 <= NodeLevel_5_count; counter5++)
{
if (Int32.Parse(NodesAnalysis[counter5, 5, 1].ToString()) != prntNodeAnalyzed)
{
prtNodeAnalyzed = Int32.Parse(NodesAnalysis[counter5, 5, 1].ToString());
NodesAnalysis[Int32.Parse(NodesAnalysis[counter5, 5, 1].ToString()), 4, 0] = NodesAnalysis[counter5, 5, 0];
}
if (NodesAnalysis[counter5, 5, 0] >= NodesAnalysis[Int32.Parse(NodesAnalysis[counter5, 5, 1].ToString()), 4, 0])
NodesAnalysis[Int32.Parse(NodesAnalysis[counter5, 5, 1].ToString()), 4, 0] = NodesAnalysis[counter5, 5, 0];
}
...
[MiniMax算法– skakos-结束]([MiniMax algorithm – skakos - END]) 重画棋盘(REDRAW THE CHESSBOARD)
// now it is the other color's turn to play
if (m_PlayerColor.CompareTo("Black") == 0)
m_WhichColorPlays = "Black";
else if (m_PlayerColor.CompareTo("White") == 0)
m_WhichColorPlays = "White";
// now it is the human's turn to play
m_WhoPlays = "Human";
CountScore
衡量每个举动得分(如果举动合法且正确).这些分数存储在(Every move score is measured (if the move is legal and correct). These scores are stored in the) NodesAnalysis
数组(请参见下文).计分功能是程序的核心.目前,它主要考虑的是物质价值,并考虑了游戏开始阶段的一些位置问题(即(array (see below). The scoring function is the heart of the program. It currently takes into account mainly material values, with some positional considerations for the opening phase of the game (i.e. if) Move < 11
请不要移动您的女王,否则将被施加少量的"记分罚款”).该功能的优化是提高计算机播放强度的关键.(it is not good to move your Queen or else a small “scoring penalty” is imposed). The optimization of that function is key to the increasing of the computer play strength.)
应用了MiniMax算法(MiniMax algorithm applied)
当我们达到思考的深度时(即当我们达到(When we have reached the thinking depth (i.e. when we have reached the) ComputerMove
函数,我们将其定义为分析链中的最后一个),我们针对每个思考深度级别(适用于0.93及更高版本)存储思考树节点的棋盘得分.(function which we have defined as the last one in the chain of analysis), we store the chessboard scores of the thinking tree nodes for every thinking depth level (applies for version 0.93 and newer).)
然后,这些节点将用于MiniMax算法中以找到最佳移动.(These nodes are then going to be used in the MiniMax algorithm to find the best move.)
// Record the node in the Nodes Analysis array (to use with MiniMax algorithm) skakos
NodesAnalysis[NodeLevel_1_count, 1, 0] = Temp_Score_Human_before_2;
NodesAnalysis[NodeLevel_2_count, 2, 0] = Temp_Score_Human_after_2;
NodesAnalysis[NodeLevel_3_count, 3, 0] = Temp_Score_Human_before_4;
NodesAnalysis[NodeLevel_4_count, 4, 0] = Temp_Score_Human_after_4;
NodesAnalysis[NodeLevel_5_count, 5, 0] = Temp_Score_Human_before_6;
NodesAnalysis[NodeLevel_6_count, 6, 0] = Temp_Score_Human_after_6;
对于每个节点,我们还存储父节点的编号:(For every node, we also store the number of the parent node:)
// Store the parents (number of the node of the upper level)
NodesAnalysis[NodeLevel_1_count, 1, 1] = 0;
NodesAnalysis[NodeLevel_2_count, 2, 1] = NodeLevel_1_count;
NodesAnalysis[NodeLevel_3_count, 3, 1] = NodeLevel_2_count;
NodesAnalysis[NodeLevel_4_count, 4, 1] = NodeLevel_3_count;
NodesAnalysis[NodeLevel_5_count, 5, 1] = NodeLevel_4_count;
这对于MiniMax算法实现是必需的(请参阅(This is required for the MiniMax algorithm implementation (see) http://en.wikipedia.org/wiki/Minimax(http://en.wikipedia.org/wiki/Minimax) 关于此算法的工作原理):我们从较低级别的节点开始,一直到树的开头,如以下模式所示:(on how this algorithm works): We start from the lower level nodes and go up to the beginning of the tree, like in the schema that follows:)
假设正在玩的游戏每回合每个玩家最多只能有两个可能的动作.该算法生成上图所示的树,其中的圆圈代表运行该算法的计算机AI的移动((Suppose the game being played only has a maximum of two possible moves per player each turn. The algorithm generates the tree shown in the figure above, where the circles represent the moves of the computer AI running the algorithm ()最大化玩家(maximizing player)),正方形代表人类对手的移动((), and squares represent the moves of the human opponent ()最小化玩家(minimizing player)).为了满足示例的需要,该树仅限于(). For the example’s needs, the tree is limited to a)**展望(look-ahead)**4个动作.(of 4 moves.)
该算法评估每个(The algorithm evaluates each)**叶节点(leaf node)**使用(using the) CountScore
评估功能,获取显示的值.的动作(evaluation functions, obtaining the values shown. The moves where the)**最大化玩家(maximizing player)**获胜者分配正无穷大,而导致获胜者的举动(wins are assigned with positive infinity, while the moves that lead to a win of the)**最小化玩家(minimizing player)**被赋予负无穷大(这再次仅用于说明目的-无穷无尽在当前开发的游戏中).在第3级,算法将为每个节点选择(are assigned with negative infinity (this is again for illustration purposes only – infinity will not happen in the game as it is currently developed). At level 3, the algorithm will choose, for each node, the)最小的(smallest)的(of the)**子节点(child node)**值,并将其分配给同一节点(例如,左侧的节点将在" 10"和" +8"之间选择最小值,因此为其自身分配值" 10").级别2的下一步包括为每个节点选择(values, and assign it to that same node (e.g. the node on the left will choose the minimum between “10” and “+8”, therefore assigning the value “10” to itself). The next step, in level 2, consists of choosing for each node the)最大的(largest)的(of the)**子节点(child node)**价值观.再一次,将值分配给每个(values. Once again, the values are assigned to each)父节点(parent node).算法继续交替评估子节点的最大值和最小值,直到达到子节点的最大值为止.(. The algorithm continues evaluating the maximum and minimum values of the child nodes alternately until it reaches the)根节点(root node),在该处选择具有最大值的移动(在图中以蓝色箭头表示).这是玩家应该采取的行动(, where it chooses the move with the largest value (represented in the figure with a blue arrow). This is the move that the player should make in order to)**最小化(minimize)**的(the)**最大值(maximum)**可能的损失.(possible loss.)
为了使程序能够计算出最佳移动,一些"(In order for the program to calculate the best move, a number of “) for
应用"循环"以使上述反向计算成为可能.(loops” are applied so as to make the abovementioned backwards computation possible.)
for (counter7 = 1; counter7 <= NodeLevel_7_count; counter7++)
{
for (counter8 = 1; counter8 <= NodeLevel_8_count; counter8++)
{
if (NodesAnalysis[counter8, 8, 1] == counter7)
{
if (counter8 == 1)
NodesAnalysis[counter7, 7, 0] = NodesAnalysis[counter8, 8, 0];
if (counter8 > 1)
if (NodesAnalysis[counter8, 8, 0] < NodesAnalysis[counter7, 7, 0])
NodesAnalysis[counter7, 7, 0] = NodesAnalysis[counter8, 8, 0];
}
}
}
算法到达根节点后,将选择得分最高的移动.(After the algorithm has reached the root node, the move with the best score is selected.)
ComputerMove
[最大思考深度] –结束([Maximum thinking depth] – End)
三, Huo Chess思维流程(v0.95 Simple-Minimax)(III. Huo Chess Thinking Flow (v0.95 Simple-Minimax))
ComputerMove()
{
DangerousSquares
MoveFilter
for all possible moves
{
Temporarily make all possible moves
Count the score of these moves
Call ComputerMove2 (with the temporary chessboard as input)
// Second level of thought
ComputerMove2()
{
...
ComputerMove5()
{
Record the moves and their scores in the Nodes Analysis array
}
}
}
Do the best move (MiniMax);
}
IV. Huo Chess Thought Flow(v0.93 Kakos-Minimax或所有v0.84及更低版本)(IV. Huo Chess Thought Flow (v0.93 Kakos-Minimax or all v0.84 and older versions))
在本节中,我将分析0.93-Kakos-Minimax版本或0.84及更高版本的思维算法. (它们之间的主要区别是在完成所有可能动作的分析之后,用于找到最佳动作的方法).下面,我以2的思考深度说明计算机思维的逐步过程. “步骤"框可了解程序的结构方式.(In this section, I analyze the thinking algorithm for version 0.93-Kakos-Minimax or for versions 0.84 and older. (the main difference between these are the method used to find the best move after the analysis of all possible moves is complete) Below, I illustrate the step-by-step process of the computer’s thought for a thinking depth of 2. Let’s see the “step” boxes to understand the way the program is structured.) 场景详细信息(Scenario Details)
- 计算机级别:Maitre(ThinkingDepth =2)(Computer Level: Maitre (ThinkingDepth = 2))
ComputerMove
-开始(- Start)
第1步(Step 1)
开始(START)
Move_Analyzed
=0(= 0)
1. If the first time called -> store initial chessboard position.
2. if( Move_Analyzed >Thinking_Depth )
3. Stop_Analyzing = true;
4. if( Stop_Analyzing = false)
5. Scan chessboard.
for iii, jjj
6. Scan chessboard, find a piece of the HY , conduct move,
check correctness and legality of move,
and if all is OK, then call CheckMove to measure the score of the move.
呼叫:(Call:) CheckMove
CheckMove
-开始(- Start)
- 分析的动作数++.(Number of moves analyzed ++.)
- 检查移动的正确性和合法性.(Check correctness and legality of move.)
- 检查棋盘上是否有伴侣.(Check if there is a mate on the chessboard.)
- 如果此举是正确和合法的,那就去做.(If the move is correct and legal, then do it.)
- 检查是否有要提升的棋子.(Check if there is a pawn to be promoted.)
- 将移动存储到*** _ HY变量,因为在多次调用之后(*Store move to ***_HY variables because, after many calls of*)
ComputerMove
和(*and*)CheckMove
功能,分析的移动的初始值将丢失.(*functions, the initial values of the move analyzed will be lost.*) - 如果这是分析的第一个举动,那么无论它有多糟糕,都应将其记录为正确的"最佳"举动.(If this is the first move analyzed, then record it as the correct “best” move, no matter how bad it is.)
第2步(Step 2)
IF result: FALSE
Move_Analyzed = 0
- 如果((if()
Move_Analyzed
=(=)Thinking_Depth
)()) - 测量移动分数,如果它大于迄今为止最好的移动分数,则将其记录为"最佳"移动.(Measure the score of the move and record it as “best” move if it is larger than the score of the so-far best move score.)
第三步(Step 3)
IF result: TRUE
Move_Analyzed = 1
- 如果((if ()
Move_Analyzed < Thinking_Depth
)())HumanMove
-开始[(- Start [)HumanMove_Template
对于v0.93](for v0.93])
第4步(Step 4)
找到最佳答案(Find the best answer of the) Human (Move_Analyzed
=1).(= 1).)
0.93版:查找所有可能的人类举动(Version 0.93: Find ALL possible human moves)
- 扫描棋盘->查找任何可能的移动.(Scan the chessboard -> find any possible move.)
- 呼叫(Call)
CheckHumanMove
. [v0.93中的冗余](. [redundant in v0.93]) 在人体移动之前和之后存储棋盘分数.(Store the chessboard score before and after the human move.)CheckHumanMove
-开始(- Start)
voidCheckHumanMove(array<String^, 2>^ CMSkakiera_Human_Thinking)
计算动作分数,如果其分数比迄今为止的最佳动作更好,则将其记录为"最佳”.(Count the score of the move and record it as “best"if its score is better than the so-far best move.)
在v0.93及更高版本中:在人类对手行动之前和之后记录得分.(In v0.93 and newer: Record the score before and after the human opponents makes his move.)
这些分数记录在"节点分析"数组中,最后将用于MiniMax算法(以评估最佳移动).(Those scores are recorded in the Nodes Analysis array and will be used for the MiniMax algorithm at the end (to evaluate the best move).)
CheckHumanMove
- 结束(- End)
做出人类的最佳举动[在v0.93中进行所有可能的人类举动].(Conduct the best move of the human [conduct all possible human moves in v0.93].)
Move_Analyzed = Move_Analyzed + 1;
Who_Is_Analyzed = "HY";
for(i = 0; i <= 7;i++)
{
for(j = 0; j <= 7; j++)
{
Skakiera_Move_After[(i),(j)]=Skakiera_Human_Thinking[(i),(j)];
}
第5步(Step 5)
Move_Analyzed = 2
第6步(Step 6)
拨打电话(CALL next) ComputerMove
功能用于下一级移动分析.(function for next-level move analysis.)
Move_Analyzed = 2
if(Move_Analyzed == 2)
this->ComputerMove2(Skakiera_Move_After);
elseif(Move_Analyzed == 4)
this->ComputerMove4(Skakiera_Move_After);
elseif(Move_Analyzed == 6)
this->ComputerMove6(Skakiera_Move_After);
elseif(Move_Analyzed == 8)
this->ComputerMove8(Skakiera_Move_After);
// Call ComputerMove2 to find the best next move of the HY (deeper thinking)
步骤7(Step 7)
扫描棋盘,找到计算机的最佳举动.(Scan the chessboard and find the best move for the computer.)
Move_Analyzed = 2
voidComputerMove2(array<STRING^, />^ Skakiera_Thinking_2)
{
// Same as…ComputerMove
if(Move_Analyzed has not reached thinking depth)
{
// Same as…ComputerMove: Call CheckMove -> HumanMove -> next ComputerMove etc
// (If we haven't reached the desired level of analysis, then the HumanMove
// will be called again, then again the ComputerMove function etc.)
}
步骤8(Step 8)
返回上一个(Return to a previous) ComputerMove
(即((i.e.) ComputerMove4
来电(calls) ComputerMove2
)功能以继续分析.() function to continue the analysis.)
Move_Analyzed = 2
(在分析结束时,此变量将等于0,请参见步骤9).((at the end of the analysis this variable will be equal to 0, see Step 9).)
// Return to the ComputerMove function of the 'previous' thinking
// level to continue the analysis
Move_Analyzed = Move_Analyzed - 2;
Who_Is_Analyzed = "HY";
for(i = 0; i <= 7; i++)
{
for(j = 0; j <= 7; j++)
{
Skakiera_Thinking[i,j] = Skakiera_Move_0[i,j];
}
}
}
ComputerMove2
- 结束(- End)
HumanMove
- 结束(- End)
CheckMove
- 结束(- End)
// close for iii, jjj loop
// close if( Stop_Analyzing = false ) segment
如果找不到合法举动->我们有MATE!(If no legal move is found -> we have MATE!)
步骤9(Step 9)
0.93版:应用MiniMax算法以达到最佳效果.(Version 0.93: Apply the MiniMax algorithm to reach to the best move.) 得分最高的棋局.现在轮到人类玩了.(Play the move with the highest score. Now it is the Human’s turn to play.)
if (move_analyzed==0){
- 检查进行铸造是否良好.(Check if it is good to conduct castling.)
- 找到最佳动作的棋盘"重画”.(“Redraw” the chessboard with the best move found.)
- 如果发生cast叫,将车子移到国王旁边.(Move the rook next to the king, if castling occurred.)
- 检查棋子是否被提升(在当前版本中,计算机始终将棋子提升为女王).(Check if a pawn is promoted (at the current version computer always promotes a pawn to queen).)
- 现在轮到另一个玩家(人类)玩了!(Now it is the turn of the other player (human) to play!)
}
20. else
21. {
22. Move_Analyzed = Move_Analyzed - 2;
23. Who_Is_Analyzed = "HY";
24.
25. for(i = 0; i <= 7; i++)
26. {
27. for(j = 0; j <= 7;j++)
28. {
29. Skakiera_Thinking[i,j] = Skakiera_Move_0[i,j];
30. }
31. }
}
ComputerMove
- 结束(– End)
v0.93 Kakos-Minimax或v0.84及更低版本的思维流程摘要(Thinking Flow summary for v0.93 Kakos-Minimax or v0.84 and older versions)
ComputerMove()
{
for
{
// First level of thought
CheckMove()
{
if (Move_Analyzed <Thinking_Depth)
{
Move_Analyzed++;
// Find the best possible human move-answer and continue the thinking tree
Find Best Human Move (HumanMove function) / Find all possible human moves (v0.93);
Record chessboard scores before and after the human move;
Move_Analyzed++;
Go to next thinking depth
ComputerMove2()
{
for
{
CheckMove();
// Think deeper if you have not reached the thinking depth
if (Move_Analyzed <Thinking_Depth)
[Think deeper, if necessary!];
// Record move analyzed as Best Move, if it has the best score
if (Move_Analyzed = Thinking_Depth)
CountScore();
[Record if best move];
}
// Return to the initial level of thinking to start
// analyzing a new thread
Move_Analyzed = Move_Analyzed – 2;
}
}
}
Do the best move;
}
V.Huo Chess GUI版(V. Huo Chess GUI Edition)
Huo Chess的图形用户界面(GUI)版本由显示当前棋盘状态的简单棋盘组成.它确实支持鼠标移动,因此您不必通过键盘输入移动.将来会推出更多高级GUI版本.必须注意的是,GUI对程序的总大小影响不大. Huo Chess C#0.980 GUI版的总大小为78 KB.(The Graphical User interface (GUI) edition of Huo Chess consists of a simple chessboard which shows the current chessboard state. It does support mouse move so you do not have to enter the moves via keyboard. More advanced GUI editions with come in the future. It must be noted that the GUI did not affect the total size of the program much. The Huo Chess C# 0.980 GUI edition has a total size of 78 KB.)未来的计划(Future plans)包括开发与PGN兼容的程序,该程序可以利用Internet上可用的任何Chess GUI.(include the development of a PGN compatible program which can utilize any Chess GUI available on the Internet.)
VI.象棋游戏存档(VI. Huo Chess Games Archive)
该部分包含Huo Chess和其他国际象棋程序所玩的游戏.(That segment contains games played by Huo Chess versus other micro chess programs.)
游戏1(GAME 1)
日期:2007-11-11(Date: 2007-11-11) 地点:希腊雅典(Place: Athens, Greece) 白色:HuoChess v0.4(含开幕书)[由The Code Project分发](White: HuoChess v0.4 (with Opening Book) [as distributed by The Code Project]) 黑色:Microchess(由(Black: Microchess (as provided by) 本洛公园(BenLo Park) )()) 结果:三倍重复绘制(Result: Draw by threefold repetition)
1. d4 Nc6
2. d5 Nb4
3. Nc3 e5
4. Bg5 Qxg5
5. Nh3 Qg4
6. e4 Qh4
7. Be2 d6
8. Bb5+ Kd8
9. Nf4 Qxf4
10. h3 Nf6
11. f3 Qe3+
12. Be2 Bd7
13. f4 Qg3+
14. Kd2 Qxf4+
15. Ke1 Qg3+
16. Kd2 Qf4+
17. Ke1 Qg3+
18. Kd2 Qf4+
19. Ke1 Qg3+
20. Kd2 Qf4+
21. Ke1 [draw by threefold repetition]
游戏2(GAME 2)
日期:2007-11-11(Date: 2007-11-11) 地点:希腊雅典(Place: Athens, Greece) 白色:Microchess(由(White: Microchess (as provided by) 本洛公园(BenLo Park) )()) 黑色:HuoChess v0.4(含开幕书)[由The Code Project分发](Black: HuoChess v0.4 (with Opening Book) [as distributed by The Code Project]) 结果:三倍重复绘制(Result: Draw by threefold repetition)
1. e4 e6
2. Qh5 d6
3. Bb5+ Ke7
4. Qg5+ f6
5. Qh5 h6
6. d4 g6
7. Qxg6 Nd7
8. Bf4 f5
9. exf5 Ndf6
10. fxe6 Bxe6
11. a4 Bg7
12. Qxg7+ Bf7
13. Qxh8 Bh5
14. Qg7+ Bf7
15. Nc3 h5
16. Nf3 Nh7
17. Nd5+ Ke6
18. c4 c6
19. Nc7+ Qxc7
20. d5+ cxd5
21. Nd4+ Ke7
22. Nf5+ Ke6
23. Nd4+ Ke7
24. Nf5+ Ke6
25. Nd4+ Ke7
26. Nf5+ Ke6
27. Nd4+ Ke7
28. Nf5+ [draw by threefold repetition]
游戏3(GAME 3)
日期:2008-01-22(Date: 2008-01-22) 地点:希腊雅典(Place: Athens, Greece) 白色:Microchess(由(White: Microchess (as provided by) 本洛公园(BenLo Park) )()) 黑色:HuoChess v0.5(带有开幕书)[由The Code Project分发](Black: HuoChess v0.5 (with Opening Book) [as distributed by The Code Project]) 结果:三倍重复绘制(Result: Draw by threefold repetition)
1. e2-e4 e7-e6
2. d1-h5 c7-c5
3. f1-b5 g8-f6
4. h5-e5 f6-g4
5. e5-f4 g4xf2
6. e1xf2 g7-g5
7. f4-e5 a7-a6
8. b5-c4 f7-f6
9. e5-g3 d7-d6
10. g1-h3 h7-h6
11. h1-e1 e8-e7
12. b1-a3 d8-b6
13. d2-d4 b6-a5
14. c1-d2 a5xd2+
15. e1-e2 d2xd4+
16. 16.f2-f3 d4xb2
17. a1-d1 b2xa3+
18. c2-c3 a3xc3+
19. c4-d3 a6-a5
20. f3-g4 e7-d7
21. d3-b5+ d7-e7
22. g3xc3 f8-g7
23. e2-f2 e7-f7
24. d1xd6 a8-a7
25. c3xc5 b8-c6
26. f2-f3 b7-b6
27. c5xb6 c8-d7
28. f3-c3 e6-e5+
29. d6xd7+ a7xd7
30. b5-c4+ f7-e7
31. b6-c5+ d7-d6
32. c3-d3 c6-d4
33. c5-c7+ d6-d7
34. c7-c5+ d7-d6
35. c5-c7+ d6-d7
36. c7-c5+ d7-d6 [draw by threefold repetition]
游戏4(GAME 4)
日期:2008-02-22(Date: 2008-02-22) 地点:希腊雅典(Place: Athens, Greece) 白色:Microchess(由(White: Microchess (as provided by) 本洛公园(BenLo Park) )()) 黑色:HuoChess v0.6(无开幕书)[由The Code Project分发](Black: HuoChess v0.6 (without Opening Book) [as distributed by The Code Project]) 结果:三倍重复绘制(Result: Draw by threefold repetition)
1. Nf3 d5
2. Nc3 Qd6
3. Na4 Qf4
4. c3 Bd7
5. d4 Qe4
6. Ng5 Qg4
7. f3 Qh4+
8. g3 Qh5
9. Nc5 Bb5
10. b3 f6
11. Nge6 b6
12. e3 Bc6
13. Nd3 Bd7
14. Nxf8 Kxf8
15. Nf4 Qg5
16. Ne2 Nc6
17. f4 Qg4
18. h3 Qf3
19. Rh2 Nh6
20. Kd2 Nf5
21. Kc2 Qe4+
22. Kb2 Qf3
23. Kc2 Qe4+
24. Kb2 Qf3
25. Kc2 Qe4+
Huo Chess(即使没有打开书本)也成功打出了非常出色的游戏,在此期间,他下了很好的棋.在比赛结束时(三重重复导致平局),它没有进行任何错误的动作,没有放弃任何棋子并且比Microchess拥有更好的位置.(Huo Chess (even without Opening Book) managed to play a very good game, during which it played well-structured chess. It didn’t conduct any wrong moves, didn’t give up any pieces and had a better position than Microchess at the end of the game (when the threefold repetition resulted in a draw).)
游戏5(GAME 5)
日期:2009-01-25(Date: 2009-01-25) 地点:希腊雅典(Place: Athens, Greece) 白色:Microchess(由(White: Microchess (as provided by) 本洛公园(BenLo Park) )()) 黑色:HuoChess v0.82(含开幕书)[由The Code Project分发](Black: HuoChess v0.82 (with Opening Book) [as distributed by The Code Project]) 结果:三倍重复绘制(Result: Draw by threefold repetition)
1. e4 e6
2. Qh5 Qe7
3. Bc4 Kd8
4. d4 a6
5. Bf4 d5
6. exd5 f5
7. dxe6 Bxe6
8. Bxe6 g6
9. Qe2 Nd7
10. Bxc7+ Kxc7
11. Qc4+ Nc5
12. dxc5 Qg7
13. Qf4+ Kc6
14. Qf3+ Kxc5
15. Qd5+ Kb6
16. Qb3+ Kc7
17. Qc4+ Kd6
18. Qd5+ Kc7
19. Qc4+ Kd6
20. Qd5+ Kc7
21. Qc4+ Kd6
22. Qd5+ draw by threefold repetition
霍`象棋打的很好.它并没有无故放弃碎片,也没有失去杀死对手碎片的机会.(Huo Chess played a good game. It did not give up pieces without reason and did not lose chances to kill opponent’s pieces when possible.)
历史(History)
- 2007年10月3日-发布原始版本(3 October, 2007 – Original version posted)
- 2007年10月15日-版本0.2(15 October, 2007 – Version 0.2)
- 2007年10月22日-版本0.3(22 October, 2007 – Version 0.3)
- 2007年11月15日-版本0.4(15 November, 2007 – Version 0.4)
- 2008年1月25日-版本0.5(25 January, 2008 – Version 0.5)
- 2008年1月28日-许可证信息和下载已更新(28 January, 2008 – License info and download updated)
- 2008年2月28日-文章内容和下载已更新(28 February, 2008 – Article content and downloads updated)
- 2008年7月3日-版本0.721-文章内容和下载已更新(3 July, 2008 – Version 0.721 - Article content and downloads updated)
- 2009年1月8日-版本0.722-文章内容和下载已更新(8 January, 2009 – Version 0.722 - Article content and downloads updated)
- 2009年4月22日-版本0.82-文章内容和下载已更新(22 April, 2009 - Version 0.82 - Article content and downloads updated)
- 2011年9月8日– 0.93版(仅C#)– MiniMax算法更新(8 September, 2011 – Version 0.93 (C# only) – MiniMax algorithm update)
- 2012年9月19日– 0.95版(仅适用于C#)-更新危险方块检查和CountScore(19 September 2012 – Version 0.95 (C# only) - Update dangerous squares check & CountScore)
- 2014年8月12日-版本0.961(仅限C#)-修复了MiniMax算法的问题(12 August 2014 - Version 0.961 (C# only) - Fix problems with MiniMax algorithm)
- 2015年8月22日-版本0.971(C#不带GUI,带GUI,微型版)-提高算法性能,修复了"愚蠢的移动"过滤器等问题(22 August 2015 - Version 0.971 (C# without GUI, with GUI, Micro edition) - Improve algorithm performance, fixed “Stupid move” filter et cetera)
- 2015年8月28日-0.980版(C#不带GUI,带GUI,微型版)-修复了与检查和无效人员举动有关的错误,增加了``辞职'‘功能(28 August 2015 - Version 0.980 (C# without GUI, with GUI, Micro edition) - Fixed bugs related to check and invalid human moves, added the “resign” functionality)
- 2018年8月2日-0.990版(C#不带GUI,带GUI,微型版)-更新了引擎,修复了一些错误.(2 August 2018 - Version 0.990 (C# without GUI, with GUI, Micro edition) - Updated engine, fixed bugs.)
- 2019年2月12日:发布了0.991版(C#),包括开发人员版.(12 February 2019: Version 0.991 published (C#), including a Developers edition.)
版本控制(Versioning)
Huo Chess是智能设计的,但它也在发展.当前,该程序的版本为0.990.版本的时间线和在程序代码中进行的相应更改如下所示.(Huo Chess is intelligently designed, but it also evolves. Currently, the program is at version 0.990. The timeline of versions and the respective changes conducted in the program’s code are depicted below.)
版本0.991(C#)(Version 0.991 (C#)) | 修复了MinMax算法的一些问题,该算法现在可以按计划执行.再次增加了打开书的功能. [Visual Studio 2017](Fixed some issues with the MinMax algorithm, which now performs as planned. Added again the opening book capability. [Visual Studio 2017]) |
---|---|
版本0.990(C#)(Version 0.990 (C#)) | 更新了引擎.修正错误. [Visual Studio 2015/2017](Updated engine. Fixed bugs. [Visual Studio 2015/ 2017]) |
版本0.980(C#)(Version 0.980 (C#)) | 修复了与检查和无效人员移动有关的错误,添加了"辞职"功能[Visual Studio 2013/2015](Fixed bugs related to check and invalid human moves, added the “resign” functionality [Visual Studio 2013/ 2015]) |
版本0.971(C#)(Version 0.971 (C#)) | 修复了节点分析:为每个级别创建了一个不同的NodesAnalysis数组.修复了错误,以便分析能够正确存储值,并且MiniMax算法会按预期执行.修复了计算机移动的"愚蠢移动"过滤器.修复了"回食的可能性"功能. [Visual Studio 2013/2015](Fixed the Nodes Analysis: Created a different NodesAnalysis array for each level. Fixed bugs so that the analysis stores correctly the values and the MiniMax algorithm performs as it should. Fixed the “Stupid move” filter for the computer moves. Fixed the “Possibility to eat back” functionality. [Visual Studio 2013/ 2015]) |
版本0.961(C#)(Version 0.961 (C#)) | Huo Chess 0.961中的更改:修复了与MiniMax算法有关的问题和错误.(Changes in Huo Chess 0.961: Fixed problems and bugs related to the MiniMax algorithm.)[Visual Studio 2012]([Visual Studio 2012]) |
0.95版(C#)(Version 0.95 (C#)) | Huo Chess 0.95中的更改:(Changes in Huo Chess 0.95:) |
1.将CountScore和CountScore_Human合并到一个函数中.还向该函数添加了参数,以便更好地控制其参数化.(1. Merged the CountScore and CountScore_Human in one function. Also added parameters to the function so as to better control its parameterization.) | |
2.添加了在棋盘上查找危险方块的功能(请参阅FindAttackers和FindDefenders函数).在CountScore函数中添加了"危险"检查.这将检查一个正方形中的棋子是否受到一个或多个对手的威胁(请参阅DangerWeight变量)(2. Added functions to find the dangerous squares in the chessboard (see FindAttackers and FindDefenders functions). Added a “danger” check in the CountScore function. This will check whether the piece in a square is threatened by one or more pieces of the opponent (see DangerWeight variable)) | |
3.删除了未使用的变量以消除所有警告.维护指数达到19(以前版本中为16).(3. Removed unused variables to eliminate all warnings. Reach a Maintenance Index of 19 (from 16 in the previous versions).) | |
4.修复了程序中考虑到Danger_penalty的问题(并删除了在某些地方使用过的引起危险的相似的anger_penalty,实际上使CountScore中的Danger_penalty的影响无效)(4. Fixed the program to take into account Danger_penalty (and removed the similar danger_penalty which was used in some places and caused confusion, actually nulling the effect of Danger_penalty in CountScore)) | |
5.在ComputerMove中取消注释"在Skakiera(y,u)中查找件的值"部分,以便找到Value_of_piece_in_square的值.+++(5. Uncomment the “Find value of piece in Skakiera(y,u)” part in ComputerMove, so as to find the value of Value_of_piece_in_square.+++) | |
大小:57 KB(无GUI),93 KB(有GUI)(Size: 57 KB (without GUI), 93 KB (with GUI)) | |
0.93版本(仅C#)(0.93 Versions (only C#)) | 实现了MiniMax思维算法.分发两种类型的版本:(Implemented the MiniMax algorithm for thinking. Two types of versions are distributed:) |
- Huo Chess(Kakos-MiniMax版):使用现有的深度搜索Kakos算法的版本,并添加了MiniMax算法以评估最佳移动.(Huo Chess (Kakos-MiniMax edition): A version where the existing Kakos algorithm for searching in depth is used, with the MiniMax algorithm added for the evaluation of the best move.)
- Huo Chess(Simple-MiniMax):一种新的简单版本,其中从头开始编写了深度搜索(以尝试"清理"代码). MiniMax算法再次用于评估最佳移动.在这种更简单的方法中,进行了以下更改:删除了(Huo Chess (Simple-MiniMax): A new simpler version where the searching in depth has been written from scratch (in an attempt to “clean” the code). MiniMax algorithm is again used for the evaluation of the best move. In this simpler method, the following changes have taken place: Deleted the)
CheckMove
,CountScore_Human
,HumanMove
,CheckHumanMove HumanMove_template
功能.重组并简单地将思考深度从8增加到20.(functions. Reorganized and simply Increased thinking depths from 8 to 20. Reduced the size by using a template)ComputerMove
具有所有思考深度的功能(而不是(function for all thinking depths (instead of)ComputerMove2
,ComputerMove4
,ComputerMove6
等). C ++版本仍为0.81版本(单独(, etc.). The C++ edition is still in 0.81 version (separate)ComputerMove
功能仍然存在),并且XNA/VB版本仍为0.82版本,并且仍出于教育目的而分发. C#版本的大小:52.5 KB.(functions still exist) and XNA / VB versions are still in 0.82 versions and are still distributed for educational purposes. Size of C# edition: 52.5 KB.) | |版本0.82(Version 0.82)|改变了(Changed the)ComputerMove
,HumanMove
,CountScore
,ElegxosOrthotitas
功能.思维深度从8增加到20.使用模板减小了尺寸(functions. Increased thinking depths from 8 to 20. Reduced the size by using a template)ComputerMove
具有所有思考深度的功能(而不是(function for all thinking depths (instead of)ComputerMove2
,ComputerMove4
,ComputerMove6
等等). C ++版本仍为0.81版本(单独(etc). The C++ edition is still in 0.81 version (separate)ComputerMove
功能仍然存在),用于教育目的. C#版本的大小:52.5 KB.(functions still exist), for educational purposes. Size of C# edition: 52.5 KB.)| |版本0.722 XNA(Version 0.722 XNA)|具有基于XNA的图形用户界面的Huo Chess(C#版).(Huo Chess (C# edition) with Graphical User Interface based on XNA.)| |版本0.722 CS(Version 0.722 cs)|C#编程语言中的Huo Chess端口.(Huo Chess port in C# programming language.)| |版本0.722(Version 0.722)|修复了一些问题(Fixed some issues with the)HumanMove
function.| |版本0.721(Version 0.721)|该程序增加了更多的思考深度分析功能. Huo Chess使用(More thinking depth analysis capability has been added to the program. Huo Chess uses the)ComputerMove2
,ComputerMove4
,ComputerMove6
andComputerMove8
可以思考8个动作的深度(白色为4个半动作,黑色为4个半动作).大小:56.5 KB(functions to think at a depth of 8 moves (4 half-moves for the white and 4 half-moves for the black pieces). Size: 56.5 KB)| |0.6版(微型版)(Version 0.6 (Micro edition))|它基于0.6版.减少所有字符串/文本(即" White Rook" =>" WR").减少了变量名的长度(在程序中的每个变量中,特定的字符串都被较小的字符串替换了).图标被替换为较小的图标.删除了所有不必要的文件(资源,(It was based on version 0.6. Reduced all string/text (i.e. “White Rook” => “WR”). Reduced the length of variable names (in every variable in the program, specific strings were replaced with smaller ones). Icon was replaced with smaller one. Removed all unnecessary files (resources,)assembly.cpp,stdafx等).大小:47.5 KB(, stdafx, etc.). Size: 47.5 KB)| |版本0.6(Version 0.6)|删除了3959行中的空try … catch语句(Removed the empty try…catch statement in line 3959 at)HumanMove
,导致在(, which caused the bug at)ElegxosNomimotitas
不显示.优化了(not to show. Optimized the)CountScore
功能.修复了错误(function. Fixed the bug at)ElegxosNomimotitas
在第3143-32173行中检查Rook-Queen-Bishop动作的部分.如果计算机将其棋子移到对手的棋子旁边,则会加重惩罚.有机会让计算机吃掉对手的女王.降低对手国王的价值,以免计算机不断追随他并为此而牺牲碎片.优化了(in the part that checks moves of Rook-Queen-Bishop at lines 3143-32173. Added penalty in case the computer moves its pieces next to an opponent’ pawn. Made the computer eat the opponent’s queen when there is a chance. Lowered the value of the opponent’s king, so as to avoid the computer continuously going after him and sacrifice pieces for that. Optimized the)CountScore_Human
功能.大小:53.5 KB(function. Size: 53.5 KB)| |版本0.5(Version 0.5)|FixedHumanMove
功能.优化(function. Optimized)CountScore
andComputerMove
功能.大小:51.5 KB(functions. Size: 51.5 KB)| |版本0.4(Version 0.4)|增加了随机播放功能.优化(Added random playing capability. Optimized)CheckForWhiteCheck
andCheckForBlackCheck
功能.大小:51.0 KB(functions. Size: 51.0 KB)| |版本0.3(Version 0.3)|播放能力更强.新增了开本功能.优化(Stronger playing capabilities. Added opening book capability. Optimized)ElegxosNomimotitas
andElegxosOrthotitas
功能.大小:91.5 KB(functions. Size: 91.5 KB)| |0.2版(Version 0.2)|修复了由于计算机进行非法移动而导致的一些错误.感谢所有给我反馈的人!大小:99.5 KB(Fixed some bugs due to which computer played illegal moves. Thanks to everyone who gave me feedback! Size: 99.5 KB)| |版本0.1(Version 0.1)|初始版本.已知问题:该程序有时会进行一些非法动作.一点也不强. 49.0 KB(Initial version. Known problems: the program plays some illegal moves sometimes. Not too strong at all. 49.0 KB)|
++继续编码!(++Keep coding!)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C++ C# VC8.0 Windows Vista Win32 VS2008 Dev Microsoft JSON 新闻 翻译