• Stars
    star
    51
  • Rank 568,706 (Top 12 %)
  • Language
    Scala
  • License
    MIT License
  • Created about 9 years ago
  • Updated about 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A chess library that runs on the server (Scala) and on the browser (ScalaJS).

Ostinato A chess library that runs on the server (Scala), on the browser (ScalaJS) and on the REPL.

Build Status GitHub license

Blogpost

Best introduction to the library with code examples in JavaScript, Scala and in the REPL.

Chess Game Parser (using ChessBoardJS)

Tool to paste any chess match in any known notation and browse through the moves via Chessboard. Also play from any board state against the AI, or convert to any other notation.

Chess Game (using ChessBoardJS)

Play a Chess Match against the AI. A hacker will be able to play from whatever board starting position, as white or black, configuring AI's strength and enabling debug mode.

Chess Game Notation Converter

Convert any pasted chess match in any known notation to any other known notation.

Chess Auto-play (using ChessBoardJS)

Two AI's playing each other (making random moves).

Scaladoc

Features

  • Supporting the following Chess notations (with variants): PGN, Algebraic, Figurine, Coordinate, Descriptive, ICCF, Smith and FEN
  • Random and Basic AI available based on minimax with alpha-beta pruning
  • Compiled for JVM and JS => can serve as backend or in the frontend
  • Fully stateless design => thread-safe & scalable; no shared mutable state & no side-effects
  • Functional design; no nulls or exception handling x Object Oriented design with inheritance but no downcasting
  • ostinato.js on the front-end, Akka HTTP Server on the back-end
  • Docker Hub image available; Kubernetes deployment, service and auto-scaling examples on the blogpost

Importing a ChessBoard

$ sbt pack && scala -cp target/pack/lib/ostinato_2.12-1.0.2.jar

scala> import ostinato.chess.core._
import ostinato.chess.core._

// Import a chessboard by drawing it
scala> val game = ChessGame.fromGridString(
        """........
          |........
          |........
          |...โ™œ....
          |........
          |........
          |........
          |........""".stripMargin, turn = BlackChessPlayer).get


// Get available actions (note that the board keeps track of turns; 0 actions for white here!)
scala> val actions = game.board.actions
actions: Set[ostinato.chess.core.ChessAction] = Set(Black's Rook moves to a5, Black's Rook moves to d2, 
Black's Rook moves to d3, ...)

// Print them out! 
scala> actions map game.board.doAction foreach (b => println(b.get + "\n"))
// -> Shows on console (outlined horizontally for brevity)
...โ™œ....    ........    ........    ........    ........    ........    ........
........    ........    ........    ........    ........    ........    ........
........    ...โ™œ....    ........    ........    ........    ........    ........
........    ........    .โ™œ......    โ™œ.......    .....โ™œ..    ........    ....โ™œ...
........    ........    ........    ........    ........    ........    ........
........    ........    ........    ........    ........    ........    ........
........    ........    ........    ........    ........    ...โ™œ....    ........
........    ........    ........    ........    ........    ........    ........

........    ........    ........    ........    ........    ........    ........
........    ...โ™œ....    ........    ........    ........    ........    ........
........    ........    ........    ........    ........    ........    ........
........    ........    .......โ™œ    ......โ™œ.    ..โ™œ.....    ........    ........
........    ........    ........    ........    ........    ........    ...โ™œ....
........    ........    ........    ........    ........    ...โ™œ....    ........
........    ........    ........    ........    ........    ........    ........
...โ™œ....    ........    ........    ........    ........    ........    ........

Importing a game from any known notation, without specifying which one

it("should parse the same game in different notations") {
      val pgn =
        Notation.parseMatchString("""[Event "Ostinato Testing"]
                                    |[Site "Buenos Aires, Argentina"]
                                    |[Date "2015.??.??"]
                                    |[Round "1"]
                                    |[Result "ยฝโ€“ยฝ"]
                                    |[White "Fake Player 1"]
                                    |[Black "Fake Player 2"]
                                    |
                                    |1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. Bb5+ Bd7 5. Bxd7+ Qxd7 6. Nge2
                                    |dxe4 7. 0-0
                                    |""".stripMargin)

      val algebraic =
        Notation.parseMatchString("""e4 e6
                                    |d4 d5
                                    |Nc3 Bb4
                                    |Bb5+ Bd7
                                    |Bxd7+ Qxd7
                                    |Nge2 dxe4
                                    |0-0""".stripMargin)

      val figurine =
        Notation.parseMatchString("""e4 e6
                                    |d4 d5
                                    |โ™˜c3 โ™b4
                                    |โ™—b5+ โ™d7
                                    |โ™—xd7+ โ™›xd7
                                    |โ™˜ge2 dxe4
                                    |0-0""".stripMargin)

      val coordinate =
        Notation.parseMatchString("""
                                    |1. e2-e4 e7-e6
                                    |2. d2-d4 d7-d5
                                    |3. b1-c3 f8-b4
                                    |4. f1-b5+ c8-d7
                                    |5. b5xd7+ d8xd7
                                    |6. g1-e2 d5xe4
                                    |7. 0-0""".stripMargin)

      val descriptive =
        Notation.parseMatchString("""
                                    |1. P-K4 P-K3
                                    |2. P-Q4 P-Q4
                                    |3. N-QB3 B-N5
                                    |4. B-N5ch B-Q2
                                    |5. BxBch QxB
                                    |6. KN-K2 PxP
                                    |7. 0-0
                                    |""".stripMargin)

      val iccf =
        Notation.parseMatchString("""
                                    |1. 5254 5756
                                    |2. 4244 4745
                                    |3. 2133 6824
                                    |4. 6125 3847
                                    |5. 2547 4847
                                    |6. 7152 4554
                                    |7. 5171""".stripMargin)

      val smith =
        Notation.parseMatchString("""
                                    |1. e2e4  e7e6
                                    |2. d2d4  d7d5
                                    |3. b1c3  f8b4
                                    |4. f1b5  c8d7
                                    |5. b5d7b d8d7b
                                    |6. g1e2  d5e4p
                                    |7. e1g1c""".stripMargin)

      Set(pgn, algebraic, figurine, coordinate, descriptive, iccf, smith) foreach {
        case Right(parsedGame) โ‡’
          parsedGame.size shouldBe 13
          parsedGame.last shouldBe (CastlingAction.whiteKingside(), ChessGame.fromString(
            """โ™œโ™ž..โ™š.โ™žโ™œ
              |โ™Ÿโ™Ÿโ™Ÿโ™›.โ™Ÿโ™Ÿโ™Ÿ
              |....โ™Ÿ...
              |........
              |.โ™.โ™™โ™Ÿ...
              |..โ™˜.....
              |โ™™โ™™โ™™.โ™˜โ™™โ™™โ™™
              |โ™–.โ™—โ™•.โ™–โ™”.""".stripMargin, turn = BlackChessPlayer, castlingAvailable = castlingOnlyBlackAvailable,
            fullMoveNumber = 7, halfMoveClock = 1
          ).board)
        case _ โ‡’
          fail
      }
    }

Some illustrative tests

  • En Passant
    it("should not find en passant take move for black pawn, since king would be threatened") {
      val game = ChessGame.fromGridString(
        """....โ™–...
          |........
          |...โ†“....
          |...โ™™โ™Ÿ...
          |........
          |........
          |....โ™š...
          |........""".stripMargin).get

      game.whitePlayer.pawns.head.actions(game.board).size shouldBe 1
    }
  • Algebraic Notation
CastlingAction.blackQueenside().toAn shouldBe "0-0-0"
TakeMovement(โ™(XY(1, 3), WhiteChessPlayer), XY(1, -1), โ™ž(XY(2, 2), BlackChessPlayer)).toAn shouldBe "Bxc6"
  • FEN Notation importing/exporting
    it("should encode this board") {
      ChessGame.fromGridString(
        """.......โ™”
          |........
          |โ™š.โ™™.....
          |.......โ™Ÿ
          |........
          |........
          |........
          |........""".stripMargin).get.board.toFen shouldBe "7K/8/k1P5/7p/8/8/8/8"
    }
    it("should decode a chess setup with black en passant in FEN Notation") {
      ChessGame.fromFen("rnbqkbnr/p1pppppp/8/1p6/8/8/PPPPPPPP/RNBQKBNR w KQkq b6 4 5") shouldBe
      Some(ChessGame.fromGridString(
      """โ™œโ™žโ™โ™›โ™šโ™โ™žโ™œ
        |โ™Ÿ.โ™Ÿโ™Ÿโ™Ÿโ™Ÿโ™Ÿโ™Ÿ
        |.โ†“......
        |.โ™Ÿ......
        |........
        |........
        |โ™™โ™™โ™™โ™™โ™™โ™™โ™™โ™™
        |โ™–โ™˜โ™—โ™•โ™”โ™—โ™˜โ™–""".stripMargin, turn = WhiteChessPlayer, castlingFullyAvailable, 5, 4).get)
    }    

More Repositories

1

chart

Quick & smart charting for STDIN
Go
544
star
2

sqlparser

Simple SQL parser meant for querying CSV files
Go
392
star
3

flowbro

Real-time flowchart visualisation for Kafka-based distributed systems.
Go
121
star
4

sql

MySQL & PostgreSQL pipe
Go
86
star
5

gomario

Basic Golang text-mode Mario-like game
Go
76
star
6

cheesse

Package, server, cli tool and WebAssembly binary for chess use cases.
Go
63
star
7

jira-cli

Lightweight bash script for easily querying your company's JIRA issues
Shell
42
star
8

crypto-candles

Universal crypto candlestick iterator library & CLI
Go
13
star
9

sd

Diffs two streams of newline-separated strings, timing them out if necessary.
Go
13
star
10

leetcode

Go
12
star
11

parseq

Parallel processing with sequential output, respecting order of input
Go
10
star
12

Spreadsheet-to-MediaWiki-table-Converter

Converts an Google Spreadsheet/Excel Sheet to MediaWiki table format, providing styling features.
PHP
10
star
13

mediawiki-table-utility

A handy tool to convert tab-separated tables (e.g. Excel, Google Spreadsheets) to the MediaWiki table format (e.g. Wikipedia)
HTML
7
star
14

kafka-examples

A suite of working test cases for getting started with Apache Kafka painlessly (in Scala)
Scala
5
star
15

bookie

Indexing for Kafka queues.
Go
4
star
16

ponganoid

A simple cli game reminiscent of Pong and Arkanoid.
Go
4
star
17

sctool

Starcraft: Remastered replay analyzer library and CLI tool
Go
3
star
18

hackerrank

Go
3
star
19

happiest-state-python

Determining the happiest USA state using Twitter streams and Sentiment Analysis in Python.
Python
3
star
20

blacklist

DNS-based blacklist checker
Go
3
star
21

fsm

Ridiculously hacky tool to help me keep in touch with my friends.
Go
2
star
22

iknowkungfoo

Website aiming to provide easiest way to learn Algos & DS for FAANGs
Go
2
star
23

bincli

Binance CLI
Go
2
star
24

cheesse-examples

JavaScript
2
star
25

crypto-predictions

State machine-based engine for tracking crypto-related predictions across social media posts.
Go
2
star
26

ostinato-examples

A quick and dirty demo to showcase the ostinato library
JavaScript
2
star
27

termserve

Go
1
star
28

chessboard-image-builder

Shell
1
star
29

kafkasimpletest

A working smoke int test for Apache Kafka to start up a Scala project
Scala
1
star
30

signal-checker

cli tool, server & library to check the results of crypto signals against an exchange's historical data.
Go
1
star
31

tablerenderer

A minimalist script to render an associative array as a MySQL result table
PHP
1
star
32

marianogappa.github.io

My blog about Software Engineering and Music Production
HTML
1
star