package main import ( "fmt" "image/color" "os" "strings" "time" chess "git.nightmare.haus/rudi/chessv2" "git.nightmare.haus/rudi/chessv2/image" "samhofi.us/x/keybase/v2/types/chat1" ) func chessCommand(m chat1.MsgSummary) { defer log.PanicSafe("chessCommand") convID := string(m.ConvID) parts := strings.Split(m.Content.Text.Body, " ") if g, ok := config.Games[convID]; ok { if len(parts) != 2 { return } if parts[1] == "show" { go showBoard(m, g) return } submitMove(m, g) return } log.LogInfo("Game not found") if len(parts) < 3 { return } coin := r.Intn(100) log.LogInfo(fmt.Sprintf("Coin toss resulted in %+v\n", coin)) var game Game if coin%2 == 0 { if len(parts) == 4 && parts[3] == "heads" { game.White = m.Sender.Username game.Black = strings.Replace(parts[2], "@", "", -1) } else { game.Black = m.Sender.Username game.White = strings.Replace(parts[2], "@", "", -1) } } else { if len(parts) == 4 && parts[3] == "heads" { game.Black = m.Sender.Username game.White = strings.Replace(parts[2], "@", "", -1) } else { game.White = m.Sender.Username game.Black = strings.Replace(parts[2], "@", "", -1) } } log.LogDebug("There are currently %+v games.\n", len(config.Games)) g := chess.NewGame() game.Game = *g game.ConvID = convID game.Move = true game.StartTime = time.Now() config.Games[convID] = game saveConfig() k.SendMessageByConvID(m.ConvID, fmt.Sprintf("I have created a new game for this conversation @%+v is playing as White, @%+v is playing as Black.", game.White, game.Black)) k.SendMessageByConvID(m.ConvID, fmt.Sprintf("Possible commands are `@chessbot show` to show the board, or `@chessbot forfeit`. Otherwise I will be expecting a move in Algebraic Notation.")) } func showBoard(m chat1.MsgSummary, g Game) { defer log.PanicSafe("showBoard") // create file log.LogInfo("Creating file for %+v.svg", m.ConvID) f, err := os.Create(fmt.Sprintf("/home/chessbot/chessbot/games/%+v.svg", m.ConvID)) if err != nil { log.LogError(fmt.Sprintf("Error in ShowBoard os.Create: %+v\n", err)) } log.LogInfo("Creating board position (g.Game.Position().String()): %+v", g.ConvID) // create board position fenStr := g.Game.Pos.String() log.LogInfo("Creating pos &chess.Position{}") pos := &chess.Position{} if err := pos.UnmarshalText([]byte(fenStr)); err != nil { log.LogError(fmt.Sprintf("Error in ShowBoard pos.UnmasrhalText: %+v\n", err)) } log.LogInfo("Trying to check Moves History") if len(g.Game.MovesHistory()) != 0 { // write board SVG to file yellow := color.RGBA{255, 255, 0, 1} lastMove := g.Game.MovesHistory()[len(g.Game.MovesHistory())-1] mark := image.MarkSquares(yellow, lastMove.S1(), lastMove.S2()) if err := image.SVG(f, pos.Board(), mark); err != nil { log.LogError("Error in ShowBoard image.SVG Mark: %+v\n", err) } } else { if err := image.SVG(f, pos.Board()); err != nil { log.LogError("Error in ShowBoard image.SVG: %+v\n", err) } } log.LogInfo("Closing file.") f.Close() if svgToPNG(fmt.Sprintf("/home/chessbot/chessbot/games/%+v", m.ConvID)) { k.UploadToConversation(m.ConvID, "", fmt.Sprintf("/home/chessbot/chessbot/games/%+v.png", m.ConvID)) } else { k.SendMessageByConvID(m.ConvID, fmt.Sprintf("```%+v```", g.Game.Position().Board().Draw())) } } func submitMove(m chat1.MsgSummary, g Game) { defer log.PanicSafe("submitMove") defer saveConfig() parts := strings.Split(m.Content.Text.Body, " ") if g.Move { if m.Sender.Username != g.White { k.SendMessageByConvID(m.ConvID, "Wait your turn.") return } } else { if m.Sender.Username != g.Black { k.SendMessageByConvID(m.ConvID, "Wait your turn.") return } } if parts[1] == "forfeit" || parts[1] == "surrender" { if g.Move { g.Game.Resign(chess.White) } else { g.Game.Resign(chess.Black) } } else { err := g.Game.MoveStr(parts[1]) if err != nil { k.SendMessageByConvID(m.ConvID, "There was an error with your move.") log.LogDebug("%+v\n", err) return } } g.Move = !g.Move if g.Game.GameOutcome() != chess.NoOutcome { k.SendMessageByConvID(m.ConvID, fmt.Sprintf("Game completed in %+v. %s by %s.\n", time.Since(g.StartTime), g.Game.GameOutcome(), g.Game.OutcomeMethod())) delete(config.Games, g.ConvID) } go showBoard(m, g) }