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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.bloop/
.metals/
.vscode/

target/
out/
project/project
project/metals.sbt
15 changes: 11 additions & 4 deletions src/main/scala/Puzzles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import akka.util.ByteString
import chess.format.{ Fen, FullFen }
import com.typesafe.config.ConfigFactory
import java.nio.file.Paths
import java.time.Instant
import lila.db.dsl.*
import reactivemongo.akkastream.cursorProducer
import reactivemongo.api.*
Expand All @@ -27,7 +28,8 @@ object Puzzles:
plays: Int,
themes: List[String],
openings: List[String],
gameUrl: String
gameUrl: String,
day: Option[Instant]
)

def main(args: Array[String]): Unit =
Expand Down Expand Up @@ -65,6 +67,7 @@ object Puzzles:
plays <- doc.int("plays")
themes <- doc.getAsOpt[List[String]]("themes")
gameId <- doc.string("gameId")
day = doc.getAsOpt[Instant]("day")
openings = doc.getAsOpt[List[String]]("opening")
yield PuzzleLine(
id = id,
Expand All @@ -80,7 +83,8 @@ object Puzzles:
val hash = Fen.readPly(fen).map(_ + 1).fold("")(p => s"#$p")
s"https://lichess.org/${gameId}${if asWhite then "" else "/black"}$hash"
,
openings = openings.getOrElse(Nil)
openings = openings.getOrElse(Nil),
day = day
)

def toCsvLine(puzzle: PuzzleLine): String =
Expand All @@ -94,7 +98,8 @@ object Puzzles:
puzzle.plays,
puzzle.themes.sorted.mkString(" "),
puzzle.gameUrl,
puzzle.openings.mkString(" ")
puzzle.openings.mkString(" "),
puzzle.day.map(_.toEpochMilli()).getOrElse("")
).mkString(",")

def csvSink: Sink[String, Future[IOResult]] =
Expand Down Expand Up @@ -134,7 +139,9 @@ object Puzzles:
.map(toCsvLine)
.prepend(
Source(
List("PuzzleId,FEN,Moves,Rating,RatingDeviation,Popularity,NbPlays,Themes,GameUrl,OpeningTags")
List(
"PuzzleId,FEN,Moves,Rating,RatingDeviation,Popularity,NbPlays,Themes,GameUrl,OpeningTags,DailyDate"
)
)
)
.runWith(csvSink)
Expand Down
13 changes: 8 additions & 5 deletions web/index.html.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@
</p>
<h3 id="puzzle_format">Format</h3>
<p>Puzzles are formatted as standard CSV. The fields are as follows:</p>
<pre>PuzzleId,FEN,Moves,Rating,RatingDeviation,Popularity,NbPlays,Themes,GameUrl,OpeningTags</pre>
<pre>PuzzleId,FEN,Moves,Rating,RatingDeviation,Popularity,NbPlays,Themes,GameUrl,OpeningTags,DailyDate</pre>
<h3 id="puzzle_sample">Sample</h3>
<pre>00sHx,q3k1nr/1pp1nQpp/3p4/1P2p3/4P3/B1PP1b2/B5PP/5K2 b k - 0 17,e8d7 a2e6 d7d8 f7f8,1760,80,83,72,mate mateIn2 middlegame short,https://lichess.org/yyznGmXs/black#34,Italian_Game Italian_Game_Classical_Variation
00sJ9,r3r1k1/p4ppp/2p2n2/1p6/3P1qb1/2NQR3/PPB2PP1/R1B3K1 w - - 5 18,e3g3 e8e1 g1h2 e1c1 a1c1 f4h6 h2g1 h6c1,2671,105,87,325,advantage attraction fork middlegame sacrifice veryLong,https://lichess.org/gyFeQsOE#35,French_Defense French_Defense_Exchange_Variation
00sJb,Q1b2r1k/p2np2p/5bp1/q7/5P2/4B3/PPP3PP/2KR1B1R w - - 1 17,d1d7 a5e1 d7d1 e1e3 c1b1 e3b6,2235,76,97,64,advantage fork long,https://lichess.org/kiuvTFoE#33,Sicilian_Defense Sicilian_Defense_Dragon_Variation
00sO1,1k1r4/pp3pp1/2p1p3/4b3/P3n1P1/8/KPP2PN1/3rBR1R b - - 2 31,b8c7 e1a5 b7b6 f1d1,998,85,94,293,advantage discoveredAttack master middlegame short,https://lichess.org/vsfFkG0s/black#62,</pre>
<pre>00sHx,q3k1nr/1pp1nQpp/3p4/1P2p3/4P3/B1PP1b2/B5PP/5K2 b k - 0 17,e8d7 a2e6 d7d8 f7f8,1760,80,83,72,mate mateIn2 middlegame short,https://lichess.org/yyznGmXs/black#34,Italian_Game Italian_Game_Classical_Variation,
00sJ9,r3r1k1/p4ppp/2p2n2/1p6/3P1qb1/2NQR3/PPB2PP1/R1B3K1 w - - 5 18,e3g3 e8e1 g1h2 e1c1 a1c1 f4h6 h2g1 h6c1,2671,105,87,325,advantage attraction fork middlegame sacrifice veryLong,https://lichess.org/gyFeQsOE#35,French_Defense French_Defense_Exchange_Variation,1607774862751
00sJb,Q1b2r1k/p2np2p/5bp1/q7/5P2/4B3/PPP3PP/2KR1B1R w - - 1 17,d1d7 a5e1 d7d1 e1e3 c1b1 e3b6,2235,76,97,64,advantage fork long,https://lichess.org/kiuvTFoE#33,Sicilian_Defense Sicilian_Defense_Dragon_Variation,
00sO1,1k1r4/pp3pp1/2p1p3/4b3/P3n1P1/8/KPP2PN1/3rBR1R b - - 2 31,b8c7 e1a5 b7b6 f1d1,998,85,94,293,advantage discoveredAttack master middlegame short,https://lichess.org/vsfFkG0s/black#62,,</pre>
<h3 id="puzzle_notes">Notes</h3>
<p>
Moves are in UCI format. Use a chess library to convert them to SAN, for display.
Expand All @@ -167,6 +167,9 @@
The <code>OpeningTags</code> field is only set for puzzles starting before move 20.
Here's the <a href="https://github.com/lichess-org/chess-openings">list of possible openings</a>.
</p>
<p>
The <code>DailyDate</code> field is a Unix timestamp in milliseconds. If present, it indicates the date when the puzzle was featured as a daily puzzle on <a href="https://lichess.org/training/daily">lichess.org/training/daily</a>.
</p>
<p>
<a href="https://github.com/ornicar/lichess-puzzler/tree/master/generator">Generating these chess puzzles</a>
took more than 100 years of CPU time.<br />
Expand Down
Loading