github.com/frankkopp/FrankyGo@v1.0.3/internal/types/posValues.go (about) 1 // 2 // FrankyGo - UCI chess engine in GO for learning purposes 3 // 4 // MIT License 5 // 6 // Copyright (c) 2018-2020 Frank Kopp 7 // 8 // Permission is hereby granted, free of charge, to any person obtaining a copy 9 // of this software and associated documentation files (the "Software"), to deal 10 // in the Software without restriction, including without limitation the rights 11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 // copies of the Software, and to permit persons to whom the Software is 13 // furnished to do so, subject to the following conditions: 14 // 15 // The above copyright notice and this permission notice shall be included in all 16 // copies or substantial portions of the Software. 17 // 18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 // SOFTWARE. 25 // 26 27 package types 28 29 import ( 30 "github.com/frankkopp/FrankyGo/internal/assert" 31 ) 32 33 // PosMidValue returns the pre computed positional value 34 // for the piece on the given square in mid game 35 func PosMidValue(p Piece, sq Square) Value { 36 if assert.DEBUG { 37 assert.Assert(initialized, "Pos values have not been initialized. Please call types.Init() first.") 38 } 39 return posMidValue[p][sq] 40 } 41 42 // PosEndValue returns the pre computed positional value 43 // for the piece on the given square in end game 44 func PosEndValue(p Piece, sq Square) Value { 45 if assert.DEBUG { 46 assert.Assert(initialized, "Pos values have not been initialized. Please call types.Init() first.") 47 } 48 return posEndValue[p][sq] 49 } 50 51 // PosValue returns the pre computed positional value 52 // for the piece on the given square and given game phase 53 func PosValue(p Piece, sq Square, gp int) Value { 54 if assert.DEBUG { 55 assert.Assert(initialized, "Pos values have not been initialized. Please call types.Init() first.") 56 } 57 return posValue[p][sq][gp] 58 } 59 60 // initPosValues pre computes arrays containing the positional values of each piece 61 // for each square and game phase 62 func initPosValues() { 63 // all game phases 64 for pc := WhiteKing; pc <= BlackQueen; pc++ { 65 for sq := SqA1; sq <= SqH8; sq++ { 66 for gp := GamePhaseMax; gp >= 0; gp-- { 67 switch pc { 68 case WhiteKing: 69 posMidValue[pc][sq] = kingMidGame[63-sq] 70 posEndValue[pc][sq] = kingEndGame[63-sq] 71 posValue[pc][sq][gp] = calcPosValueWhite(sq, gp, &kingMidGame, &kingEndGame) 72 case WhitePawn: 73 posMidValue[pc][sq] = pawnsMidGame[63-sq] 74 posEndValue[pc][sq] = pawnsEndGame[63-sq] 75 posValue[pc][sq][gp] = calcPosValueWhite(sq, gp, &pawnsMidGame, &pawnsEndGame) 76 case WhiteKnight: 77 posMidValue[pc][sq] = knightMidGame[63-sq] 78 posEndValue[pc][sq] = knightEndGame[63-sq] 79 posValue[pc][sq][gp] = calcPosValueWhite(sq, gp, &knightMidGame, &knightEndGame) 80 case WhiteBishop: 81 posMidValue[pc][sq] = bishopMidGame[63-sq] 82 posEndValue[pc][sq] = bishopEndGame[63-sq] 83 posValue[pc][sq][gp] = calcPosValueWhite(sq, gp, &bishopMidGame, &bishopEndGame) 84 case WhiteRook: 85 posMidValue[pc][sq] = rookMidGame[63-sq] 86 posEndValue[pc][sq] = rookEndGame[63-sq] 87 posValue[pc][sq][gp] = calcPosValueWhite(sq, gp, &rookMidGame, &rookEndGame) 88 case WhiteQueen: 89 posMidValue[pc][sq] = queenMidGame[63-sq] 90 posEndValue[pc][sq] = queenEndGame[63-sq] 91 posValue[pc][sq][gp] = calcPosValueWhite(sq, gp, &queenMidGame, &queenEndGame) 92 case BlackKing: 93 posMidValue[pc][sq] = kingMidGame[sq] 94 posEndValue[pc][sq] = kingEndGame[sq] 95 posValue[pc][sq][gp] = calcPosValueBlack(sq, gp, &kingMidGame, &kingEndGame) 96 case BlackPawn: 97 posMidValue[pc][sq] = pawnsMidGame[sq] 98 posEndValue[pc][sq] = pawnsEndGame[sq] 99 posValue[pc][sq][gp] = calcPosValueBlack(sq, gp, &pawnsMidGame, &pawnsEndGame) 100 case BlackKnight: 101 posMidValue[pc][sq] = knightMidGame[sq] 102 posEndValue[pc][sq] = knightEndGame[sq] 103 posValue[pc][sq][gp] = calcPosValueBlack(sq, gp, &knightMidGame, &knightEndGame) 104 case BlackBishop: 105 posMidValue[pc][sq] = bishopMidGame[sq] 106 posEndValue[pc][sq] = bishopEndGame[sq] 107 posValue[pc][sq][gp] = calcPosValueBlack(sq, gp, &bishopMidGame, &bishopEndGame) 108 case BlackRook: 109 posMidValue[pc][sq] = rookMidGame[sq] 110 posEndValue[pc][sq] = rookEndGame[sq] 111 posValue[pc][sq][gp] = calcPosValueBlack(sq, gp, &rookMidGame, &rookEndGame) 112 case BlackQueen: 113 posMidValue[pc][sq] = queenMidGame[sq] 114 posEndValue[pc][sq] = queenEndGame[sq] 115 posValue[pc][sq][gp] = calcPosValueBlack(sq, gp, &queenMidGame, &queenEndGame) 116 default: 117 } 118 } 119 } 120 } 121 } 122 123 func calcPosValueBlack(sq Square, gamePhase int, posMidTable *[SqLength]Value, posEndTable *[SqLength]Value) Value { 124 return (Value(gamePhase)*posMidTable[sq] + (Value(GamePhaseMax-gamePhase) * posEndTable[sq])) / GamePhaseMax 125 } 126 127 func calcPosValueWhite(sq Square, gamePhase int, posMidTable *[SqLength]Value, posEndTable *[SqLength]Value) Value { 128 return (Value(gamePhase)*posMidTable[63-sq] + (Value(GamePhaseMax-gamePhase))*posEndTable[63-sq]) / GamePhaseMax 129 } 130 131 var ( 132 posMidValue = [PieceLength][SqLength]Value{} 133 posEndValue = [PieceLength][SqLength]Value{} 134 posValue = [PieceLength][SqLength][GamePhaseMax + 1]Value{} 135 136 // positional values for pieces 137 // @formatter:off 138 // PAWN Tables 139 pawnsMidGame = [SqLength]Value { 140 0, 0, 0, 0, 0, 0, 0, 0, 141 0, 0, 0, 0, 0, 0, 0, 0, 142 0, 5, 5, 5, 5, 5, 5, 0, 143 5, 5, 10, 30, 30, 10, 5, 5, 144 0, 0, 0, 30, 30, 0, 0, 0, 145 5, -5,-10, 0, 0,-10, -5, 5, 146 5, 10, 10,-30,-30, 10, 10, 5, 147 0, 0, 0, 0, 0, 0, 0, 0} 148 149 pawnsEndGame = [SqLength]Value { 150 0, 0, 0, 0, 0, 0, 0, 0, 151 90, 90, 90, 90, 90, 90, 90, 90, 152 40, 50, 50, 60, 60, 50, 50, 40, 153 20, 30, 30, 40, 40, 30, 30, 20, 154 10, 10, 20, 20, 20, 10, 10, 10, 155 5, 10, 10, 10, 10, 10, 10, 5, 156 5, 10, 10, 10, 10, 10, 10, 5, 157 0, 0, 0, 0, 0, 0, 0, 0} 158 159 // KNIGHT Tables 160 knightMidGame = [SqLength]Value { 161 -50,-40,-30,-30,-30,-30,-40,-50, 162 -40,-20, 0, 0, 0, 0,-20,-40, 163 -30, 0, 10, 15, 15, 10, 0,-30, 164 -30, 5, 15, 20, 20, 15, 5,-30, 165 -30, 0, 15, 20, 20, 15, 0,-30, 166 -30, 5, 10, 15, 15, 10, 5,-30, 167 -40,-20, 0, 5, 5, 0,-20,-40, 168 -50,-25,-20,-30,-30,-20,-25,-50} 169 170 knightEndGame = [SqLength]Value { 171 -50,-40,-30,-30,-30,-30,-40,-50, 172 -40,-20, 0, 0, 0, 0,-20,-40, 173 -30, 0, 10, 15, 15, 10, 0,-30, 174 -30, 0, 15, 20, 20, 15, 0,-30, 175 -30, 0, 15, 20, 20, 15, 0,-30, 176 -30, 0, 10, 15, 15, 10, 0,-30, 177 -40,-20, 0, 0, 0, 0,-20,-40, 178 -50,-40,-20,-30,-30,-20,-40,-50} 179 180 // BISHOP Tables 181 bishopMidGame = [SqLength]Value { 182 -20,-10,-10,-10,-10,-10,-10,-20, 183 -10, 0, 0, 0, 0, 0, 0,-10, 184 -10, 0, 5, 10, 10, 5, 0,-10, 185 -10, 5, 5, 10, 10, 5, 5,-10, 186 -10, 0, 10, 10, 10, 10, 0,-10, 187 -10, 10, 10, 10, 10, 10, 10,-10, 188 -10, 5, 0, 0, 0, 0, 5,-10, 189 -20,-10,-40,-10,-10,-40,-10,-20} 190 191 bishopEndGame = [SqLength]Value { 192 -20,-10,-10,-10,-10,-10,-10,-20, 193 -10, 0, 0, 0, 0, 0, 0,-10, 194 -10, 0, 5, 5, 5, 5, 0,-10, 195 -10, 0, 5, 10, 10, 5, 0,-10, 196 -10, 0, 5, 10, 10, 5, 0,-10, 197 -10, 0, 5, 5, 5, 5, 0,-10, 198 -10, 0, 0, 0, 0, 0, 0,-10, 199 -20,-10,-10,-10,-10,-10,-10,-20} 200 201 // ROOK Tables 202 rookMidGame = [SqLength]Value { 203 5, 5, 5, 5, 5, 5, 5, 5, 204 10, 10, 10, 10, 10, 10, 10, 10, 205 0, 0, 0, 0, 0, 0, 0, 0, 206 0, 0, 0, 0, 0, 0, 0, 0, 207 0, 0, 0, 0, 0, 0, 0, 0, 208 0, 0, 0, 0, 0, 0, 0, 0, 209 0, 0, 0, 0, 0, 0, 0, 0, 210 -15,-10, 15, 15, 15, 15,-10,-15} 211 212 rookEndGame = [SqLength]Value { 213 5, 5, 5, 5, 5, 5, 5, 5, 214 0, 0, 0, 0, 0, 0, 0, 0, 215 0, 0, 0, 0, 0, 0, 0, 0, 216 0, 0, 0, 0, 0, 0, 0, 0, 217 0, 0, 0, 0, 0, 0, 0, 0, 218 0, 0, 0, 0, 0, 0, 0, 0, 219 0, 0, 0, 0, 0, 0, 0, 0, 220 0, 0, 0, 0, 0, 0, 0, 0} 221 222 // Queen Tables 223 queenMidGame = [SqLength]Value { 224 -20,-10,-10, -5, -5,-10,-10,-20, 225 -10, 0, 0, 0, 0, 0, 0,-10, 226 -10, 0, 0, 0, 0, 0, 0,-10, 227 -5, 0, 2, 2, 2, 2, 0, -5, 228 -5, 0, 5, 5, 5, 5, 0, -5, 229 -10, 0, 5, 5, 5, 5, 0,-10, 230 -10, 0, 5, 5, 5, 5, 0,-10, 231 -20,-10,-10, -5, -5,-10,-10,-20} 232 233 queenEndGame = [SqLength]Value { 234 -20,-10,-10, -5, -5,-10,-10,-20, 235 -10, 0, 0, 0, 0, 0, 0,-10, 236 -10, 0, 5, 5, 5, 5, 0,-10, 237 -5, 0, 5, 5, 5, 5, 0, -5, 238 -5, 0, 5, 5, 5, 5, 0, -5, 239 -10, 0, 5, 5, 5, 5, 0,-10, 240 -10, 0, 0, 0, 0, 0, 0,-10, 241 -20,-10,-10, -5, -5,-10,-10,-20} 242 243 // King Tables 244 kingMidGame = [SqLength]Value { 245 -30,-40,-40,-50,-50,-40,-40,-30, 246 -30,-40,-40,-50,-50,-40,-40,-30, 247 -30,-40,-40,-50,-50,-40,-40,-30, 248 -30,-40,-40,-50,-50,-40,-40,-30, 249 -20,-30,-30,-40,-40,-30,-30,-20, 250 -10,-20,-20,-30,-30,-30,-20,-10, 251 0, 0,-20,-20,-20,-20, 0, 0, 252 20, 50, 0,-20,-20, 0, 50, 20} 253 254 kingEndGame = [SqLength]Value { 255 -50,-30,-30,-20,-20,-30,-30,-50, 256 -30,-20,-10, 0, 0,-10,-20,-30, 257 -30,-10, 20, 30, 30, 20,-10,-30, 258 -30,-10, 30, 40, 40, 30,-10,-30, 259 -30,-10, 30, 40, 40, 30,-10,-30, 260 -30,-10, 20, 30, 30, 20,-10,-30, 261 -30,-30, 0, 0, 0, 0,-30,-30, 262 -50,-30,-30,-30,-30,-30,-30,-50} 263 // @formatter:on 264 )