github.com/gorgonia/agogo@v0.1.1/encoding_helper.go (about) 1 package agogo 2 3 import ( 4 "github.com/gorgonia/agogo/game" 5 "github.com/pkg/errors" 6 "gorgonia.org/vecf32" 7 ) 8 9 // EncodeTwoPlayerBoard encodes black as 1, white as -1 for each stone placed 10 func EncodeTwoPlayerBoard(a []game.Colour, prealloc []float32) []float32 { 11 if len(prealloc) != len(a) { 12 prealloc = make([]float32, len(a)) 13 } 14 15 for i := range a { 16 switch a[i] { 17 case game.Black: 18 prealloc[i] = 1 19 case game.White: 20 prealloc[i] = -1 21 default: 22 prealloc[i] = 0 23 } 24 } 25 return prealloc 26 } 27 28 // WQEncoder encodes a Go board 29 func WQEncoder(a game.State) []float32 { 30 const lookback = 8 31 const features = 2*lookback + 2 32 board := a.Board() 33 size := len(board) 34 retVal := make([]float32, size*features) 35 36 next := a.ToMove() 37 encodedPlayer := float32(1) 38 var blackStart, whiteStart, nextStart int 39 if next == game.Player(game.Black) { 40 blackStart = 0 41 whiteStart = lookback * size 42 nextStart = 2 * lookback * size 43 } else { 44 blackStart = lookback * size 45 whiteStart = 0 46 nextStart = (2*lookback + 1) * size 47 encodedPlayer = -1 48 } 49 50 current := a.MoveNumber() - 1 51 for i := 1; i < lookback; i++ { 52 h := current - i 53 if h > 0 && h < current { 54 past := a.Historical(h) 55 encodeBlack(past, retVal[blackStart:blackStart+size]) 56 encodeWhite(past, retVal[whiteStart:whiteStart+size]) 57 } 58 59 blackStart += size 60 whiteStart += size 61 } 62 63 for i := nextStart; i < nextStart+size; i++ { 64 retVal[i] = encodedPlayer 65 } 66 67 return retVal 68 } 69 70 func encodeBlack(a []game.Colour, prealloc []float32) []float32 { 71 return EncodeTwoPlayerBoard(a, prealloc) 72 } 73 74 func encodeWhite(a []game.Colour, prealloc []float32) []float32 { 75 retVal := EncodeTwoPlayerBoard(a, prealloc) 76 vecf32.Scale(retVal, -1) 77 return retVal 78 } 79 80 func RotateBoard(board []float32, m, n int) ([]float32, error) { 81 if m != n { 82 return nil, errors.Errorf("Cannot handle m %d, n %d. This function only takes square boards", m, n) 83 } 84 copied := make([]float32, len(board)) 85 copy(copied, board) 86 it := MakeIterator(copied, m, n) 87 for i := 0; i < m/2; i++ { 88 mi1 := m - i - 1 89 for j := i; j < mi1; j++ { 90 mj1 := m - j - 1 91 tmp := it[i][j] 92 // right to top 93 it[i][j] = it[j][mi1] 94 95 // bottom to right 96 it[j][mi1] = it[mi1][mj1] 97 98 // left to bottom 99 it[mi1][mj1] = it[mj1][i] 100 101 // tmp is left 102 it[mj1][i] = tmp 103 } 104 } 105 ReturnIterator(m, n, it) 106 return copied, nil 107 }