2012-09-12 112 views
2

我正在制作一个国际象棋游戏,用OpenGL渲染。C++/OpenGL国际象棋游戏程序设计建议

我不是在找人告诉我所有的答案,我想要自己的代码出来,但指出我正确的概念是我真正需要的。在这一点上,我不确定从哪里开始。这里是我已经想通了:

枚举,TurnState,具有以下值:

  • playerOneTurn
  • playerTwoTurn
  • Stopped

枚举,GameState,与以下值:

  • playerOneCheck
  • playerTwoCheck
  • playerOnecCheckMate
  • PlayerTwoCheckMate
  • InitializingGame
  • Tie
  • NormalPlay

抽象类,Player,和一个子类,Computer

类,ChessGame,具有以下字段:

Player p1, p2 
TurnState turnState 
GameState gameState 

类,Move,具有以下字段:

*Piece 
Location origin 
Location destination 

类,Location,具有以下字段:

row 
col 
*ChessBoard 

A class,ChessBoard,使用一种方法isValid,它需要Move并检查移动是否有效。

一个抽象类,ChessPieces,用下面的方法:

GetValue()  // returns an int value of the piece (for scoring) 
GetPosition() // returns the current position of a piece 
getIsSelected() // returns a boolean, true if selected, false if unselected 
move()   // moves the piece in a way dependent upon what piece 

而下面的子类:

  • Pawn
  • Rook
  • Queen
  • King
  • Knight
+0

堆栈溢出的格式,减价,搞砸了原来的格式。我已经将其编辑为更具可读性,但您可能需要进一步编辑它。 – icktoofay

回答

3

至于棋局的AI部分:

要获得国际象棋AI,或任何类型的回合制游戏AI,你将需要计算的“价值”在某一回合中的游戏(这很重要)(即你为每个棋子分配一个值,然后将player1和player2的值相加,然后你得分= player1score - player2score,所以负值有利于玩家2和正面玩家,玩家1,这仅仅是一个基本的例子,而不是一个非常有效的例子,但它是解释游戏“价值”的最基本方式)。

之后你可以计算出你需要能够计算给定板的某种配置的玩家的每一个可能的移动。

这样你就可以建立一个决策树,在这棵树中你将拥有当前游戏状态的根节点。树的下一个“级别”将表示您可以从当前状态(等等)获得的每种可能状态。重要的是要注意,如果你考虑玩家1可能在树的等级上的移动,你会考虑玩家在下一个可能的移动。

接下来要做的是:

假设PLAYER1是会做出的举动,他将考虑在树上,直到深度5(用于一盘棋,你永远不会看在整个树)。所以他会选择一个会为他优化的举动,这意味着:在每个级别他都会考虑他的最佳举动或者player2的最佳举措(所以他会在最坏的情况下工作),所以他会把树的下一级中最高值的节点。

要计算节点的值,请执行以下操作: 注意:考虑根节点的深度为0,每个奇数深度节点需要为player1的maxValue和player2的每个偶数深度节点minValue。

您会将树扩展到您定义的最大深度,对于maxDepth中的节点,您只需计算板的值(我在回答的开头提到),对于上层节点,会做:

即使节点的值:minValue(最小值)的所有子节点之间 奇节点的值:包括maxValue所有子节点之间

所以基本上你会做回归查找节点的基础上的价值的价值更深的节点。那么,你可以研究一些其他的东西,如果你想你可以PM我,我已经做了一些关于这种搜索的工作,我只是在这里描述了最基本的想法,为了获得高效的代码,您需要大量的优化技术。

希望它有一点帮助

1

首先:分开两个:AI和GUI/OpenGL。在国际象棋中,在两个不同的进程与预定义的协议进行通信时,将GUI和AI(计算机国际象棋术语中的“引擎”)置于正常状态是正常的。这两个最流行的协议是UCI和WinBoard。

对于国际象棋引擎的一部分,你基本上需要三个东西:

  1. 一个板/位置表示
  2. 叶节点评价函数
  3. 一个搜索算法

我建议你阅读:

  1. Chess Programming WIKI
  2. TalkChess forum for computer chess
  3. 研究的一个开放源计算机下棋发动机,如鳕鱼干,狡猾或水果。
0

这可能不是直接回答你的问题(实际上你的问题是什么?),但你提到你想要的是指向正确概念的指针。

oysteijo是对的,其中一个非常重要的概念是将程序的各个部分彼此分开。

对于像国际象棋这样的事情,国际象棋游戏存在许多高效优雅的表现形式。我会说MVC(模型,视图,控制器)设计模式对于象棋游戏来说工作得很好。

希望这会有所帮助,如果不是的话,我建议你再阅读一下MVC。

您的模型将主要涉及存储游戏状态表示的数据结构,这是棋盘。一件作品只能在64个作品中的一个作品上,而作品的种类,作品的种类以及作品的种类都有限制。该模型将负责处理这些东西。为模型提供确定任何给定移动的合法性的逻辑(即游戏的属性不一定涉及任何给定游戏实例的状态)也是有意义的。

该视图是所有与演示相关的代码所在的位置。所有这些OpenGL都会在这里进行,就像一个“调试”例程,它可能(例如)将棋盘的ASCII表示打印到控制台。

控制器可能有一些与用户接口来处理输入的功能。控制器是操纵模型的代码(“将E5移动到D3”:控制器中的一个函数可能调用model.moveKnight('D3'))和视图(“以光荣的3D绘制板子”:控制器可能会执行一些操作,如调用openGLView.draw(model)

MVC帮助实现的主要目标之一是独立执行不同任务的代码部分。如果AI中的某些变化导致渲染算法出现问题,那么这是一个令人沮丧和困难的位置。有经验的程序员会花费很大的精力确保不会发生这种情况。

在这一点上,你可能想知道你的AI代码适合图片。那么,这真的取决于你。用你最好的判断力。它可能是控制器的一部分。我个人认为它是一个完整的控制器(chessAIController),它实现了AI算法,但它很容易包含在主控制器中。

问题是,只要以某种逻辑方式完成代码,实际上如何组织代码并不重要。 MVC如此广泛的原因在于,这3个组件通常存在于大多数软件中,通常将它们分开是有意义的。注意它们实际上并没有真正分开......控制器通常直接操纵视图和模型。诸如不允许视图操纵任何东西的限制有助于代码保持干净和清晰。

当你在编程项目中没有结构或组织也可以是几乎不可能的,以避免巨大的程序里面做一切的一点点,因为真的是有在其中在建立功能的代码只有一个地方。这一切产生的总是大量的意大利面条代码,无论语言水平如何高,都无法使您摆脱困境。这会创建一些简单的代码,因为没有其他人能够理解它,甚至连编写它两周后你都无法理解它。