// best tactical result for the moving side Score StaticExchangeEvaluation(Board &board, Move mv) { board.ResetSee(); // convert the move to SEE format PieceType pt; Square from; Square to; pt = GetPieceType(mv); from = GetFromSquare(mv); to = GetToSquare(mv); PieceType capturedPT = board.ApplyMoveSee(pt, from, to); // the first move is forced Score ret = 0; if (capturedPT != EMPTY) { ret = SEE_MAT[capturedPT] - StaticExchangeEvaluationSq(board, to); } else { ret = -StaticExchangeEvaluationSq(board, to); } board.UndoMoveSee(); return ret; }
std::string GetMoveSAN(Position &position, const Move move) { const Square from = GetFrom(move); const Square to = GetTo(move); const Move moveType = GetMoveType(move); std::string result; if (moveType == MoveTypeCastle) { if (GetColumn(to) > FILE_E) { result = "O-O"; } else { result = "O-O-O"; } } else { // Piece that is moving const PieceType fromPieceType = GetPieceType(position.Board[from]); switch (fromPieceType) { case PAWN: break; case KNIGHT: result += "N"; break; case BISHOP: result += "B"; break; case ROOK: result += "R"; break; case QUEEN: result += "Q"; break; case KING: result += "K"; break; } Move legalMoves[256]; int legalMoveCount = GenerateLegalMoves(position, legalMoves); // Do we need to disambiguate? bool dupe = false, rowDiff = true, columnDiff = true; for (int i = 0; i < legalMoveCount; i++) { if (GetFrom(legalMoves[i]) != from && GetTo(legalMoves[i]) == to && GetPieceType(position.Board[GetFrom(legalMoves[i])]) == fromPieceType) { dupe = true; if (GetRow(GetFrom(legalMoves[i])) == GetRow(from)) { rowDiff = false; } if (GetColumn(GetFrom(legalMoves[i])) == GetColumn(from)) { columnDiff = false; } } } if (dupe) { if (columnDiff) { result += GetSquareSAN(from)[0]; } else if (rowDiff) { result += GetSquareSAN(from)[1]; } else { result += GetSquareSAN(from); } } else if (fromPieceType == PAWN && position.Board[to] != PIECE_NONE) { // Pawn captures need a row result += GetSquareSAN(from)[0]; } // Capture? if (position.Board[to] != PIECE_NONE || moveType == MoveTypeEnPassent) { result += "x"; } // Target square result += GetSquareSAN(to); } if (moveType == MoveTypePromotion) { switch (GetPromotionMoveType(move)) { case KNIGHT: result += "=N"; break; case BISHOP: result += "=B"; break; case ROOK: result += "=R"; break; case QUEEN: result += "=Q"; break; } } MoveUndo moveUndo; position.MakeMove(move, moveUndo); if (position.IsInCheck()) { Move checkEscapes[64]; result += GenerateCheckEscapeMoves(position, checkEscapes) == 0 ? "#" : "+"; } position.UnmakeMove(move, moveUndo); return result; }
bool StreetMap::GetRandomPavementArea(uint32_t x, uint32_t y, sm::Vec3 &position, sm::Vec3 &direction) { static Randomizer random; StreetPiece::PieceType type = GetPieceType(x, y); float streetWidth = 10.0f; float pavementWidth = 2.0f; switch (type) { case StreetPiece::PieceType_Pavement: return false; break; case StreetPiece::PieceType_StraightHori_1: position = sm::Vec3( x * streetWidth + random.GetFloat(-streetWidth / 2, streetWidth / 2), 0, y * streetWidth + random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * random.GetSign()); direction = sm::Vec3(MathUtils::Sign(random.GetFloat(-1, 1)), 0, 0); return true; case StreetPiece::PieceType_StraightVert_1: position = sm::Vec3( x * streetWidth + random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * random.GetSign(), 0, y * streetWidth + random.GetFloat(-streetWidth / 2, streetWidth / 2)); direction = sm::Vec3(0, 0, MathUtils::Sign(random.GetFloat(-1, 1))); return true; case StreetPiece::PieceType_TurnUpRight_1: if (random.GetInt(0, 1) == 1) { position = sm::Vec3( x * streetWidth + random.GetFloat(-streetWidth / 2, streetWidth / 2), 0, y * streetWidth + random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2)); } else { position = sm::Vec3( x * streetWidth + random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1, 0, y * streetWidth + random.GetFloat(-streetWidth / 2, streetWidth / 2)); } direction = sm::Vec3(0, 0, MathUtils::Sign(random.GetFloat(-1, 1))); return true; case StreetPiece::PieceType_TurnUpLeft_1: if (random.GetInt(0, 1) == 1) { position = sm::Vec3( random.GetFloat(-streetWidth / 2, streetWidth / 2), 0, random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1); } else { position = sm::Vec3( random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1, 0, random.GetFloat(-streetWidth / 2, streetWidth / 2)); } position = Street::Instance->GetStreetPiece((uint8_t)type)->GetTransform() * position; position.x += streetWidth * x; position.z += streetWidth * y; direction = sm::Vec3(0, 0, MathUtils::Sign(random.GetFloat(-1, 1))); return true; case StreetPiece::PieceType_TurnDownRight_1: if (random.GetInt(0, 1) == 1) { position = sm::Vec3( random.GetFloat(-streetWidth / 2, streetWidth / 2), 0, random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1); } else { position = sm::Vec3( random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1, 0, random.GetFloat(-streetWidth / 2, streetWidth / 2)); } position = Street::Instance->GetStreetPiece((uint8_t)type)->GetTransform() * position; position.x += streetWidth * x; position.z += streetWidth * y; direction = sm::Vec3(0, 0, MathUtils::Sign(random.GetFloat(-1, 1))); return true; case StreetPiece::PieceType_TurnDownLeft_1: if (random.GetInt(0, 1) == 1) { position = sm::Vec3( random.GetFloat(-streetWidth / 2, streetWidth / 2), 0, random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1); } else { position = sm::Vec3( random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1, 0, random.GetFloat(-streetWidth / 2, streetWidth / 2)); } position = Street::Instance->GetStreetPiece((uint8_t)type)->GetTransform() * position; position.x += streetWidth * x; position.z += streetWidth * y; direction = sm::Vec3(0, 0, MathUtils::Sign(random.GetFloat(-1, 1))); return true; case StreetPiece::PieceType_Cross_1: break; case StreetPiece::PieceType_TUp_1: position = sm::Vec3( x * streetWidth + random.GetFloat(-streetWidth / 2, streetWidth / 2), 0, y * streetWidth + random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1); direction = sm::Vec3(MathUtils::Sign(random.GetFloat(-1, 1)), 0, 0); return true; case StreetPiece::PieceType_TDown_1: position = sm::Vec3( x * streetWidth + random.GetFloat(-streetWidth / 2, streetWidth / 2), 0, y * streetWidth + random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * 1); direction = sm::Vec3(MathUtils::Sign(random.GetFloat(-1, 1)), 0, 0); return true; case StreetPiece::PieceType_TLeft_1: position = sm::Vec3( x * streetWidth + random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * 1, 0, y * streetWidth + random.GetFloat(-streetWidth / 2, streetWidth / 2)); direction = sm::Vec3(MathUtils::Sign(random.GetFloat(-1, 1)), 0, 0); return true; case StreetPiece::PieceType_TRight_1: position = sm::Vec3( x * streetWidth + random.GetFloat(streetWidth / 2 - pavementWidth, streetWidth / 2) * -1, 0, y * streetWidth + random.GetFloat(-streetWidth / 2, streetWidth / 2)); direction = sm::Vec3(MathUtils::Sign(random.GetFloat(-1, 1)), 0, 0); return true; case StreetPiece::PieceType_Skycrapper_1: case StreetPiece::PieceType_Skycrapper_2: case StreetPiece::PieceType_Skycrapper_3: break; default: break; } return false; }