github.com/gorgonia/agogo@v0.1.1/internal/gtp/command.go (about) 1 package gtp 2 3 import ( 4 "bytes" 5 "fmt" 6 "strconv" 7 8 "github.com/gorgonia/agogo/game" 9 "github.com/pkg/errors" 10 ) 11 12 type Command interface { 13 Do(id int, args []string, e *Engine) (int, string, error) 14 } 15 16 type stdlib func(e *Engine) string 17 18 type stdlib2 func(e *Engine, args []string) (string, error) 19 20 func (f stdlib) Do(id int, args []string, e *Engine) (int, string, error) { 21 str := f(e) 22 return id, str, nil 23 } 24 25 func (f stdlib2) Do(id int, args []string, e *Engine) (int, string, error) { 26 str, err := f(e, args) 27 return id, str, err 28 } 29 30 func protocolVersion(e *Engine) string { return "2" } 31 func name(e *Engine) string { return e.name } 32 func version(e *Engine) string { return e.version } 33 34 func listCommands(e *Engine) string { 35 var buf bytes.Buffer 36 for c := range e.known { 37 fmt.Fprintf(&buf, "%v\n", c) 38 } 39 return buf.String() 40 } 41 42 func quit(e *Engine) string { close(e.ch); return "QUIT" } 43 func clearBoard(e *Engine) string { e.g.Reset(); return "" } 44 func showboard(e *Engine) string { return fmt.Sprintf("\n%v\n", e.g) } 45 func undo(e *Engine) string { e.g.UndoLastMove(); return "" } 46 47 func knownCommand(e *Engine, args []string) (string, error) { 48 if len(args) == 0 { 49 return "", errors.New("Not enough arguments for \"known_command\"") 50 } 51 if _, ok := e.known[args[0]]; ok { 52 return "true", nil 53 } 54 return "false", nil 55 } 56 57 func boardSize(e *Engine, args []string) (string, error) { 58 // arg 59 switch len(args) { 60 case 0: 61 return "", errors.New("Not enough arguments for \"boardsize\"") 62 case 1: 63 newsize, err := strconv.Atoi(args[0]) 64 if err != nil { 65 return "", errors.WithMessage(err, "Unable to parse first argument of boardsize") 66 } 67 m := sqrt(newsize) 68 e.g = e.New(m, m) 69 return "", nil 70 default: 71 newM, err := strconv.Atoi(args[0]) 72 if err != nil { 73 return "", errors.WithMessage(err, "Unable to parse first argument of boardsize") 74 } 75 newN, err := strconv.Atoi(args[1]) 76 if err != nil { 77 return "", errors.WithMessage(err, "Unable to parse second argument of boardsize") 78 } 79 e.g = e.New(newM, newN) 80 81 return "", nil 82 } 83 } 84 85 func komi(e *Engine, args []string) (string, error) { 86 if len(args) == 0 { 87 return "", errors.New("Not enough arguments for \"komi\"") 88 } 89 90 komi, err := strconv.ParseFloat(args[0], 64) 91 if err != nil { 92 return "", errors.WithMessage(err, "Unable to parse komi argument") 93 } 94 95 if ks, ok := e.g.(game.KomiSetter); ok { 96 ks.SetKomi(komi) // ignore errors because GTP says so. Accept komi even if ridiculous 97 } 98 return "", nil 99 } 100 101 func play(e *Engine, args []string) (string, error) { 102 if len(args) == 0 { 103 return "", errors.New("Not enough arguments for \"play\"") 104 } 105 return "", errors.New("NYI") 106 } 107 108 func genmove(e *Engine, args []string) (string, error) { 109 if len(args) == 0 { 110 return "", errors.New("Not enough arguments for \"genmove\"") 111 } 112 if e.Generate == nil { 113 return "", errors.New("Unable to generate moves. No generator found") 114 } 115 return "", errors.New("NYI") 116 } 117 118 func StandardLib() map[string]Command { 119 return map[string]Command{ 120 "protocol_version": stdlib(protocolVersion), 121 "name": stdlib(name), 122 "version": stdlib(version), 123 "list_commands": stdlib(listCommands), 124 "quit": stdlib(quit), 125 "clear_board": stdlib(clearBoard), 126 "showboard": stdlib(showboard), 127 "undo": stdlib(undo), 128 129 "known_command": stdlib2(knownCommand), 130 "boardsize": stdlib2(boardSize), 131 "komi": stdlib2(komi), 132 "play": stdlib2(play), 133 "genmove": stdlib2(genmove), 134 } 135 }