The board and pieces are those of orthodox Chess, but the players also each have a number of 'coins' in hand. For each piece you capture, you get one extra stone in hand.
The coins can affect the board in the following way: whenever a capture is made, the side that lost the piece can retaliate against the capturer by paying for its removal with coins. For this he will have to outbid the opponent, however, who can pay coins for the survival of the piece.
The bidding takes place 'double blind': both sides make their bid without the other seeing it, then the bids are revealed, and if the bids happen to be equal, or the piece's owner bids more, the piece stays. Otherwise it is removed. Both sides lose all the coins they have been bidding, also the side that lost. The players are aware of the number of coins they each have before the bidding starts.
That's all. What makes this essentially different from normal Chess is the fact that you don't take turns in bidding, but have to fix your own bid before you know what your opponent will be bidding. This makes that you cannot in advance know what the result of your 'move' will be; even if you bid so high that he cannot top you, you don't know with how much coins he will be left. So something else than minimax and alpha-beta will be needed to play this game!
My idea was to replace the minimax search by this:
Code: Select all
Search(int stm, int depth)
{
xstm = Opponent(stm);
bestScore = (depth > 0 ? -INF : Evaluate()); // stand pat
for(ALL_MOVES) {
if(!IsCapture && depth <= 0) continue; // no non-capts in QS
myMaxBid = coins[stm];
hisMaxBid = coins[xstm];
if(!IsCapture()) myMaxBid = hisMaxBid = 0; // no bidding on non-capt.
MakeMove(); // board only
for(myBid = 0; myBid <= myMaxBid; myBid++) {
for(hisBid = 0; hisBid <= hisMaxBid; hisBid++) {
coins[stm] -= myBid; coins[xstm -= hisBid;
outcomeScore[myBid][hisBid] = -Search(xstm); // recursion
coins[stm] += myBid; coins[xstm += hisBid;
}
}
UnMake();
score = Optimize(outcomeSore, myMaxBid, hisMaxBid);
if(score > bestScore) bestScore = score;
}
return bestScore;
}
Any comments or suggestions?