Algorithm 计算棋类材料组合数的简单方法

Algorithm 计算棋类材料组合数的简单方法,algorithm,chess,Algorithm,Chess,在国际象棋中,一个棋手可以有不同的材质组合,例如: “1个皇后,2个车,2个骑士,2个主教,8个兵+国王”是一个组合 如果玩家失去一个主教: “1个皇后,2辆车,2个骑士,1个主教,8个兵+国王”是另一个组合 …之后,如果一名兵被提升为骑士,则: “1个皇后,2辆车,3个骑士,1个主教,7个兵+国王”是另一个组合 好的,以下组合无效: “5个皇后,5个车,5个骑士,5个主教,2个兵+国王” 因为你缺少可以提升的棋子。(5个皇后=需要4个兵)(5辆车=需要3个兵),等等。所以需要4+3+3+3=1

在国际象棋中,一个棋手可以有不同的材质组合,例如:

“1个皇后,2个车,2个骑士,2个主教,8个兵+国王”是一个组合

如果玩家失去一个主教:

“1个皇后,2辆车,2个骑士,1个主教,8个兵+国王”是另一个组合

…之后,如果一名兵被提升为骑士,则:

“1个皇后,2辆车,3个骑士,1个主教,7个兵+国王”是另一个组合

好的,以下组合无效:

“5个皇后,5个车,5个骑士,5个主教,2个兵+国王”

因为你缺少可以提升的棋子。(5个皇后=需要4个兵)(5辆车=需要3个兵),等等。所以需要4+3+3+3=13个兵。由于棋盘上有2个棋子,那么最多可以提升6个棋子。无效

有多少种有效的材料组合? 我使用下面的C代码计算了8694个组合。问题是:

您是否找到更简单/有效的算法来计算它?(更少的周期、更少的计算、更清晰的代码等)。。。甚至是一个数学公式

total = 0;
for (queens=0;queens<=9;queens++)
for (rooks=0;rooks<=10;rooks++)
for (bishops=0;bishops<=10;bishops++)
for (knights=0;knights<=10;knights++)
for (pawns=0;pawns<=8;pawns++)
{
    pawnsRequested = 0;
    if (queens>1) pawnsRequested += queens - 1;
    if (rooks>2) pawnsRequested += rooks - 2;
    if (bishops>2) pawnsRequested += bishops - 2;
    if (knights>2) pawnsRequested += knights - 2;
    if (8-pawns < pawnsRequested) continue;
    total++;
}
printf("%i\n",total); 
total=0;

对于(queens=0;queens如果棋子类型是独立的,那么我们就可以进行乘法:10种可能是queens乘以11种可能是rooks,等等。然而,我们需要跟踪典当的使用情况。有一个数学技巧,我们可以将rooks的可能性编码为

3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8,
其中,
x
的幂表示使用的棋子数量,系数表示可能性的数量。这里有三种可能性不需要升级棋子(0,1,2),一种需要一个升级棋子(3),一种需要两个升级棋子(4),等等。现在我们可以将每种因素相乘(分别是皇后、车、主教、骑士、兵)

给你

1
x^8
的系数为54、135、261、443、693、1024、1450、1986、2648,总和为8694,这是
0
8
所需的典当数

  (2 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)