README.md

# ChessLogic

## Description

This package contains logic to play the game of chess. 
Functional Chess validator written in Elixir. 

It includes [fcardinaux/chessfold](https://github.com/fcardinaux/chessfold/blob/master/erl/chessfold.erl) source files, as hex does not permit non hex dependencies.

It uses leex to parse pgn files, and chessfold to implement chess logic. Both in Erlang.

It understands following rules:

* draw by 3 times the same position
* draw by 50 moves rule
* mat
* pat
* check
* taken
* en passant
* castling

But it does not understand draw by not enough material rule! It is not meant to be an AI of some sort, just a simple chess move validator (and generator), to be used in a larger project.

It also supports importing/exporting pgn files.

## Installation

The package can be installed by adding `chess_logic` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [{:chess_logic, "~> 0.1.0"}]
end
```

[Available in Hex](https://hex.pm/packages/chess_logic).

Documentation can be found at [https://hexdocs.pm/chess_logic](https://hexdocs.pm/chess_logic).

## Erlang and dialyxir configuration

Because of some warnings detected in Erlang outside code (chessfold, leex), it is nice to configure dialyxir to avoid them... 

Update mix.exs

      erlc_paths: ["src"],
      dialyzer: [
        ignore_warnings: "dialyzer.ignore-warnings"
      ],

Add file ./dialyzer.ignore-warnings

```elixir
Unknown function chessfold
Guard test RowId::0
The variable _ can never match since previous clauses completely covered the type
Function yyrev/2 will never be called
```

## Sample usage

More sample usage in the test folder.

 ```elixir
iex(1)> g = ChessLogic.Game.new
%ChessLogic.Game{
  current_position: %ChessLogic.Position{
    fen: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
    position: [
      ["r", "n", "b", "q", "k", "b", "n", "r"],
      ["p", "p", "p", "p", "p", "p", "p", "p"],
      [" ", " ", " ", " ", " ", " ", " ", " "],
      [" ", " ", " ", " ", " ", " ", " ", " "],
      [" ", " ", " ", " ", " ", " ", " ", " "],
      [" ", " ", " ", " ", " ", " ", " ", " "],
      ["P", "P", "P", "P", "P", "P", "P", "P"],
      ["R", "N", "B", "Q", "K", "B", "N", "R"]
    ]
  },
  history: [],
  result: nil,
  status: :started,
  winner: nil
}
iex(2)> {:ok, g} = ChessLogic.Game.play(g, "e2e4")
{:ok,
 %ChessLogic.Game{
   current_position: %ChessLogic.Position{
     fen: "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1",
     position: [
       ["r", "n", "b", "q", "k", "b", "n", "r"],
       ["p", "p", "p", "p", "p", "p", "p", "p"],
       [" ", " ", " ", " ", " ", " ", " ", " "],
       [" ", " ", " ", " ", " ", " ", " ", " "], 
       [" ", " ", " ", " ", "P", " ", " ", " "],
       [" ", " ", " ", " ", " ", " ", " ", " "],
       ["P", "P", "P", "P", " ", "P", "P", "P"],
       ["R", "N", "B", "Q", "K", "B", "N", "R"]
     ]
   },
   history: [
     %{
       fen: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
       move: "e2e4",
       san: "e4"
     }
   ],
   result: nil,
   status: :playing,
   winner: nil
 }}
iex(3)> {:ok, g} = ChessLogic.Game.play(g, "g8f6")
{:ok,
 %ChessLogic.Game{
   current_position: %ChessLogic.Position{
     fen: "rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2",
     position: [
       ["r", "n", "b", "q", "k", "b", " ", "r"],
       ["p", "p", "p", "p", "p", "p", "p", "p"],
       [" ", " ", " ", " ", " ", "n", " ", " "],
       [" ", " ", " ", " ", " ", " ", " ", " "],
       [" ", " ", " ", " ", "P", " ", " ", " "],
       [" ", " ", " ", " ", " ", " ", " ", " "],
       ["P", "P", "P", "P", " ", "P", "P", "P"],
       ["R", "N", "B", "Q", "K", "B", "N", "R"]
     ]
   },
   history: [
     %{
       fen: "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1",
       move: "g8f6",
       san: "Nf6"
     },
     %{
       fen: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
       move: "e2e4",
       san: "e4"
     }
   ],
   result: nil,
   status: :playing,
   winner: nil
 }}
iex(4)> g |> ChessLogic.Game.to_pgn()
"1. e4 Nf6"
```