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 )
}