/** validState * * Check for a valid board position to play from: * (1) Number of balls for each color has to be between 9 and 14 * (2) There must be a move possible for actual color */ int Board::validState() { MoveCounter mc; int c1 = 0, c2 = 0; int i,j, moveCount, res; int color = actColor(); for(i=0; i<AllFields; i++) { j=field[i]; if (j == color1) c1++; if (j == color2) c2++; if (j == color) countFrom( i, color, mc); } color1Count = c1; color2Count = c2; moveCount = mc.moveSum(); if (c1==0 && c2==0) res = empty; // impossible token counts else if (c1>14 || c2>14 || (c1<9 && c2<9)) res = invalid; else if (c1<9) res = win2; else if (c2<9) res = win1; // counts are in valid range... else if (moveCount>0) { if (color == color1) { if (_msecsToPlay[color1]>0 && _msecsToPlay[color2]<=0) res = timeout2; else res = valid1; } else { if (_msecsToPlay[color2]>0 && _msecsToPlay[color1]<=0) res = timeout1; else res = valid2; } } // color which has to draw can not do any move... win for opponent! else if (color == color1) res = win2; else res = win1; #ifdef MYTRACE if (spyLevel>2) { indent(spyDepth); printf("Valid: %s (Color1 %d, Color2 %d, moveCount of %d: %d)\n", (res == empty) ? "empty" : (res==valid) ? "valid":"invalid", c1,c2,color,moveCount); } #endif return res; }
/** validState * * Check for a valid board position to play from: * (1) Number of pieces for each color has to be between 9 and 14 * (2) There must be a move possible for actual color */ int Board::validState() { MoveTypeCounter tc; InARowCounter cc; int c1 = 0, c2 = 0; int i,j, moveCount, res; for(i=0;i<AllFields;i++) { j=field[i]; if (j == color1) c1++; if (j == color2) c2++; if (j == color) countFrom( i, color, tc, cc); } color1Count = c1; color2Count = c2; moveCount = tc.sum(); if (c1==0 && c2==0) res = empty; else if (c1>8 && c1<15 && c2>8 && c2<15 && moveCount>0 ) res = valid; else res = invalid; #ifdef MYTRACE if (spyLevel>2) { indent(spyDepth); qDebug("Valid: %s (Color1 %d, Color2 %d, moveCount of %d: %d)\n", (res == empty) ? "empty" : (res==valid) ? "valid":"invalid", c1,c2,color,moveCount); } #endif return res; }
/* Calculate a evaluation for actual position * * A higher value means a better position for opponent * NB: This means a higher value for better position of * 'color before last move' */ int Board::calcEvaluation() { MoveTypeCounter tcColor, tcOpponent; InARowCounter ccColor, ccOpponent; int f,i,j; // if not yet set, use default scheme if (!_evalScheme) setEvalScheme(); /* different evaluation types */ int fieldValueSum=0, stoneValueSum=0; int moveValueSum=0, inARowValueSum=0; int valueSum; /* First check simple winner condition */ if (color1Count <9) valueSum = (color==color1) ? 16000 : -16000; else if (color2Count <9) valueSum = (color==color2) ? 16000 : -16000; else { /* Calculate fieldValueSum and count move types and connectivity */ for(i=0;i<RealFields;i++) { j=field[f=order[i]]; if (j == free) continue; if (j == color) { countFrom( f, j, tcColor, ccColor ); fieldValueSum -= fieldValue[i]; } else { countFrom( f, j, tcOpponent, ccOpponent ); fieldValueSum += fieldValue[i]; } } /* If color can't do any moves, opponent wins... */ if (tcColor.sum() == 0) valueSum = 16000; else { for(int t=0;t < Move::typeCount;t++) moveValueSum += _evalScheme->moveValue(t) * (tcOpponent.get(t) - tcColor.get(t)); for(int i=0;i < InARowCounter::inARowCount;i++) inARowValueSum += _evalScheme->inARowValue(i) * (ccOpponent.get(i) - ccColor.get(i)); if (color == color2) stoneValueSum = _evalScheme->stoneValue(14 - color1Count) - _evalScheme->stoneValue(14 - color2Count); else stoneValueSum = _evalScheme->stoneValue(14 - color2Count) - _evalScheme->stoneValue(14 - color1Count); valueSum = fieldValueSum + moveValueSum + inARowValueSum + stoneValueSum; } } #ifdef MYTRACE if (spyLevel>2) { indent(spyDepth); qDebug("Eval %d (field %d, move %d, inARow %d, stone %d)\n", valueSum, fieldValueSum, moveValueSum, inARowValueSum, stoneValueSum ); } #endif return valueSum; }