Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions board.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package chess
import (
"strconv"
"strings"
"bytes"
)

// A Board represents a chess board and its relationship between squares and pieces.
Expand Down Expand Up @@ -59,28 +60,30 @@ func (b *Board) Draw() string {

// String implements the fmt.Stringer interface and returns
// a string in the FEN board format: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
// TODO use zobrist instead
func (b *Board) String() string {
fen := ""
var fen bytes.Buffer
var retval string
for r := 7; r >= 0; r-- {
for f := 0; f < numOfSquaresInRow; f++ {
sq := getSquare(File(f), Rank(r))
p := b.Piece(sq)
if p != NoPiece {
fen += p.getFENChar()
fen.WriteString(p.getFENChar())
} else {
fen += "1"
fen.WriteString("1")
}
}
if r != 0 {
fen += "/"
fen.WriteString("/")
}
}
for i := 8; i > 1; i-- {
repeatStr := strings.Repeat("1", i)
countStr := strconv.Itoa(i)
fen = strings.Replace(fen, repeatStr, countStr, -1)
retval = strings.Replace(fen.String(), repeatStr, countStr, -1)
}
return fen
return retval
}

// Piece returns the piece for the given square.
Expand Down
21 changes: 21 additions & 0 deletions game.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,26 @@ func (g *Game) Move(m *Move) error {
return nil
}

// Unmove unmakes the last move
// and sets the game state to the
// one of the previous move
func (g *Game) Unmove() error {
if (len(g.moves) < 1) {
return fmt.Errorf("chess: no previous moves to unmake")
}
// delete the last move
g.moves = g.moves[:len(g.moves)-1]
// delete the last position
g.positions = g.positions[:len(g.positions)-1]
// update the current position to the last one
g.pos = g.positions[len(g.positions)-1]
// reset outcome, etc.
g.method = NoMethod
g.outcome = NoOutcome
//g.updatePosition()
return nil
}

// MoveStr decodes the given string in game's notation
// and calls the Move function. An error is returned if
// the move can't be decoded or the move is invalid.
Expand Down Expand Up @@ -335,6 +355,7 @@ func (g *Game) RemoveTagPair(k string) bool {

func (g *Game) updatePosition() {
method := g.pos.Status()

if method == Stalemate {
g.method = Stalemate
g.outcome = Draw
Expand Down
30 changes: 30 additions & 0 deletions piece.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,40 @@ var (
)

func (p Piece) getFENChar() string {
switch p {
case WhiteKing:
return "K"
case WhiteQueen:
return "Q"
case WhiteRook:
return "R"
case WhiteBishop:
return "B"
case WhiteKnight:
return "N"
case WhitePawn:
return "P"
case BlackKing:
return "k"
case BlackQueen:
return "q"
case BlackRook:
return "r"
case BlackBishop:
return "b"
case BlackKnight:
return "n"
case BlackPawn:
return "p"
default:
return ""
}
/*
for key, piece := range fenPieceMap {
if piece == p {
return key
}
}
return ""
*/
}
22 changes: 20 additions & 2 deletions position.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func (cr CastleRights) String() string {
// to its outcome. Position is translatable to FEN notation.
type Position struct {
board *Board
cached_board_string string
cached_castle_string string
turn Color
castleRights CastleRights
enPassantSquare Square
Expand Down Expand Up @@ -74,6 +76,8 @@ func (pos *Position) Update(m *Move) *Position {
b.update(m)
return &Position{
board: b,
cached_board_string: "",
cached_castle_string: "",
turn: pos.turn.Other(),
castleRights: ncr,
enPassantSquare: pos.updateEnPassantSquare(m),
Expand Down Expand Up @@ -213,9 +217,23 @@ func (pos *Position) updateEnPassantSquare(m *Move) Square {
return NoSquare
}

func (pos *Position)boardString() string {
if (pos.cached_board_string == "") {
pos.cached_board_string = pos.board.String()
}
return pos.cached_board_string
}

func (pos *Position)castleString() string {
if (pos.cached_castle_string == "") {
pos.cached_castle_string = pos.castleRights.String()
}
return pos.cached_castle_string
}

func (pos *Position) samePosition(pos2 *Position) bool {
return pos.board.String() == pos2.board.String() &&
return pos.boardString() == pos2.boardString() &&
pos.turn == pos2.turn &&
pos.castleRights.String() == pos2.castleRights.String() &&
pos.castleString() == pos2.castleString() &&
pos.enPassantSquare == pos2.enPassantSquare
}