我将编写一个国际象棋服务器和一个或多个国际象棋客户端,我想用编程语言独立的方式描述国际象棋的规则(例如基于游戏状态的允许移动,游戏完成时的规则).这有点棘手,因为一些国际象棋规则(例如King Castling,en passent,基于3次或更多次重复动作绘制)不仅基于棋盘布局而且基于移动历史.
我希望格式为:
但我愿意牺牲其中任何一种来获得合适的解决方案.
我的主要问题是:如何构建如此复杂的算法,从数据格式对这种复杂状态进行操作?
后续问题是:您能否以类似的方式提供类似问题的示例,以此作为起点?
编辑:为了回应清晰的要求 - 考虑我将用Python编写的服务器,一个用C#编写的客户端和另一个用Java编写的客户端.我想避免在每个地方指定规则(例如,允许的棋子移动,检查的情况等).我宁愿以语言独立的方式指定这些规则.
我在上个月用c#创建了一个简单的国际象棋引擎,并取得了一些不错的进展.它使用简单的Alpha-Beta算法.
为了纠正Horizon-Effect,我试图实现静态搜索(并在它工作之前多次失败).发动机的强度似乎有点改善了安静,但速度非常慢!
在此之前,我可以在大约160秒(在游戏中期的某个地方)搜索6层深度,通过静态搜索,计算机需要大约80秒才能在搜索深度3上移动!
蛮力节点计数器在深度3处大约20000个节点,而静态节点计数器高达2000万!
由于这是我的第一个国际象棋引擎,我真的不知道这些数字是否正常,或者我是否在我的静止算法中犯了错误.如果有经验的人能告诉我BF节点/静态节点的通常比例是多少,我将不胜感激.
顺便说一句,看看:(每当searchdepth为0时,此方法由BF树调用)
public static int QuiescentValue(chessBoard Board, int Alpha, int Beta)
{
QuiescentNodes++;
int MinMax = Board.WhoseMove; // 1 = maximierend, -1 = minimierend
int Counter = 0;
int maxCount;
int tempValue = 0;
int currentAlpha = Alpha;
int currentBeta = Beta;
int QuietWorth = chEvaluation.Evaluate(Board);
if(MinMax == 1) //Max
{
if (QuietWorth >= currentBeta)
return currentBeta;
if (QuietWorth > currentAlpha)
currentAlpha = QuietWorth;
}
else //Min
{
if (QuietWorth <= currentAlpha)
return currentAlpha;
if (QuietWorth …
Run Code Online (Sandbox Code Playgroud) 在许多在线国际象棋游说中,我见过"引擎"的例子,骗子会在主游戏窗口的同时打开国际象棋程序.然后他会设置它以便将对手的动作转发到计算机,然后他将复制计算机的动作,直到他(几乎总是)获胜.
作为游戏开发者和主持人,有什么办法可以解决这个问题?
首先:如果这是重复的帖子,请道歉.当我试图同时发布/注册时,事情变得有点混乱.
我开始研究从一个简单的WPF窗口运行UCI国际象棋引擎,让国际象棋引擎在与该界面不同的线程上运行,并创建了一个合理可维护的基于文本的前端.
我现在变得更加雄心勃勃了,并希望开始构建一个带有国际象棋棋子的GUI,它将为玩家提供棋子引擎的动作,并代表引擎在棋盘上的动作.我的目标是可拖动的碎片,而不是点击方块.
我目前的尝试涉及在<canvas>元素上使用可拖动的用户控件.我真的很想知道其他更有经验的WPF/.NET程序员会如何处理这个问题,因为我并不完全相信我是在正确的轨道上.
例如:使用统一网格并在子元素之间拖动数据会更好吗?我应该创建一个抽象的"片段"类,如棋子可以衍生出来吗?那种事.
有什么想法吗?这不是一个家庭作业或任何事情,只是我在业余时间作为练习在我身边徘徊.
我有一个基础类
class piece;
Run Code Online (Sandbox Code Playgroud)
以及包含派生对象的数组
piece* board[8][8];
Run Code Online (Sandbox Code Playgroud)
优势,通过虚拟功能进行清洁设计.缺点,如果我必须在板上找到一块或比较一件我必须恢复到动态铸造(或typeid).它很丑陋,在制作数百万个请求时可能会很糟糕.
另一方面,如果我创建一个单件类的数组,它有一个用于识别片段的类型字段,我没有这个问题(它应该更快)但我必须制作超级丑陋的switch语句.我想,由于件数是有限的,我不认为自己制造了那么多开关,这可能最终是一个更好的选择,你怎么看?
这很有趣(所以没有位板).
编辑1
阅读一些答案,我认为仅使用类型字段进行运算符重载(==,!= ...)可以带来两个单词的最佳效果.
boost :: variant看起来也很有趣.
我只是试图使用java在eclipse中显示一些unicode象棋符号,但是它只是打印出随机矩形,除非棋子最近在样式上进行了彻底改变 - 我不认为它是我想要的.非常感谢帮助!
我的代码:
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
public class ChessSymbols {
public static void main (String [ ] args)throws
UnsupportedEncodingException {
String unicodeMessage =
"\u2654 " + // white king
"\u2655 " + // white queen
"\u2656 " + // white rook
"\u2657 " + // white bishop
"\u2658 " + // white knight
"\u2659 " + // white pawn
"\n" +
"\u265A " + // black king
"\u265B " + // black queen
"\u265C " + // black …
Run Code Online (Sandbox Code Playgroud) 在Clojure(/ Java)中表示国际象棋比特的一些可能方法是什么?
http://pages.cs.wisc.edu/~psilord/blog/data/chess-pages/rep.html
我需要能够访问各个位并执行按位操作.
我想过使用java.lang.Long,但由于标牌,这导致了1x10 ^ 63的问题.我也不确定如何在特定索引处访问位?
我也看了BitSet,但理想情况下我需要一个固定的长度.
我正在尝试开发一个简单的国际象棋引擎,但我正在努力实现其性能.我已经使用alpha-beta修剪和迭代加深实现了Negamax(没有任何额外的启发式),但是我无法获得超过3-4层的合理搜索时间.以下是从游戏开始我的程序日志的摘录:
2013-05-11 18:22:06,835 [9] INFO CoevolutionaryChess.Engine.MoveSearchers.NegamaxMoveSearcher [(null)] - Searching at depth 1
2013-05-11 18:22:06,835 [9] DEBUG CoevolutionaryChess.Engine.MoveSearchers.NegamaxMoveSearcher [(null)] - Leaves searched: 28
2013-05-11 18:22:06,835 [9] DEBUG CoevolutionaryChess.Engine.MoveSearchers.NegamaxMoveSearcher [(null)] - Nodes searched: 28
2013-05-11 18:22:06,835 [9] DEBUG CoevolutionaryChess.Engine.MoveSearchers.NegamaxMoveSearcher [(null)] - Found PV: A4->A6
2013-05-11 18:22:06,835 [9] INFO CoevolutionaryChess.Engine.MoveSearchers.NegamaxMoveSearcher [(null)] - Searching at depth 2
2013-05-11 18:22:06,897 [9] DEBUG CoevolutionaryChess.Engine.MoveSearchers.NegamaxMoveSearcher [(null)] - Leaves searched: 90
2013-05-11 18:22:06,897 [9] DEBUG CoevolutionaryChess.Engine.MoveSearchers.NegamaxMoveSearcher [(null)] - Nodes searched: 118
2013-05-11 18:22:06,897 [9] DEBUG CoevolutionaryChess.Engine.MoveSearchers.NegamaxMoveSearcher [(null)] - …
Run Code Online (Sandbox Code Playgroud) 我刚开始开发Android应用程序(使用java,在Android工作室,如果这很重要),我正在做一个小项目,只是为了好玩.我想创建自己的国际象棋应用程序,到目前为止我做了很多事情.我设置了一个菜单切换到另一个活动,这是游戏本身,我用自绘板制作了一个自定义视图,我认为我的模型也差不多完整了.我唯一不明白的是如何处理阻力.因此,当您使用拖动手势将一个部件从一个位置移动到另一个位置时,您如何获得该部分的起点和终点?
如上所述,我已经在我的模型中实现了一个移动(带有一个函数移动(位置开始,位置结束)),它还检查该移动是否对某个部分有效,但我唯一需要的是让它我在实际的板上拖了一块.
我正在考虑在我的Controller类中放置一个onDrag方法,但我不知道如何解决这个问题,并且无法在互联网上找到好的例子.我已经开始了,但不知道它是否可行.
你能帮我实现拖拽吗?
提前致谢!
PS我还将在我的问题中添加自定义视图和(尚未完成)控制器的代码,如果这有帮助的话.如果您需要更多我的代码来回答这个问题,我也会把它放在这里,让我知道.
public class ChessView extends View implements Observer {
private Game game;
private static final Paint WHITE_PAINT = new Paint(), BLACK_PAINT = new Paint();
public ChessView(Context context) {
super(context);
init();
}
public ChessView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ChessView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public void init() {
WHITE_PAINT.setColor(Color.rgb(200, 159, 77));
BLACK_PAINT.setColor(Color.rgb(61, 34, 18));
}
public void setGame(Game game) {
if (this.game != null)
this.game.deleteObserver(this); …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个程序,用于计算国际象棋变体的终结表基础.填充tablebase的算法如下:
unsigned char
,每个成员代表一个位置(我们总是假设它是白色的).即使位置丢失也是数组成员,如果赢了则是奇数,如果它是0xff
无效的,0xfe
如果它是平局的话.0xff
,白色与其匹配的每个位置0x00
以及所有其他位置0x0fe
.0xfe
.检查是否存在是导致其数组成员为偶数的位置,如果有,写一加那个位置为对应于CURREN位置上的成员数量的举动.如果所有的移动导致由奇数显示位置(即这是一个失去位置),纪念这个位置一加最高这些数字来表示防御最强的花费多长时间.为了速度,我想并行化第三步.仔细阅读会产生在每次迭代中,我们只会将一个值(迭代次数)写入数组.以下策略获得:
0xfe
,因为这意味着该成员刚刚被另一个线程同时写入.现在显然这个程序中存在竞争条件,但是没关系,因为如果没有任何粉红色的大象(如果a char
是原子写的则不能存在),我们总能得到正确的结果.但是,由于在纸面上存在竞争条件,C编译器可能会声明我的程序未定义并格式化我的硬盘.
如何在不违反C内存模型的任何约束的情况下并行化此算法并且不会导致大量减速(例如通过添加锁定),我该怎么做?
这是一个简化的算法,它演示了相同的概念,但剥离了所有不重要的东西:
unsigned char a[n]
.每个数组成员都是0或1.由于我们只将0更改为2,因此我们处理数组条目的顺序并不重要,即使我们并行执行竞争条件(因为我们同时读取/写入相同的对象) .如何在不牺牲性能的情况下告诉编译器它不应该关心竞争条件?
chess ×10
java ×4
c# ×2
algorithm ×1
android ×1
c ×1
c++ ×1
clojure ×1
concurrency ×1
dataformat ×1
eclipse ×1
inheritance ×1
online-game ×1
oop ×1
python ×1
tearing ×1
unicode ×1
wpf ×1