//**************************************************************************** //Copyright (C) 2005-2006 Beijing BlueDJ Technology Co.,Ltd. All rights reserved. //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either version 2 //of the License, or (at your option) any later version. //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. //You should have received a copy of the GNU General Public License //along with this program (in the file LICENSE.GPL); if not, write to the Free Software //Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //Please visit http://www.bluedj.com for more infomation about us. //Contact us at ggwizard@gmail.com or darkdong@gmail.com. //****************************************************************************/ #include #include "dmnrule.h" #include "dmnprofile.h" #include "jdebug.h" bool IsPlacable(PDominoChains pchains,unsigned char *pchCards,unsigned char chPages) { unsigned char root1,root2; root1 = DOMINO_CARD_GET1(pchains->root); root2 = DOMINO_CARD_GET2(pchains->root); DEBUG_OUTPUT(("IsPlacable pages=%d\n",chPages)); DEBUG_BUFFER(((char *)pchains,sizeof(DominoChains))); if(chPages == 0 || pchCards == NULL) return false; DEBUG_OUTPUT(("cards : ")); DEBUG_BUFFER(((char *)pchCards,chPages)); if(DOMINO_CARD_ERROR(root1) || DOMINO_CARD_ERROR(root2)) return true; unsigned char i,j=(root1==root2)?4:2; unsigned char num=0,chNumbers[5]={DOMINO_CARD_ERRORID,DOMINO_CARD_ERRORID,DOMINO_CARD_ERRORID,DOMINO_CARD_ERRORID,DOMINO_CARD_ERRORID}; unsigned char ch1,ch2; for(i=1;i<=j;i++) { ch2 = DOMINO_CARD_GET2(pchains->chLastCard[i]); if(!DOMINO_CARD_ERROR(ch2)) { chNumbers[num] = ch2; num ++; }else { if(i==1) { chNumbers[num] = root1; num ++; j = 2; }else if(i==2) { chNumbers[num] = root2; num ++; j = 2; }else { chNumbers[num] = root2; num ++; } } } for(j=0;jroot); root2 = DOMINO_CARD_GET2(pchains->root); if(root1 == root2 && DOMINO_ISCARD(pchains->chLastCard[1]) && DOMINO_ISCARD(pchains->chLastCard[2]) ) chMaxChains=4; if(!DOMINO_ISCARD(pchains->chLastCard[1])) { if(root1 == root2) chRet = (root1<<1); else chRet = root1; if(DOMINO_ISCARD(pchains->chLastCard[2])) { ch1 = DOMINO_CARD_GET1(pchains->chLastCard[2]); ch2 = DOMINO_CARD_GET2(pchains->chLastCard[2]); if(ch1 == ch2) chRet += (ch1<<1); else chRet += ch2; } return chRet; } if(!DOMINO_ISCARD(pchains->chLastCard[2])) { if(root1 == root2) chRet = (root1<<1); else chRet = root2; ch1 = DOMINO_CARD_GET1(pchains->chLastCard[1]); ch2 = DOMINO_CARD_GET2(pchains->chLastCard[1]); if(ch1 == ch2) chRet += (ch1<<1); else chRet += ch2; return chRet; } for(i=1;i<= chMaxChains;i++) { if(DOMINO_ISCARD(pchains->chLastCard[i])) { ch1 = DOMINO_CARD_GET1(pchains->chLastCard[i]); ch2 = DOMINO_CARD_GET2(pchains->chLastCard[i]); if(ch1 == ch2) chRet += (ch1<<1); else chRet += ch2; } } return chRet; } bool AppendCard2Chain(PDominoChains pchains,unsigned char chChainID,unsigned char chCard,unsigned char *pchCards,unsigned char chPages,bool bRemove) { //是自己手里的牌 unsigned char chPos=chPages+1, i,ch1,ch2; if(pchCards == NULL || chPages == 0) return false; for(i=0;i= chPages ) { DEBUG_OUTPUT(("is't hand-card\n")); return false; } unsigned char root1,root2; root1 = DOMINO_CARD_GET1(pchains->root); root2 = DOMINO_CARD_GET2(pchains->root); if(DOMINO_CARD_ERROR(root1) || DOMINO_CARD_ERROR(root2)) {//放置第一张牌 unsigned char chMaxCard=DOMINO_CARD_ERRORID; char chMax=-1; bool bDouble = false; for(i=0;i chMax) ) { bDouble = true; chMax = (ch1<<1); chMaxCard = *(pchCards+i); } if(ch1 != ch2 && !bDouble && ch1+ch2 > chMax) { chMax = ch1+ch2; chMaxCard = *(pchCards+i); } } if(chCard != chMaxCard) return false; pchains->root = chCard; if(bRemove) { *(pchCards+chPos) = *(pchCards+(chPages-1)); *(pchCards+(chPages-1)) = DOMINO_CARD_ERRORID; } pchains->chChainPages = 0; return true; } //是否能接上 if(chChainID > 4 || chChainID == 0) { DEBUG_OUTPUT(("error chain id %d \n",chChainID)); return false; } ch1 = DOMINO_CARD_GET1(chCard); ch2 = DOMINO_CARD_GET2(chCard); unsigned chLast2 = DOMINO_CARD_GET2(pchains->chLastCard[chChainID] ); if(DOMINO_CARD_ERROR(chLast2)) { if(chChainID > 2) { if(root1==root2 && DOMINO_ISCARD(pchains->chLastCard[1]) && DOMINO_ISCARD(pchains->chLastCard[2])) { chLast2 = root1; }else return false; }else if(chChainID == 1) chLast2 = root1; else chLast2 = root2; } if(ch1 == chLast2) { ; }else if(ch2 == chLast2) { chCard = DOMINO_CARD_REVERSE(chCard); }else return false; pchains->chLastCard[chChainID] = chCard; pchains->chain[pchains->chChainPages][DOMINOCHAINS_CHAIN_ID] = chChainID; pchains->chain[pchains->chChainPages][DOMINOCHAINS_CHAIN_CARD] = chCard; pchains->chChainPages ++; if(bRemove) { *(pchCards+chPos) = *(pchCards+(chPages-1)); *(pchCards+(chPages-1)) = DOMINO_CARD_ERRORID; } if(root1 != root2 && ch1==ch2) {//顶替root成为旋接牌 DominoChains tempc; unsigned char chTempCard,chNewChainIndex=0,chNewID = (chChainID==1)?2:1; memset(&tempc,DOMINO_CARD_ERRORID,sizeof(DominoChains) ); tempc.root = chCard; char chCurIndex = pchains->chChainPages+1; do { chTempCard = GetCardOnChain(pchains,chChainID,-1,&chCurIndex); if(DOMINO_ISCARD(chTempCard)) { chTempCard = DOMINO_CARD_REVERSE(chTempCard); tempc.chain[chNewChainIndex][DOMINOCHAINS_CHAIN_ID] = chNewID; tempc.chain[chNewChainIndex][DOMINOCHAINS_CHAIN_CARD] = chTempCard; tempc.chLastCard[chNewID] = chTempCard; chNewChainIndex ++; }else break; }while(chCurIndex >= 0); tempc.chain[chNewChainIndex][DOMINOCHAINS_CHAIN_ID] = chNewID; if(chChainID == 1) tempc.chain[chNewChainIndex][DOMINOCHAINS_CHAIN_CARD] = pchains->root; else tempc.chain[chNewChainIndex][DOMINOCHAINS_CHAIN_CARD] = DOMINO_CARD_REVERSE(pchains->root); tempc.chLastCard[chNewID] = DOMINO_CARD_REVERSE(pchains->root); chNewChainIndex ++; chCurIndex = 0; do { chTempCard = GetCardOnChain(pchains,chNewID,1,&chCurIndex); if(DOMINO_ISCARD(chTempCard)) { tempc.chain[chNewChainIndex][DOMINOCHAINS_CHAIN_ID] = chNewID; tempc.chain[chNewChainIndex][DOMINOCHAINS_CHAIN_CARD] = chTempCard; tempc.chLastCard[chNewID] = chTempCard; chNewChainIndex ++; }else break; }while(chCurIndex <= pchains->chChainPages); tempc.chChainPages = chNewChainIndex; memcpy(pchains,&tempc,sizeof(DominoChains)); } return true; } unsigned char GetCardOnChain(PDominoChains pchains,unsigned char chChainID,char chReqIndex,char *pchStartIndex) { if(chChainID == 0) { return pchains->root; } if(chChainID > 4 || pchains->chChainPages == 0 || pchains->chChainPages > DOMINO_DOUBLE9_CARDS) return DOMINO_CARD_ERRORID; if(abs(chReqIndex) > pchains->chChainPages || pchStartIndex < 0) return DOMINO_CARD_ERRORID; int start,index; if(chReqIndex < 0) { if(*pchStartIndex < pchains->chChainPages) start = *pchStartIndex; else start = pchains->chChainPages-1; index = -1; while(start>=0) { if(pchains->chain[start][DOMINOCHAINS_CHAIN_ID] == chChainID) { if(index == chReqIndex) { *pchStartIndex = start-1; return pchains->chain[start][DOMINOCHAINS_CHAIN_CARD]; } index --; } start --; } return DOMINO_CARD_ERRORID; }else { if(*pchStartIndex > pchains->chChainPages) return DOMINO_CARD_ERRORID; start = (*pchStartIndex); index = 1; while(startchChainPages) { if(pchains->chain[start][DOMINOCHAINS_CHAIN_ID] == chChainID) { // printf("find %d chain %d card %02x\n",chChainID,index,pchains->chain[start][DOMINOCHAINS_CHAIN_CARD]); if(index == chReqIndex) { *pchStartIndex = start+1; return pchains->chain[start][DOMINOCHAINS_CHAIN_CARD]; } index ++; } start ++; } return DOMINO_CARD_ERRORID; } return DOMINO_CARD_ERRORID; } unsigned char GetChainTotalPoints(PDominoChains pchains) { unsigned char root1,root2; root1 = DOMINO_CARD_GET1(pchains->root); root2 = DOMINO_CARD_GET2(pchains->root); if(DOMINO_CARD_ERROR(root1) || DOMINO_CARD_ERROR(root2)) return DOMINO_MAX_POINTS + 10; unsigned char i,chPoints=0,ch1,ch2,j=(root1==root2)?4:2; for(i=1;i<=j;i++) { ch1 = DOMINO_CARD_GET1(pchains->chLastCard[i]); ch2 = DOMINO_CARD_GET2(pchains->chLastCard[i]); if(!DOMINO_CARD_ERROR(ch2)) { if(ch1 == ch2) chPoints += (ch2<<1); else chPoints += ch2; }else if(i<=2) { if(root1 ==root2) chPoints += (root1<<1); else { if(i == 1) chPoints += root1; else chPoints += root2; } j = 2; } } return chPoints; }