github.com/gorgonia/agogo@v0.1.1/game/state.go (about)

     1  package game
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  type Colour int32
     8  
     9  const (
    10  	None Colour = iota
    11  	Black
    12  	White
    13  )
    14  
    15  func (cl Colour) Format(s fmt.State, c rune) {
    16  	switch c {
    17  	case 'v': // used in debug
    18  		switch cl {
    19  		case None:
    20  			fmt.Fprint(s, "None")
    21  		case Black:
    22  			fmt.Fprint(s, "Black")
    23  		case White:
    24  			fmt.Fprint(s, "White")
    25  		}
    26  	case 's': // used in board games
    27  		switch cl {
    28  		case None:
    29  			fmt.Fprint(s, "·")
    30  		case Black:
    31  			fmt.Fprint(s, "X")
    32  		case White:
    33  			fmt.Fprint(s, "O")
    34  		}
    35  	}
    36  }
    37  
    38  // Player represents a player. It's also a colour.
    39  type Player Colour
    40  
    41  func (p Player) Format(s fmt.State, c rune) {
    42  	switch c {
    43  	case 'v': // used in debug
    44  		switch Colour(p) {
    45  		case None:
    46  			fmt.Fprint(s, "None")
    47  		case Black:
    48  			fmt.Fprint(s, "Black")
    49  		case White:
    50  			fmt.Fprint(s, "White")
    51  		}
    52  	case 's': // used in board games
    53  		switch Colour(p) {
    54  		case None:
    55  			fmt.Fprint(s, "·")
    56  		case Black:
    57  			fmt.Fprint(s, "X")
    58  		case White:
    59  			fmt.Fprint(s, "O")
    60  		}
    61  	}
    62  }
    63  
    64  // PlayerMove is a tuple indicating the player and the move to be made.
    65  //
    66  // For now, the move is a Single. The original implementation took a Coordinate
    67  type PlayerMove struct {
    68  	Player
    69  	Single
    70  }
    71  
    72  // Eq returns true if both are equal
    73  func (p PlayerMove) Eq(other PlayerMove) bool {
    74  	return p.Player == other.Player && p.Single == other.Single
    75  }
    76  
    77  func (p PlayerMove) Format(s fmt.State, c rune) { fmt.Fprintf(s, "%v@%d", p.Player, p.Single) }
    78  
    79  // Coordinate is a representation of coordinates. This is typically a move
    80  type Coordinate interface {
    81  	IsResignation() bool
    82  	IsPass() bool
    83  }
    84  
    85  // Coord represents a (row, col) coordinate.
    86  // Given we're unlikely to actually have a board size of 255x255 or greater,
    87  // a pair of bytes is sufficient to represent the coordinates
    88  //
    89  // The Coord uses a standard computer cartesian coordinates
    90  //		- (0, 0) represents the top left
    91  //		- (18, 18) represents the bottom right of a 19x19 board
    92  //		- (255, 255) represents a "pass" move
    93  // 		- (254, 254) represents a "resign" move
    94  type Coord struct {
    95  	X, Y int16
    96  }
    97  
    98  func (c Coord) Add(other Coord) struct{ X, Y int16 } {
    99  	return Coord{c.X + other.X, c.Y + other.Y}
   100  }
   101  
   102  func (c Coord) Eq(other Coord) bool { return c.X == other.X && c.Y == other.Y }
   103  
   104  // IsResignation returns true when the coordinate represents a "resignation" move
   105  func (c Coord) IsResignation() bool { return c.X == 254 && c.Y == 254 }
   106  
   107  // IsPass returns true when the coordinate represents a "pass" move
   108  func (c Coord) IsPass() bool { return c.X == 255 && c.Y == 255 }
   109  
   110  // Single represents a coordinate as a single 8-bit number, utilized in a rowmajor fashion.
   111  //		- 0 represents the top left
   112  //		- 18 represents the top right
   113  //		- 19 represents (1, 0)
   114  // 		- -1 represents the "pass" move
   115  //		- -2 represents the "resignation" move
   116  type Single int32
   117  
   118  // IsResignation returns true when the coordinate represents a "resignation" move
   119  func (c Single) IsResignation() bool { return c == -2 }
   120  
   121  // IsPass returns true when the coordinate represents a "pass" move
   122  func (c Single) IsPass() bool { return c == -1 }
   123  
   124  // State is any game that implements these and are able to report back
   125  type State interface {
   126  	// These methods represent the game state
   127  	BoardSize() (int, int) // returns the board size
   128  	Board() []Colour       // returns the board state
   129  	ActionSpace() int      // returns the number of permissible actions
   130  	Hash() Zobrist         // returns the hash of the board
   131  	ToMove() Player        // returns the next player to move (terminology is a bit confusing - this means the current player)
   132  	Passes() int           // returns number of passes that have been made
   133  	MoveNumber() int       // returns count of moves so far that led to this point.
   134  	LastMove() PlayerMove  // returns the last move that was made
   135  	Handicap() int         // returns a handicap (i.e. allow N moves)
   136  
   137  	// Meta-game stuff
   138  	Score(p Player) float32             // score of the given player
   139  	AdditionalScore() float32           // additional tie breaking scores (like komi etc)
   140  	Ended() (ended bool, winner Player) // has the game ended? if yes, then who's the winner?
   141  
   142  	// interactions
   143  	SetToMove(Player)         // set the next player to move
   144  	Check(m PlayerMove) bool  // check if the placement is legal
   145  	Apply(m PlayerMove) State // should return a GameState. The required side effect is the NextToMove has to change.
   146  	Reset()                   // reset state
   147  
   148  	// For MCTS
   149  	Historical(i int) []Colour // returns the board state from history
   150  	UndoLastMove()
   151  	Fwd()
   152  
   153  	// generics
   154  	Eq(other State) bool
   155  	Clone() State
   156  }
   157  
   158  // KomiSetter is any State that can set a Komi score.
   159  //
   160  // The komi score may be acquired from the State via AdditionalScore()
   161  type KomiSetter interface {
   162  	State
   163  	SetKomi(komi float64) error
   164  }
   165  
   166  // Zobrist is a type representing a "zobrist" hash.
   167  // The word "Zobrist" is put in quotes because only Go and chess uses zobrist hashing.
   168  // Other games have different hashes of the boards (because only Go and Chess have subtractive boards)
   169  type Zobrist uint32
   170  
   171  type MetaState interface {
   172  	Name() string // name of the game
   173  	Epoch() int
   174  	GameNumber() int
   175  	Score(a Player) float64
   176  	State() State
   177  }
   178  
   179  type CoordConverter interface {
   180  	Ltoi(Coord) Single
   181  	Itol(Single) Coord
   182  }