Code Monkey home page Code Monkey logo

chess's Introduction

Chess

Scala CI

This project is mostly for experimental and testing purpose as it is my first project on github. Don't take it too seriously. (Though it works pretty well, and I appreciate any support)

Components

  1. A backend.
  2. An GUI implementation of the backend.
  3. A CLI to the backend.

A Framework used to simulate a chess game and capable of storing and computing positions, moves, loading and saving. When using scala, you can interact with it through framework.ChessIO trait as a pipe for in&output or JChessIO for use with Java. The main game logic is located in framework.ChessBoard. It currently features:

  1. Recognition and execution of correct moves
  2. Promotions
  3. Any types of draws (insufficient material, stalemate, ...) and mates
  4. Saving and loading your games
  5. Currently no AI opponent but I might be adding Stockfish or Lila when I feel like it
  6. A full java interface

When you start the .jar the game will open. Use a path to a saved game as parameter to open that game.

Right now there are neither animations nor sounds because I normally turn these off in chess apps. I might add these in on demand.

 

Example

example

Use 'console' argument to start in console mode:

java -jar Chess.jar console

Use a path to a saved game as additional parameter to open that game.

java -jar Chess.jar console saves/mySavedGame.save

 

Example

version 0.3
Welcome to my gorgeous CLI chess game! Type "help" and then press 'ENTER' to get a list of available commands.

    a   b   c   d   e   f   g   h
  +---+---+---+---+---+---+---+---+
8 | R | N | B | Q | K | B | N | R |
  +---+---+---+---+---+---+---+---+
7 | P | P | P | P | P | P | P | P |
  +---+---+---+---+---+---+---+---+
6 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
5 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
4 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
3 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
2 | p | p | p | p | p | p | p | p |
  +---+---+---+---+---+---+---+---+
1 | r | n | b | q | k | b | n | r |
  +---+---+---+---+---+---+---+---+

> d2d4
    a   b   c   d   e   f   g   h
  +---+---+---+---+---+---+---+---+
8 | R | N | B | Q | K | B | N | R |
  +---+---+---+---+---+---+---+---+
7 | P | P | P | P | P | P | P | P |
  +---+---+---+---+---+---+---+---+
6 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
5 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
4 |   |   |   | p |   |   |   |   |
  +---+---+---+---+---+---+---+---+
3 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
2 | p | p | p |   | p | p | p | p |
  +---+---+---+---+---+---+---+---+
1 | r | n | b | q | k | b | n | r |
  +---+---+---+---+---+---+---+---+

> save testfile

Successfully saved!

> h7h5
    a   b   c   d   e   f   g   h
  +---+---+---+---+---+---+---+---+
8 | R | N | B | Q | K | B | N | R |
  +---+---+---+---+---+---+---+---+
7 | P | P | P | P | P | P | P |   |
  +---+---+---+---+---+---+---+---+
6 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
5 |   |   |   |   |   |   |   | P |
  +---+---+---+---+---+---+---+---+
4 |   |   |   | p |   |   |   |   |
  +---+---+---+---+---+---+---+---+
3 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
2 | p | p | p |   | p | p | p | p |
  +---+---+---+---+---+---+---+---+
1 | r | n | b | q | k | b | n | r |
  +---+---+---+---+---+---+---+---+

> help

===================<HELP>===================
 - SAVE | S | WRITE | W <file path> : Save this game.
 - RESIGN  : Resign the game.
 - MOVE | MV | M <letter><digit><letter><digit> : Move a piece from one square to another.
 - TAKEBACK | T  : Take the last move back.
 - DRAW  : Propose a draw.
 - HELP | H | ? | MAN | MANUAL [command name] : Get help.
 - EXIT | HALT | STOP | DIE | END | SHUTDOWN | QUIT | KILL  : Stop this BS.
 - RESTART  : Restart the game.
 - LOAD <file path> : Load a saved game.
============================================

> load testfile
    a   b   c   d   e   f   g   h
  +---+---+---+---+---+---+---+---+
8 | R | N | B | Q | K | B | N | R |
  +---+---+---+---+---+---+---+---+
7 | P | P | P | P | P | P | P | P |
  +---+---+---+---+---+---+---+---+
6 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
5 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
4 |   |   |   | p |   |   |   |   |
  +---+---+---+---+---+---+---+---+
3 |   |   |   |   |   |   |   |   |
  +---+---+---+---+---+---+---+---+
2 | p | p | p |   | p | p | p | p |
  +---+---+---+---+---+---+---+---+
1 | r | n | b | q | k | b | n | r |
  +---+---+---+---+---+---+---+---+


Successfully loaded!

> exit
CYA...

chess's People

Contributors

slaynandkorpil avatar

Watchers

James Cloos avatar  avatar

chess's Issues

Yet another blockage problem.

Description
When testing for blockage, the king is counted as possible defender of squares. This leads to many positions that are wrongly counted as blocked.

To Reproduce
blockageKingIssue.txt
After the last move(Kd7-e6) the game detects a blocked position.

Desktop:

  • OS: Win10
  • Version alpha 0.1

Promotions ignored in new save system

When saving in v3, only move history and start position are stored although promotions cannot always be reconstructed from the move history.
The most memory efficient way to solve this would probably be saving all promotions. Another solution is storing promotions in move history.

Stalemate issue

Description
When a piece cannot move because this would lead to a check, it is not as detected as blocked.

To Reproduce
Load stalemateIssue.txt.
This does unexpectedly not result in a stalemate.

Expected behavior
Normally black's last move (Rd4-b4) would result in a stalemate as white's king can't move because of the b rook and the bishop is pinned by the a3 rook.

Desktop:

  • OS: windows 10
  • Version alpha 0.1

No error message when command unknown.

In console UI:
When requesting help for a command that is unknown, it just prints the general help info instead of an error message.
E.g. :

help laod
===================<HELP>===================
 - HELP [command name] : Get help.
 - SAVE | S | WRITE | W <file path> : Save this game.
 - EXIT | HALT | STOP | DIE | END | SHUTDOWN  : Stop this BS.
 - RESIGN  : Resign the game.
 - TAKEBACK | T  : Take the last move back.
 - DRAW  : Propose a draw.
 - RESTART  : Restart the game.
 - MOVE | M <letter><digit><letter><digit> : Move a piece from one square to another.
 - LOAD <file path> : Load a saved game.
============================================

add global save file directory

Currently the GUI app opens the C:/Users/user/Documents/ folder to load and the console app needs a full path. Maybe use smth like [dir]/save/ ?

Unable to load games drawn by stalemate

When parsing a save file with the status <boardStatus>Ended(Draw(Stalemate</boardStatus> it gives the following error:

java.lang.ClassCastException: chess.framework.BoardStatus.ResultReason.Resignation$ cannot be cast to chess.framework.BoardStatus.ResultReason.DrawResultReason
	at chess.framework.BoardStatus.GameResult.GameResult$.createResult(GameResult.scala:30)
	at chess.framework.BoardStatus.GameResult.GameResult$.apply(GameResult.scala:21)
	at chess.framework.BoardStatus.GameStatus.GameStatus$.apply(GameStatus.scala:25)
	at chess.framework.SaveLoader$Loader2$.load(SaveLoader.scala:223)
	at chess.framework.SaveLoader$.load(SaveLoader.scala:27)
	at chess.framework.ChessBoard$.loadExactPath(ChessBoard.scala:966)
	at chess.framework.ChessBoard$.load(ChessBoard.scala:958)
	at chess.framework.ChessIO.load(ChessIO.scala:100)
	at chess.framework.ChessIO.load$(ChessIO.scala:99)
	at chess.graphics.Board.load(Board.scala:130)
	at chess.graphics.CMenuBar$Menu$load$$anonfun$$lessinit$greater$8.apply(CMenuBar.scala:77)
	at chess.graphics.CMenuBar$Menu$load$$anonfun$$lessinit$greater$8.apply(CMenuBar.scala:71)
	at chess.graphics.CMenuItem$$anon$1.apply(CMenuItem.scala:13)
	at scala.swing.Action$$anon$1.actionPerformed(Action.scala:78)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
	at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:369)
	at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:349)
	at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI$Actions.actionPerformed(BasicMenuItemUI.java:935)
	at java.desktop/javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1805)
	at java.desktop/javax.swing.JComponent.processKeyBinding(JComponent.java:2901)
	at java.desktop/javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(JMenuBar.java:699)
	at java.desktop/javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(JMenuBar.java:706)
	at java.desktop/javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(JMenuBar.java:706)
	at java.desktop/javax.swing.JMenuBar.processKeyBinding(JMenuBar.java:677)
	at java.desktop/javax.swing.KeyboardManager.fireBinding(KeyboardManager.java:311)
	at java.desktop/javax.swing.KeyboardManager.fireKeyboardAction(KeyboardManager.java:297)
	at java.desktop/javax.swing.JComponent.processKeyBindingsForAllComponents(JComponent.java:2994)
	at java.desktop/javax.swing.JComponent.processKeyBindings(JComponent.java:2986)
	at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2863)
	at java.desktop/java.awt.Component.processEvent(Component.java:6355)
	at java.desktop/java.awt.Container.processEvent(Container.java:2259)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4961)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2317)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4793)
	at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1955)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:827)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1096)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:966)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:792)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4842)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2317)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2758)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4793)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:766)
	at java.desktop/java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:717)
	at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:711)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:89)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:99)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:739)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:737)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:89)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:736)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:199)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

and cannot complete parsing
ERROR graphics >> Failed to parse this file.

Unclear error when loading (probably corrupted) file.

Request
When loading blockageKingIssue.txt the error message ERROR graphics >> Unable to load file C:\Users\user\Documents\blockageKingIssue.txt is printed although the file is located at this location, the correct loader gets selected and the loading process gets at least initialized.
There should be a more specific error message at this point in time.

Additional context
The load method of Loader2 throws a java.lang.StringIndexOutOfBoundsException: begin 5, end 41, length 21 exception.

Use framework.ClassicPosition

ClassicPosition is implemented but not used.
It should be explicitly used in ChessBoard.classicalBoard to further minimize save file sizes.
It also needs to be implemented in framework.SaveLoader.Loader3.load as the special xml-elem is currently not parsed.

Performance issues

When loading saves that contain a game with a long history/ positions list or taking a move back in a long game it takes very long (2 sec and more) to load.

Castle issue

When generating the position history from a castling move, the rook does not get moved.

Recreation

  1. Load castleIssue.txt
  2. Go back a few moves and you can notice a white rook on A1, which just wasn't played correctly after white's long castle.

Declutter console

When using the console interface, it gets cluttered quit fast. Maybe print additional empty lines after every output?

Ignore empty input in console

When the input interpreter receives an empty input it still prints the error message. It should just ignore it so that you can add some spacing in the console yourself.

Wrong ending chosen.

When a game that should be ended with a mate is in a position that would also be a stalemate (besides that the king is checked), the framework counts it as stalemate.

Missing check marking after promotion

Describe the bug
When promoting to any piece and thereby checking the enemy's king, it does not get marked in red.

To Reproduce
Load the save promotionCheckProblem.txt and promote the pawn via capturing on B8 to a queen or a rook. This checks the king but it does not get displayed by the GUI.

Expected behavior
There should always be a visual feedback for check .

Desktop:

  • OS: Windows 10
  • Version alpha 0.1; 11.06.19

Show file explorer when saving for the first time.

Right now when you press Ctrl S you will never get a file selection as either you already have saved a to a file or the standard "save" (see ChessIO.scala) is used as a file name. It would be more intuitive to only use the last save file name when you already chose a file. So the first time you save you would always get the file chooser.

Error when generating reactions for java interface.

Describe the bug
When adding reactions via a JReaction instance, often the generated isDefinedAt method of the PartialFunction that gets added to the reactions gives false positive results and causes errors like java.lang.ClassCastException: chess.framework.IOEvents.NoEvent$ cannot be cast to chess.framework.IOEvents.ShowEnded

To Reproduce
Add the following reactions to an implementation of chess.framework.JavaInterfacing.JChessIO:
addReaction(new JReaction<>(System.out::println)); addReaction(new JReaction<>((ShowEnded message) -> System.out.println("Game ended with a "+message.result())));

Expected behavior
Independend from the order should always when e.g a NoEvent is thrown the first reaction get called.

Desktop :

  • OS: Windows 10
  • Version alpha 0.1

Additional context
This problem is completely irrelevant 'cause nobody likes java.

Remove capture information

The "capture" attribute of the "move" node in save files is unnecessary as it is unused. And should be able to be simply removed.

framework.Column#apply fix

The apply method in framework.Column subtracts 1 from the index so you can use the actual row counting from the board to search for a piece. This heavily interferes with the inherited methods like map or foreach.

Possible mate edgecase.

There is an edge-case of a possible piece-combination that can lead to a mate that is currently falsely handeled as draw due to insufficient material: K and B against K and N (KB can theoretically still mate)

Console game loading does not accept strings

load ".stalemateIssue.save"

ERROR: Unable to load file ".stalemateIssue.save"

load "./stalemateIssue.save"

ERROR: Unable to load file "./stalemateIssue.save"

load "C:\Users\user\Documents\stalemateIssue.save"

ERROR: Unable to load file "C:\Users\user\Documents\stalemateIssue.save"

King-less error prevention

Rework backend/framework so that a number of kings != 0 does not result in an runtime-error.
At many occasions in chess.framework.ChessBoard it is assumed that there is exactly one king per color.

This will otherwise cause problems when implementing suicide chess or a board editor.

Broken promotion

Description
When the promotion-chooser popup window opens, you can actually just close it by pressing the red [X] button which will lead to game being stuck in a state in which the backend waits for a promotion and the frontend just does not allow to promote the piece.

Expected behavior
It should not be possible to close this window.

Save file in broken state

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.