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  }