Upload 21 files
Browse files- assets/.DS_Store +0 -0
- assets/chesspieces/bB.png +0 -0
- assets/chesspieces/bK.png +0 -0
- assets/chesspieces/bN.png +0 -0
- assets/chesspieces/bP.png +0 -0
- assets/chesspieces/bQ.png +0 -0
- assets/chesspieces/bR.png +0 -0
- assets/chesspieces/wB.png +0 -0
- assets/chesspieces/wK.png +0 -0
- assets/chesspieces/wN.png +0 -0
- assets/chesspieces/wP.png +0 -0
- assets/chesspieces/wQ.png +0 -0
- assets/chesspieces/wR.png +0 -0
- board.html +14 -0
- modules/__pycache__/chess.cpython-310.pyc +0 -0
- modules/__pycache__/states.cpython-310.pyc +0 -0
- modules/__pycache__/utility.cpython-310.pyc +0 -0
- modules/chess.py +149 -0
- modules/states.py +31 -0
- modules/utility.py +34 -0
- style.css +31 -0
assets/.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
assets/chesspieces/bB.png
ADDED
|
assets/chesspieces/bK.png
ADDED
|
assets/chesspieces/bN.png
ADDED
|
assets/chesspieces/bP.png
ADDED
|
assets/chesspieces/bQ.png
ADDED
|
assets/chesspieces/bR.png
ADDED
|
assets/chesspieces/wB.png
ADDED
|
assets/chesspieces/wK.png
ADDED
|
assets/chesspieces/wN.png
ADDED
|
assets/chesspieces/wP.png
ADDED
|
assets/chesspieces/wQ.png
ADDED
|
assets/chesspieces/wR.png
ADDED
|
board.html
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<link rel="stylesheet" href="css/chessboard-1.0.0.min.css">
|
| 2 |
+
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
|
| 3 |
+
<script src="js/chessboard-1.0.0.min.js"></script>
|
| 4 |
+
|
| 5 |
+
<div id="board" style="width: 300px"></div>
|
| 6 |
+
|
| 7 |
+
<script>
|
| 8 |
+
var config = {
|
| 9 |
+
pieceTheme: 'https://chessboardjs.com/img/chesspieces/wikipedia/{piece}.png',
|
| 10 |
+
position: 'start'
|
| 11 |
+
}
|
| 12 |
+
var board = Chessboard('board', config)
|
| 13 |
+
// var board = ChessBoard('board', 'start');
|
| 14 |
+
</script>
|
modules/__pycache__/chess.cpython-310.pyc
ADDED
|
Binary file (5.02 kB). View file
|
|
|
modules/__pycache__/states.cpython-310.pyc
ADDED
|
Binary file (735 Bytes). View file
|
|
|
modules/__pycache__/utility.cpython-310.pyc
ADDED
|
Binary file (868 Bytes). View file
|
|
|
modules/chess.py
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import chess
|
| 2 |
+
import streamlit as st
|
| 3 |
+
|
| 4 |
+
class Chess:
|
| 5 |
+
def __init__(self, width, fen):
|
| 6 |
+
self.width = width
|
| 7 |
+
self.fen = fen
|
| 8 |
+
|
| 9 |
+
def __header__(self):
|
| 10 |
+
return """
|
| 11 |
+
<link rel="stylesheet"
|
| 12 |
+
href="https://unpkg.com/@chrisoakman/chessboardjs@1.0.0/dist/chessboard-1.0.0.min.css"
|
| 13 |
+
integrity="sha384-q94+BZtLrkL1/ohfjR8c6L+A6qzNH9R2hBLwyoAfu3i/WCvQjzL2RQJ3uNHDISdU"
|
| 14 |
+
crossorigin="anonymous">
|
| 15 |
+
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
|
| 16 |
+
<script src="https://unpkg.com/@chrisoakman/chessboardjs@1.0.0/dist/chessboard-1.0.0.min.js"
|
| 17 |
+
integrity="sha384-8Vi8VHwn3vjQ9eUHUxex3JSN/NFqUg3QbPyX8kWyb93+8AC/pPWTzj+nHtbC5bxD"
|
| 18 |
+
crossorigin="anonymous"></script>
|
| 19 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.2/chess.js"
|
| 20 |
+
integrity="sha384-s3XgLpvmHyscVpijnseAmye819Ee3yaGa8NxstkJVyA6nuDFjt59u1QvuEl/mecz"
|
| 21 |
+
crossorigin="anonymous"></script>
|
| 22 |
+
"""
|
| 23 |
+
|
| 24 |
+
def __sidetomove__(self):
|
| 25 |
+
return 'white' if chess.Board(self.fen).turn else 'black'
|
| 26 |
+
|
| 27 |
+
def __board_placeholder__(self):
|
| 28 |
+
return f"""
|
| 29 |
+
<div id="myBoard" style="width: {self.width}px"></div><br>
|
| 30 |
+
<label><strong>Status:</strong></label>
|
| 31 |
+
<div id="status"></div>
|
| 32 |
+
"""
|
| 33 |
+
|
| 34 |
+
def puzzle_board(self):
|
| 35 |
+
sidetomove = self.__sidetomove__()
|
| 36 |
+
|
| 37 |
+
script1 = f"""
|
| 38 |
+
// NOTE: this example uses the chess.js library:
|
| 39 |
+
// https://github.com/jhlywa/chess.js
|
| 40 |
+
|
| 41 |
+
var board = null
|
| 42 |
+
var game = new Chess('{self.fen}')
|
| 43 |
+
var $status = $('#status')
|
| 44 |
+
var $fen = $('#fen')
|
| 45 |
+
var $pgn = $('#pgn')
|
| 46 |
+
"""
|
| 47 |
+
|
| 48 |
+
game_over_ = """
|
| 49 |
+
// do not pick up pieces if the game is over
|
| 50 |
+
if (game.game_over()) return false
|
| 51 |
+
if ((game.turn() === 'w' && piece.search(/^b/) !== -1) ||
|
| 52 |
+
(game.turn() === 'b' && piece.search(/^w/) !== -1)) return false
|
| 53 |
+
"""
|
| 54 |
+
|
| 55 |
+
script2 = f"""
|
| 56 |
+
function onDragStart (source, piece, position, orientation) {{{game_over_}}}
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
script3 = """
|
| 60 |
+
function onDrop (source, target) {
|
| 61 |
+
// see if the move is legal
|
| 62 |
+
var move = game.move({
|
| 63 |
+
from: source,
|
| 64 |
+
to: target,
|
| 65 |
+
promotion: 'q' // NOTE: always promote to a queen for example simplicity
|
| 66 |
+
})
|
| 67 |
+
|
| 68 |
+
// illegal move
|
| 69 |
+
if (move === null) return 'snapback'
|
| 70 |
+
|
| 71 |
+
if (window.parent) {
|
| 72 |
+
console.log("in iframe")
|
| 73 |
+
window.parent.stBridges.send("my-bridge", {'move': move, 'fen': game.fen(), 'pgn': game.pgn()});
|
| 74 |
+
}
|
| 75 |
+
else {
|
| 76 |
+
console.log("not in iframe")
|
| 77 |
+
window.stBridges.send("my-bridge", {'move': move, 'fen': game.fen(), 'pgn': game.pgn()});
|
| 78 |
+
}
|
| 79 |
+
updateStatus()
|
| 80 |
+
}
|
| 81 |
+
"""
|
| 82 |
+
|
| 83 |
+
script4 = """
|
| 84 |
+
// update the board position after the piece snap
|
| 85 |
+
// for castling, en passant, pawn promotion
|
| 86 |
+
function onSnapEnd () {
|
| 87 |
+
board.position(game.fen())
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
function updateStatus () {
|
| 91 |
+
var status = ''
|
| 92 |
+
|
| 93 |
+
var moveColor = 'White'
|
| 94 |
+
if (game.turn() === 'b') {
|
| 95 |
+
moveColor = 'Black'
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
if (game.in_checkmate()) {
|
| 99 |
+
status = 'Game over, ' + moveColor + ' is in checkmate.'
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
// draw?
|
| 103 |
+
else if (game.in_draw()) {
|
| 104 |
+
status = 'Game over, drawn position'
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
// game still on
|
| 108 |
+
else {
|
| 109 |
+
status = moveColor + ' to move'
|
| 110 |
+
|
| 111 |
+
// check?
|
| 112 |
+
if (game.in_check()) {
|
| 113 |
+
status += ', ' + moveColor + ' is in check'
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
$status.html(status)
|
| 117 |
+
}
|
| 118 |
+
"""
|
| 119 |
+
|
| 120 |
+
config_ = f"""
|
| 121 |
+
pieceTheme: 'https://chessboardjs.com/img/chesspieces/wikipedia/{{piece}}.png',
|
| 122 |
+
position: '{self.fen}',
|
| 123 |
+
orientation: '{sidetomove}',
|
| 124 |
+
draggable: true,
|
| 125 |
+
onDragStart: onDragStart,
|
| 126 |
+
onDrop: onDrop,
|
| 127 |
+
onSnapEnd: onSnapEnd
|
| 128 |
+
"""
|
| 129 |
+
|
| 130 |
+
script5 = f"""
|
| 131 |
+
var config = {{{config_}}}
|
| 132 |
+
board = Chessboard('myBoard', config)
|
| 133 |
+
|
| 134 |
+
updateStatus()
|
| 135 |
+
"""
|
| 136 |
+
|
| 137 |
+
ret = []
|
| 138 |
+
|
| 139 |
+
ret.append(self.__header__())
|
| 140 |
+
ret.append(self.__board_placeholder__())
|
| 141 |
+
ret.append('<script>')
|
| 142 |
+
ret.append(script1)
|
| 143 |
+
ret.append(script2)
|
| 144 |
+
ret.append(script3)
|
| 145 |
+
ret.append(script4)
|
| 146 |
+
ret.append(script5)
|
| 147 |
+
ret.append('</script>')
|
| 148 |
+
|
| 149 |
+
return '\n'.join(ret)
|
modules/states.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Manages session states variables.
|
| 2 |
+
"""
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
import streamlit as st
|
| 6 |
+
from st_bridge import bridge
|
| 7 |
+
import datetime as dt
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def init_states():
|
| 11 |
+
if 'next' not in st.session_state:
|
| 12 |
+
st.session_state.next = 0
|
| 13 |
+
|
| 14 |
+
if ('curfen' not in st.session_state) or ('moves' not in st.session_state) :
|
| 15 |
+
st.session_state.curside = 'white'
|
| 16 |
+
st.session_state.curfen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
| 17 |
+
st.session_state.moves = {
|
| 18 |
+
st.session_state.curfen : {
|
| 19 |
+
'side':'GAME START',
|
| 20 |
+
'curfen':st.session_state.curfen,
|
| 21 |
+
'last_fen':'',
|
| 22 |
+
'last_move':'',
|
| 23 |
+
'data':None,
|
| 24 |
+
'timestamp':str(dt.datetime.now())
|
| 25 |
+
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
# Get the info from current board after the user made the move.
|
| 30 |
+
# The data will return the move, fen and the pgn.
|
| 31 |
+
# The move contains the from sq, to square, and others.
|
modules/utility.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Supports other functionalities.
|
| 2 |
+
"""
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
import streamlit as st
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
# Add a block of HTML code to the app
|
| 10 |
+
def apply_css():
|
| 11 |
+
"""
|
| 12 |
+
Apply CSS styling to the app.
|
| 13 |
+
"""
|
| 14 |
+
st.markdown('<link rel="stylesheet" href="streamlit\style.css">', unsafe_allow_html=True)
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def set_page(title='Chess', page_icon="♟️"):
|
| 18 |
+
st.set_page_config(
|
| 19 |
+
page_title=title,
|
| 20 |
+
page_icon=page_icon,
|
| 21 |
+
layout="wide",
|
| 22 |
+
initial_sidebar_state="expanded",
|
| 23 |
+
menu_items={
|
| 24 |
+
'Get Help':
|
| 25 |
+
'https://github.com/dakotalock/QuantumBlue',
|
| 26 |
+
'Report a bug':
|
| 27 |
+
"https://github.com/dakotalock/QuantumBlue",
|
| 28 |
+
'About': "# Streamlit chessboard"
|
| 29 |
+
}
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
apply_css()
|
| 33 |
+
|
| 34 |
+
st.title('Streamlit Chessboard')
|
style.css
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
body {
|
| 2 |
+
font-family: sans-serif;
|
| 3 |
+
font-size: 16px;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
h1 {
|
| 7 |
+
font-size: 24px;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
p {
|
| 11 |
+
margin-bottom: 10px;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
a {
|
| 15 |
+
color: #000000;
|
| 16 |
+
text-decoration: none;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
a:hover {
|
| 20 |
+
color: #0000ff;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
.light-theme {
|
| 24 |
+
background-color: #ffffff;
|
| 25 |
+
color: #000000;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
.dark-theme {
|
| 29 |
+
background-color: #000000;
|
| 30 |
+
color: #ffffff;
|
| 31 |
+
}
|