...

Source file src/code.rocket9labs.com/tslocum/bgammon/board.go

Documentation: code.rocket9labs.com/tslocum/bgammon

     1  package bgammon
     2  
     3  import (
     4  	"log"
     5  	"sort"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  const (
    11  	SpaceHomePlayer   int8 = 0  // Current player's home.
    12  	SpaceHomeOpponent int8 = 25 // Opponent player's home.
    13  	SpaceBarPlayer    int8 = 26 // Current player's bar.
    14  	SpaceBarOpponent  int8 = 27 // Opponent player's bar.
    15  )
    16  
    17  // BoardSpaces is the total number of spaces needed to represent a backgammon board.
    18  const BoardSpaces = 28
    19  
    20  // NewBoard returns a new backgammon board represented as integers. Positive
    21  // integers represent player 1's checkers and negative integers represent
    22  // player 2's checkers. The board's space numbering is always from the
    23  // perspective of the current player (i.e. the 1 space will always be in the
    24  // current player's home board).
    25  func NewBoard(variant int8) []int8 {
    26  	space := make([]int8, BoardSpaces)
    27  	switch variant {
    28  	case VariantBackgammon:
    29  		space[24], space[1] = 2, -2
    30  		space[19], space[6] = -5, 5
    31  		space[17], space[8] = -3, 3
    32  		space[13], space[12] = 5, -5
    33  	case VariantAceyDeucey, VariantTabula:
    34  		space[SpaceHomePlayer], space[SpaceHomeOpponent] = 15, -15
    35  	default:
    36  		log.Panicf("failed to initialize board: unknown variant: %d", variant)
    37  	}
    38  	return space
    39  }
    40  
    41  // HomeRange returns the start and end space of the provided player's home board.
    42  func HomeRange(player int8, variant int8) (from int8, to int8) {
    43  	if player == 2 || variant == VariantTabula {
    44  		return 24, 19
    45  	}
    46  	return 1, 6
    47  }
    48  
    49  // RollForMove returns the roll needed to move a checker from the provided spaces.
    50  func RollForMove(from int8, to int8, player int8, variant int8) int8 {
    51  	if !ValidSpace(from) || !ValidSpace(to) {
    52  		return 0
    53  	}
    54  
    55  	// Handle standard moves.
    56  	if from >= 1 && from <= 24 && to >= 1 && to <= 24 {
    57  		return SpaceDiff(from, to, variant)
    58  	}
    59  
    60  	playerHome := SpaceHomePlayer
    61  	playerBar := SpaceBarPlayer
    62  	oppHome := SpaceHomeOpponent
    63  	oppBar := SpaceBarOpponent
    64  	if player == 2 {
    65  		playerHome, oppHome, playerBar, oppBar = oppHome, playerHome, oppBar, playerBar
    66  	}
    67  
    68  	// Handle moves with special 'to' space.
    69  	if to == playerBar || to == oppBar || to == oppHome {
    70  		return 0
    71  	} else if to == playerHome {
    72  
    73  	}
    74  
    75  	// Handle moves with special 'from' space.
    76  	if from == SpaceBarPlayer {
    77  		if player == 2 && variant != VariantTabula {
    78  			return 25 - to
    79  		} else {
    80  			return to
    81  		}
    82  	}
    83  	return 0
    84  }
    85  
    86  func ParseSpace(space string) int8 {
    87  	i, err := strconv.Atoi(space)
    88  	if err != nil {
    89  		switch strings.ToLower(space) {
    90  		case "bar", "b":
    91  			return SpaceBarPlayer
    92  		case "off", "o", "home", "h":
    93  			return SpaceHomePlayer
    94  		}
    95  		return -1
    96  	}
    97  	return int8(i)
    98  }
    99  
   100  func compareMoveFunc(moves [][]int8) func(i, j int) bool {
   101  	return func(i, j int) bool {
   102  		if moves[j][0] == moves[i][0] {
   103  			return moves[j][1] < moves[i][1]
   104  		}
   105  		return moves[j][0] < moves[i][0]
   106  	}
   107  }
   108  
   109  // SortMoves sorts moves from highest to lowest.
   110  func SortMoves(moves [][]int8) {
   111  	sort.Slice(moves, compareMoveFunc(moves))
   112  }
   113  

View as plain text