Simple chessboard design + slove button (shows you the solution with the algorithm) and marks conflicts with damen red.
conflict still has some errors (damen despawn somethimes) and css is very simple.
This commit is contained in:
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
from flask import Blueprint, render_template
|
||||
from flask import Blueprint, jsonify, render_template, request
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
main_bp = Blueprint("main", __name__)
|
||||
@@ -11,3 +11,54 @@ def home():
|
||||
@login_required
|
||||
def dashboard():
|
||||
return render_template('dashboard.html', user=current_user)
|
||||
|
||||
@main_bp.route("/check", methods=["POST"])
|
||||
def check():
|
||||
data = request.json
|
||||
board = data["board"]
|
||||
row = data["row"]
|
||||
col = data["col"]
|
||||
|
||||
for r in range(len(board)):
|
||||
c = board[r]
|
||||
|
||||
if c == -1 or r == row:
|
||||
continue
|
||||
|
||||
# gleiche Spalte
|
||||
if c == col:
|
||||
return jsonify({"valid": False})
|
||||
|
||||
# gleiche Diagonale
|
||||
if abs(c - col) == abs(r - row):
|
||||
return jsonify({"valid": False})
|
||||
|
||||
return jsonify({"valid": True})
|
||||
|
||||
|
||||
@main_bp.route("/solve")
|
||||
def solve():
|
||||
n = 8
|
||||
solutions = []
|
||||
board = [-1] * n
|
||||
|
||||
def is_safe(row, col):
|
||||
for r in range(row):
|
||||
c = board[r]
|
||||
if c == col or abs(c - col) == abs(r - row):
|
||||
return False
|
||||
return True
|
||||
|
||||
def backtrack(row):
|
||||
if row == n:
|
||||
solutions.append(board[:])
|
||||
return
|
||||
|
||||
for col in range(n):
|
||||
if is_safe(row, col):
|
||||
board[row] = col
|
||||
backtrack(row + 1)
|
||||
board[row] = -1
|
||||
|
||||
backtrack(0)
|
||||
return jsonify(solutions)
|
||||
@@ -0,0 +1,116 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
/* 🔝 Navbar */
|
||||
.navbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #1e293b;
|
||||
color: white;
|
||||
padding: 15px 30px;
|
||||
}
|
||||
|
||||
.navbar a {
|
||||
color: white;
|
||||
margin-left: 15px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.navbar a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 📦 Layout */
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 30px auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* 📇 Cards */
|
||||
.card {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
margin-bottom: 25px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.game-card {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ♟️ Board */
|
||||
.board {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(8, 60px);
|
||||
margin: 20px auto;
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
.cell {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.cell:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.white {
|
||||
background: #e2e8f0;
|
||||
}
|
||||
|
||||
.black {
|
||||
background: #475569;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.invalid {
|
||||
background: #ef4444 !important;
|
||||
}
|
||||
|
||||
/* 🎛️ Buttons */
|
||||
.controls {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 10px 15px;
|
||||
margin: 5px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: #3b82f6;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #2563eb;
|
||||
}
|
||||
|
||||
.btn.secondary {
|
||||
background: #64748b;
|
||||
}
|
||||
|
||||
.btn.secondary:hover {
|
||||
background: #475569;
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
background: #ef4444;
|
||||
}
|
||||
|
||||
.btn.danger:hover {
|
||||
background: #dc2626;
|
||||
}
|
||||
+121
-24
@@ -1,51 +1,148 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<html lang="de">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard</title>
|
||||
|
||||
<link rel="stylesheet" href="../static/css/dashboard.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<a href="{{ url_for('main.dashboard') }}">Dashboard</a>
|
||||
<a href="{{ url_for('login.logout') }}">Logout</a>
|
||||
<!-- 🔝 Navbar -->
|
||||
<nav class="navbar">
|
||||
<div class="nav-left">♛ 8-Queens App</div>
|
||||
<div class="nav-right">
|
||||
<a href="{{ url_for('main.dashboard') }}">Dashboard</a>
|
||||
<a href="{{ url_for('login.logout') }}">Logout</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 📦 Container -->
|
||||
<div class="container">
|
||||
|
||||
```
|
||||
<h1>Dashboard</h1>
|
||||
<!-- 👤 User Card -->
|
||||
<div class="card">
|
||||
<h2>👋 Willkommen, {{ current_user.username }}</h2>
|
||||
|
||||
<p>Welcome back <strong>{{ current_user.username }}</strong> 👋</p>
|
||||
<div class="user-info">
|
||||
<p><strong>ID:</strong> {{ current_user.id }}</p>
|
||||
<p><strong>Username:</strong> {{ current_user.username }}</p>
|
||||
|
||||
<div class="user-info">
|
||||
<h3>Your Account</h3>
|
||||
{% if current_user.email %}
|
||||
<p><strong>Email:</strong> {{ current_user.email }}</p>
|
||||
{% else %}
|
||||
<p><strong>Email:</strong> Not set</p>
|
||||
{% endif %}
|
||||
|
||||
<p><strong>User ID:</strong> {{ current_user.id }}</p>
|
||||
<p><strong>Username:</strong> {{ current_user.username }}</p>
|
||||
<p><strong>Erstellt:</strong> {{ current_user.created_at }}</p>
|
||||
</div>
|
||||
|
||||
{% if current_user.email %}
|
||||
<p><strong>Email:</strong> {{ current_user.email }}</p>
|
||||
{% else %}
|
||||
<p><strong>Email:</strong> Not set</p>
|
||||
{% endif %}
|
||||
|
||||
<p><strong>Account created:</strong> {{ current_user.created_at }}</p>
|
||||
</div>
|
||||
|
||||
<div class="logout">
|
||||
<form action="{{ url_for('login.logout') }}" method="post">
|
||||
<button type="submit">Logout</button>
|
||||
<button class="btn danger" type="submit">Logout</button>
|
||||
</form>
|
||||
</div>
|
||||
```
|
||||
|
||||
<!-- ♟️ Game Card -->
|
||||
<div class="card game-card">
|
||||
<h2>♟️ 8-Damen Spiel</h2>
|
||||
|
||||
<div class="board" id="board"></div>
|
||||
|
||||
<div class="controls">
|
||||
<button class="btn" onclick="solve()">Solve</button>
|
||||
<button class="btn secondary" onclick="resetBoard()">Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let board = Array(8).fill(-1);
|
||||
const boardDiv = document.getElementById("board");
|
||||
|
||||
function getConflicts() {
|
||||
let conflicts = [];
|
||||
|
||||
for (let r1 = 0; r1 < 8; r1++) {
|
||||
if (board[r1] === -1) continue;
|
||||
|
||||
for (let r2 = r1 + 1; r2 < 8; r2++) {
|
||||
if (board[r2] === -1) continue;
|
||||
|
||||
let c1 = board[r1];
|
||||
let c2 = board[r2];
|
||||
|
||||
if (
|
||||
c1 === c2 ||
|
||||
Math.abs(c1 - c2) === Math.abs(r1 - r2)
|
||||
) {
|
||||
conflicts.push([r1, c1]);
|
||||
conflicts.push([r2, c2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return conflicts;
|
||||
}
|
||||
|
||||
function drawBoard() {
|
||||
boardDiv.innerHTML = "";
|
||||
const conflicts = getConflicts();
|
||||
|
||||
for (let row = 0; row < 8; row++) {
|
||||
for (let col = 0; col < 8; col++) {
|
||||
|
||||
const cell = document.createElement("div");
|
||||
cell.classList.add("cell");
|
||||
|
||||
if ((row + col) % 2 === 0) {
|
||||
cell.classList.add("white");
|
||||
} else {
|
||||
cell.classList.add("black");
|
||||
}
|
||||
|
||||
if (board[row] === col) {
|
||||
cell.textContent = "♛";
|
||||
|
||||
if (conflicts.some(([r, c]) => r === row && c === col)) {
|
||||
cell.classList.add("invalid");
|
||||
}
|
||||
}
|
||||
|
||||
cell.onclick = () => placeQueen(row, col);
|
||||
boardDiv.appendChild(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function placeQueen(row, col) {
|
||||
if (board[row] === col) {
|
||||
board[row] = -1;
|
||||
} else {
|
||||
board[row] = col;
|
||||
}
|
||||
drawBoard();
|
||||
}
|
||||
|
||||
async function solve() {
|
||||
const res = await fetch("/solve");
|
||||
const solutions = await res.json();
|
||||
|
||||
board = solutions[0];
|
||||
drawBoard();
|
||||
}
|
||||
|
||||
function resetBoard() {
|
||||
board = Array(8).fill(-1);
|
||||
drawBoard();
|
||||
}
|
||||
|
||||
drawBoard();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
<a href="/solver">Solver</a>
|
||||
<a href="/dashboard">Solver</a>
|
||||
|
||||
{% if session.get('user_id') %}
|
||||
<a href="/dashboard">Dashboard</a>
|
||||
|
||||
Reference in New Issue
Block a user