Skip to content

Commit

Permalink
feat: removed fivefold repetition, condensed to twenty-five move rule
Browse files Browse the repository at this point in the history
  • Loading branch information
dechristopher committed Mar 12, 2021
1 parent 58fa431 commit 731eded
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 73 deletions.
31 changes: 9 additions & 22 deletions game.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,12 @@ const (
DrawOffer
// Stalemate indicates that the game was drawn by stalemate.
Stalemate
// ThreefoldRepetition indicates that the game was drawn when the game
// state was repeated three times and a player requested a draw.
// ThreefoldRepetition indicates that the game was automatically drawn
// by the game state being repeated three times.
ThreefoldRepetition
// FivefoldRepetition indicates that the game was automatically drawn
// by the game state being repeated five times.
FivefoldRepetition
// FiftyMoveRule indicates that the game was drawn by the half
// move clock being one hundred or greater when a player requested a draw.
FiftyMoveRule
// SeventyFiveMoveRule indicates that the game was automatically drawn
// when the half move clock was one hundred and fifty or greater.
SeventyFiveMoveRule
// TwentyFiveMoveRule indicates that the game was automatically drawn
// when the half move clock was fifty or greater.
TwentyFiveMoveRule
// InsufficientMaterial indicates that the game was automatically drawn
// because there was insufficient material for checkmate.
InsufficientMaterial
Expand Down Expand Up @@ -267,10 +261,6 @@ func (g *Game) Draw(method Method) error {
if g.numRepetitions() < 3 {
return errors.New("octad: draw by ThreefoldRepetition requires at least three repetitions of the current board state")
}
case FiftyMoveRule:
if g.pos.halfMoveClock < 100 {
return fmt.Errorf("octad: draw by FiftyMoveRule requires the half move clock to be at 100 or greater but is %d", g.pos.halfMoveClock)
}
case DrawOffer:
default:
return fmt.Errorf("octad: unsupported draw method %s", method.String())
Expand Down Expand Up @@ -300,9 +290,6 @@ func (g *Game) EligibleDraws() []Method {
if g.numRepetitions() >= 3 {
draws = append(draws, ThreefoldRepetition)
}
if g.pos.halfMoveClock >= 100 {
draws = append(draws, FiftyMoveRule)
}
return draws
}

Expand Down Expand Up @@ -363,15 +350,15 @@ func (g *Game) updatePosition() {
}

// five fold rep creates automatic draw
if !g.ignoreAutomaticDraws && g.numRepetitions() >= 5 {
if !g.ignoreAutomaticDraws && g.numRepetitions() >= 3 {
g.outcome = Draw
g.method = FivefoldRepetition
g.method = ThreefoldRepetition
}

// 75 move rule creates automatic draw
if !g.ignoreAutomaticDraws && g.pos.halfMoveClock >= 150 && g.method != Checkmate {
if !g.ignoreAutomaticDraws && g.pos.halfMoveClock >= 50 && g.method != Checkmate {
g.outcome = Draw
g.method = SeventyFiveMoveRule
g.method = TwentyFiveMoveRule
}

// insufficient material creates automatic draw
Expand Down
55 changes: 4 additions & 51 deletions game_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,55 +158,8 @@ func TestInvalidThreeFoldRepetition(t *testing.T) {
}
}

func TestFiveFoldRepetition(t *testing.T) {
g, err := NewGame()
if err != nil {
t.Fatalf(err.Error())
return
}
moves := []string{
"Nc2", "Nb3", "Na1", "Nd4",
"Nc2", "Nb3", "Na1", "Nd4",
"Nc2", "Nb3", "Na1", "Nd4",
"Nc2", "Nb3", "Na1", "Nd4",
"Nc2", "Nb3", "Na1", "Nd4",
}
for _, m := range moves {
if err = g.MoveStr(m); err != nil {
t.Fatal(err)
}
}
if g.Outcome() != Draw || g.Method() != FivefoldRepetition {
t.Fatal("game: should automatically draw after five repetitions")
}
}

func TestFiftyMoveRule(t *testing.T) {
ofen, _ := OFEN("n2k/4/3K/N3 b - - 100 60")
g, err := NewGame(ofen)
if err != nil {
t.Fatalf(err.Error())
return
}
if err := g.Draw(FiftyMoveRule); err != nil {
t.Fatal(err)
}
}

func TestInvalidFiftyMoveRule(t *testing.T) {
ofen, _ := OFEN("n2k/4/3K/N3 b - - 99 60")
g, err := NewGame(ofen)
if err != nil {
t.Fatalf(err.Error())
return
}
if err = g.Draw(FiftyMoveRule); err == nil {
t.Fatal("game: should require fifty moves")
}
}

func TestSeventyFiveMoveRule(t *testing.T) {
ofen, _ := OFEN("n2k/4/3K/N3 b - - 149 80")
func TestTwentyFiveMoveRule(t *testing.T) {
ofen, _ := OFEN("n2k/4/3K/N3 b - - 49 24")
g, err := NewGame(ofen)
if err != nil {
t.Fatalf(err.Error())
Expand All @@ -215,8 +168,8 @@ func TestSeventyFiveMoveRule(t *testing.T) {
if err = g.MoveStr("Kc4"); err != nil {
t.Fatal(err)
}
if g.Outcome() != Draw || g.Method() != SeventyFiveMoveRule {
t.Fatal("game: should automatically draw after seventy five moves w/ no pawn move or capture")
if g.Outcome() != Draw || g.Method() != TwentyFiveMoveRule {
t.Fatal("game: should automatically draw after twenty five moves w/ no pawn move or capture")
}
}

Expand Down

0 comments on commit 731eded

Please sign in to comment.