Skip to content

Commit

Permalink
fixing queenside castling. almost to full multi-game parse.
Browse files Browse the repository at this point in the history
  • Loading branch information
freeeve committed Feb 22, 2014
1 parent 3f913b1 commit b4db00c
Show file tree
Hide file tree
Showing 6 changed files with 16,426 additions and 38 deletions.
96 changes: 78 additions & 18 deletions board.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ type CastleStatus int8
const (
Both CastleStatus = iota
None
King
Queen
Kingside
Queenside
)

func (cs CastleStatus) String(c Color) string {
Expand All @@ -107,14 +107,14 @@ func (cs CastleStatus) String(c Color) string {
}
case None:
return "-"
case King:
case Kingside:
switch c {
case Black:
ret = "k"
case White:
ret = "K"
}
case Queen:
case Queenside:
switch c {
case Black:
ret = "q"
Expand All @@ -125,9 +125,21 @@ func (cs CastleStatus) String(c Color) string {
return ret
}

func (b *Board) MakeAlgebraicMove(str string, color Color) error {
move, err := b.MoveFromAlgebraic(str, color)
if err != nil {
return err
}
err = b.MakeMove(move)
if err != nil {
return err
}
return nil
}

func (b *Board) MoveFromAlgebraic(str string, color Color) (Move, error) {
str = strings.Trim(str, "+!?")
//fmt.Println("move from alg:", str, "..", color)
fmt.Println("move from alg:", str, "..", color)
if b.toMove != color {
return NilMove, ErrMoveWrongColor
}
Expand Down Expand Up @@ -293,26 +305,74 @@ func (b *Board) String() string {
}

func (b *Board) MakeMove(m Move) error {
// TODO test/handle special enpassant and castle
// TODO test/handle special enpassant
p := b.GetPiece(m.From)
if p == Empty {
return ErrMoveFromEmptySquare
}

// sanity check for wrong color
if p.Color() != b.toMove {
return ErrMoveWrongColor
}

// see if we're taking a piece
take := b.GetPiece(m.To)
if take != Empty {
b.RemovePiece(m.To, take)
}

// the moving
b.SetPiece(m.To, p)
b.RemovePiece(m.From, p)

// handle special cases
switch p {
case BlackKing:
// handle castles
if m.From == E8 && m.To == G8 {
if b.bCastle != Kingside && b.bCastle != Both {
return ErrMoveInvalidCastle
}
rook := b.GetPiece(H8)
b.RemovePiece(H8, rook)
b.SetPiece(F8, rook)
} else if m.From == E8 && m.To == C8 {
if b.bCastle != Queenside && b.bCastle != Both {
return ErrMoveInvalidCastle
}
rook := b.GetPiece(A8)
b.RemovePiece(A8, rook)
b.SetPiece(D8, rook)
}
case WhiteKing:
// handle castles
if m.From == E1 && m.To == G1 {
if b.wCastle != Kingside && b.wCastle != Both {
return ErrMoveInvalidCastle
}
rook := b.GetPiece(H1)
b.RemovePiece(H1, rook)
b.SetPiece(F1, rook)
} else if m.From == E1 && m.To == C1 {
if b.wCastle != Queenside && b.wCastle != Both {
return ErrMoveInvalidCastle
}
rook := b.GetPiece(A1)
b.RemovePiece(A1, rook)
b.SetPiece(D1, rook)
}
}

// swap next color
switch b.toMove {
case White:
b.toMove = Black
case Black:
b.toMove = White
}

// handle move number increment
return nil
}

Expand Down Expand Up @@ -428,12 +488,12 @@ func (b Board) findAttackingPawn(pos Position, color Color) (Position, error) {
if b.GetPiece(PositionFromFileRank(pos.GetFile()-1, pos.GetRank()-1)) == WhitePawn {
retPos = PositionFromFileRank(pos.GetFile()-1, pos.GetRank()-1)
}
if b.GetPiece(PositionFromFileRank(pos.GetFile()+1, pos.GetRank()-1)) == WhitePawn {
retPos = PositionFromFileRank(pos.GetFile()+1, pos.GetRank()-1)
}
if b.GetPiece(PositionFromFileRank(pos.GetFile()-1, pos.GetRank()-1)) == WhitePawn {
retPos = PositionFromFileRank(pos.GetFile()-1, pos.GetRank()-1)
}
}
if b.GetPiece(PositionFromFileRank(pos.GetFile()+1, pos.GetRank()-1)) == WhitePawn {
retPos = PositionFromFileRank(pos.GetFile()+1, pos.GetRank()-1)
}
if b.GetPiece(PositionFromFileRank(pos.GetFile()-1, pos.GetRank()-1)) == WhitePawn {
retPos = PositionFromFileRank(pos.GetFile()-1, pos.GetRank()-1)
}
} else {
// special en-passant case
Expand Down Expand Up @@ -834,7 +894,7 @@ func (b Board) containsPieceAt(pos Position) bool {

func (b Board) getKingsideCastle(color Color) (Move, error) {
if color == White {
if b.wCastle != Both && b.wCastle != King {
if b.wCastle != Both && b.wCastle != Kingside {
return NilMove, ErrMoveInvalidCastle
}
if b.containsPieceAt(F1) || b.containsPieceAt(G1) {
Expand All @@ -845,7 +905,7 @@ func (b Board) getKingsideCastle(color Color) (Move, error) {
}
return Move{E1, G1}, nil
} else {
if b.bCastle != Both && b.bCastle != King {
if b.bCastle != Both && b.bCastle != Kingside {
return NilMove, ErrMoveInvalidCastle
}
if b.containsPieceAt(F8) || b.containsPieceAt(G8) {
Expand All @@ -860,7 +920,7 @@ func (b Board) getKingsideCastle(color Color) (Move, error) {

func (b Board) getQueensideCastle(color Color) (Move, error) {
if color == White {
if b.wCastle != Both && b.wCastle != Queen {
if b.wCastle != Both && b.wCastle != Queenside {
return NilMove, ErrMoveInvalidCastle
}
if b.containsPieceAt(B1) || b.containsPieceAt(C1) || b.containsPieceAt(D1) {
Expand All @@ -869,9 +929,9 @@ func (b Board) getQueensideCastle(color Color) (Move, error) {
if b.positionAttackedBy(B1, Black) || b.positionAttackedBy(C1, Black) || b.positionAttackedBy(D1, Black) {
return NilMove, ErrMoveThroughCheck
}
return Move{E1, B1}, nil
return Move{E1, C1}, nil
} else {
if b.bCastle != Both && b.bCastle != Queen {
if b.bCastle != Both && b.bCastle != Queenside {
return NilMove, ErrMoveInvalidCastle
}
if b.containsPieceAt(B8) || b.containsPieceAt(C8) || b.containsPieceAt(D8) {
Expand All @@ -880,7 +940,7 @@ func (b Board) getQueensideCastle(color Color) (Move, error) {
if b.positionAttackedBy(B8, White) || b.positionAttackedBy(C8, White) || b.positionAttackedBy(D8, White) {
return NilMove, ErrMoveThroughCheck
}
return Move{E8, B8}, nil
return Move{E8, C8}, nil
}
}

Expand Down
48 changes: 46 additions & 2 deletions board_king_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (s *BoardSuite) TestBoardMoveFromAlgebraicWhiteQueensideCastle(c *C) {
move, err := b.MoveFromAlgebraic("O-O-O", White)
c.Assert(err, IsNil)
c.Assert(move.From, Equals, E1)
c.Assert(move.To, Equals, B1)
c.Assert(move.To, Equals, C1)
}

func (s *BoardSuite) TestBoardMoveFromAlgebraicWhiteKingsideCastleBad(c *C) {
Expand Down Expand Up @@ -59,7 +59,7 @@ func (s *BoardSuite) TestBoardMoveFromAlgebraicBlackQueensideCastle(c *C) {
move, err := b.MoveFromAlgebraic("O-O-O", Black)
c.Assert(err, IsNil)
c.Assert(move.From, Equals, E8)
c.Assert(move.To, Equals, B8)
c.Assert(move.To, Equals, C8)
}

func (s *BoardSuite) TestBoardMoveFromAlgebraicBlackKingsideCastleBad(c *C) {
Expand Down Expand Up @@ -96,3 +96,47 @@ func (s *BoardSuite) TestBoardMoveFromAlgebraicBlackKingG8G7(c *C) {
c.Assert(move.From, Equals, G8)
c.Assert(move.To, Equals, G7)
}

func (s *BoardSuite) TestBoardMakeAlgebraicMoveWhiteKingsideCastle(c *C) {
b, err := NewBoardFEN("rn1qr1k1/p4pbp/bp1p1np1/2pP4/4PB2/2N5/PP1NBPPP/R2QK2R w KQkq - 0 1")
c.Assert(err, IsNil)
err = b.MakeAlgebraicMove("O-O", White)
c.Assert(err, IsNil)
c.Assert(b.GetPiece(G1), Equals, WhiteKing)
c.Assert(b.GetPiece(F1), Equals, WhiteRook)
c.Assert(b.GetPiece(E1), Equals, Empty)
c.Assert(b.GetPiece(H1), Equals, Empty)
}

func (s *BoardSuite) TestBoardMakeAlgebraicMoveBlackKingsideCastle(c *C) {
b, err := NewBoardFEN("rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/3P1N2/PPP1BPPP/RNBQK2R b KQkq - 2 4")
c.Assert(err, IsNil)
err = b.MakeAlgebraicMove("O-O", Black)
c.Assert(err, IsNil)
c.Assert(b.GetPiece(G8), Equals, BlackKing)
c.Assert(b.GetPiece(F8), Equals, BlackRook)
c.Assert(b.GetPiece(E8), Equals, Empty)
c.Assert(b.GetPiece(H8), Equals, Empty)
}

func (s *BoardSuite) TestBoardMakeAlgebraicMoveWhiteQueensideCastle(c *C) {
b, err := NewBoardFEN("r2qr1k1/p4pbp/bpnp1np1/2pP4/4PB2/2N5/PPQNBPPP/R3K2R w KQkq - 2 2")
c.Assert(err, IsNil)
err = b.MakeAlgebraicMove("O-O-O", White)
c.Assert(err, IsNil)
c.Assert(b.GetPiece(C1), Equals, WhiteKing)
c.Assert(b.GetPiece(D1), Equals, WhiteRook)
c.Assert(b.GetPiece(A1), Equals, Empty)
c.Assert(b.GetPiece(E1), Equals, Empty)
}

func (s *BoardSuite) TestBoardMakeAlgebraicMoveBlackQueensideCastle(c *C) {
b, err := NewBoardFEN("r3kbnr/ppp2ppp/2n1b3/3pp3/3PP2q/2NQBN2/PPP2PPP/R3KB1R b KQkq - 6 6")
c.Assert(err, IsNil)
err = b.MakeAlgebraicMove("O-O-O", Black)
c.Assert(err, IsNil)
c.Assert(b.GetPiece(C8), Equals, BlackKing)
c.Assert(b.GetPiece(D8), Equals, BlackRook)
c.Assert(b.GetPiece(E8), Equals, Empty)
c.Assert(b.GetPiece(A8), Equals, Empty)
}
12 changes: 6 additions & 6 deletions fen.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,24 @@ func ParseFEN(fenstr string) (*FEN, error) {
}

if strings.Contains(castleStr, "k") {
fen.BlackCastleStatus = King
fen.BlackCastleStatus = Kingside
}
if strings.Contains(castleStr, "q") {
if fen.BlackCastleStatus == King {
if fen.BlackCastleStatus == Kingside {
fen.BlackCastleStatus = Both
} else {
fen.BlackCastleStatus = Queen
fen.BlackCastleStatus = Queenside
}
}

if strings.Contains(castleStr, "K") {
fen.WhiteCastleStatus = King
fen.WhiteCastleStatus = Kingside
}
if strings.Contains(castleStr, "Q") {
if fen.WhiteCastleStatus == King {
if fen.WhiteCastleStatus == Kingside {
fen.WhiteCastleStatus = Both
} else {
fen.WhiteCastleStatus = Queen
fen.WhiteCastleStatus = Queenside
}
}

Expand Down
Loading

0 comments on commit b4db00c

Please sign in to comment.