Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 81d689c1ba | |||
| ecfe5c09a8 | |||
| 10e36d9aee | |||
| cb05b091d8 | |||
| 34dfa118d9 |
BIN
Binary file not shown.
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
|
from flask_login import login_required, current_user
|
||||||
|
|
||||||
main_bp = Blueprint("main", __name__)
|
main_bp = Blueprint("main", __name__)
|
||||||
@@ -12,6 +12,53 @@ def home():
|
|||||||
def dashboard():
|
def dashboard():
|
||||||
return render_template('dashboard.html', user=current_user)
|
return render_template('dashboard.html', user=current_user)
|
||||||
|
|
||||||
@main_bp.route('/solver')
|
@main_bp.route("/check", methods=["POST"])
|
||||||
def solver():
|
def check():
|
||||||
return render_template('solver.html')
|
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,143 @@
|
|||||||
|
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-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 30px repeat(8, 60px);
|
||||||
|
grid-template-rows: 30px repeat(8, 60px);
|
||||||
|
margin: 20px auto;
|
||||||
|
width: max-content;
|
||||||
|
border: 6px solid #1e293b;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: bold;
|
||||||
|
background: #aec8eb;
|
||||||
|
color: #1e293b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#queenList {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#queenList li {
|
||||||
|
padding: 5px;
|
||||||
|
background: #f1f5f9;
|
||||||
|
margin: 4px 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
+57
-47
@@ -21,40 +21,11 @@ body {
|
|||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
font-family: "Geist Sans", system-ui, sans-serif;
|
font-family: "Geist Sans", system-ui, sans-serif;
|
||||||
|
|
||||||
|
background: linear-gradient(135deg, #c6dff4, #7c8384);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MAGNET EFFECT */
|
|
||||||
.magnetic {
|
|
||||||
padding: 10px 20px;
|
|
||||||
border: none;
|
|
||||||
background: #4facfe;
|
|
||||||
color: white;
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
|
|
||||||
transition: transform 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.magnetic:hover {
|
|
||||||
background: #2d8cf0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset */
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Page setup */
|
|
||||||
body {
|
|
||||||
min-height: 100vh;
|
|
||||||
background: var(--primary-bg-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Navbar */
|
|
||||||
nav {
|
nav {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: var(--nav-bg-color);
|
background: var(--nav-bg-color);
|
||||||
@@ -93,17 +64,38 @@ main h1 {
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
animation: fadeIn 0.8s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(15px);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Form box */
|
/* Form box */
|
||||||
form {
|
form {
|
||||||
background: var(--secondary-bg-color);
|
background: rgba(255, 255, 255, 0.15);
|
||||||
padding: 30px;
|
backdrop-filter: blur(12px);
|
||||||
border-radius: 8px;
|
padding: 35px;
|
||||||
width: 300px;
|
border-radius: 12px;
|
||||||
|
width: 320px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
|
|
||||||
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Labels */
|
/* Labels */
|
||||||
label {
|
label {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
@@ -112,30 +104,48 @@ label {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Inputs */
|
/* Inputs */
|
||||||
input {
|
form {
|
||||||
padding: 10px;
|
background: rgba(255, 255, 255, 0.15);
|
||||||
border: 1px solid #ccc;
|
backdrop-filter: blur(12px);
|
||||||
border-radius: 6px;
|
padding: 35px;
|
||||||
|
border-radius: 12px;
|
||||||
|
width: 320px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Button */
|
/* Button */
|
||||||
.button {
|
button {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
padding: 10px;
|
padding: 12px;
|
||||||
border: none;
|
border: none;
|
||||||
background: #4facfe;
|
background: linear-gradient(135deg, #e9eff5, #daebf0);
|
||||||
color: white;
|
color: rgb(0, 0, 0);
|
||||||
border-radius: 6px;
|
border-radius: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
||||||
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
background: #2d8cf0;
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
transform: scale(0.97);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Error message */
|
/* Error message */
|
||||||
.error {
|
.error {
|
||||||
color: red;
|
color: red;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* button anim */
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
:root {
|
|
||||||
--bg-color: #f4f6f8;
|
|
||||||
--text-color: #333;
|
|
||||||
--board-border: #2c3e50;
|
|
||||||
--square-light: #ecf0f1;
|
|
||||||
--square-dark: #95a5a6;
|
|
||||||
--accent-color: #3498db;
|
|
||||||
--btn-hover: #2980b9;
|
|
||||||
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
||||||
background-color: var(--bg-color);
|
|
||||||
color: var(--text-color);
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: 300;
|
|
||||||
letter-spacing: -0.5px;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
color: var(--board-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
background: white;
|
|
||||||
padding: 2rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: var(--shadow);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chessboard {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(8, 50px);
|
|
||||||
grid-template-rows: repeat(8, 50px);
|
|
||||||
border: 5px solid var(--board-border);
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.square {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.square.light {
|
|
||||||
background-color: var(--square-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.square.dark {
|
|
||||||
background-color: var(--square-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
.queen {
|
|
||||||
color: var(--board-border);
|
|
||||||
text-shadow: 0 2px 2px rgba(0,0,0,0.2);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: transform 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.queen:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls {
|
|
||||||
display: flex;
|
|
||||||
gap: 1rem;
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
background-color: var(--accent-color);
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
padding: 0.6rem 1.2rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 1rem;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover {
|
|
||||||
background-color: var(--btn-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
button.secondary {
|
|
||||||
background-color: transparent;
|
|
||||||
border: 1px solid var(--accent-color);
|
|
||||||
color: var(--accent-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
button.secondary:hover {
|
|
||||||
background-color: rgba(52, 152, 219, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.chessboard {
|
|
||||||
grid-template-columns: repeat(8, 1fr);
|
|
||||||
grid-template-rows: repeat(8, 1fr);
|
|
||||||
width: 100%;
|
|
||||||
max-width: 400px;
|
|
||||||
height: auto;
|
|
||||||
aspect-ratio: 1/1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.square {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+27
-9
@@ -1,14 +1,32 @@
|
|||||||
const button = document.querySelector(".magnetic")
|
const button = document.querySelector(".magnetic");
|
||||||
|
|
||||||
button.addEventListener("mousemove", (e) => {
|
button.addEventListener("mousemove", (e) => {
|
||||||
const rect = button.getBoundingClientRect()
|
const rect = button.getBoundingClientRect();
|
||||||
|
const x = e.clientX - rect.left - rect.width / 2;
|
||||||
|
const y = e.clientY - rect.top - rect.height / 2;
|
||||||
|
|
||||||
const x = e.clientX - rect.left - rect.width / 2
|
button.style.transform = `translate(${x * 0.2}px, ${y * 0.2}px)`;
|
||||||
const y = e.clientY - rect.top - rect.height / 2
|
});
|
||||||
|
|
||||||
button.style.transform = `translate(${x * 0.3}px, ${y * 0.3}px)`
|
|
||||||
})
|
|
||||||
|
|
||||||
button.addEventListener("mouseleave", () => {
|
button.addEventListener("mouseleave", () => {
|
||||||
button.style.transform = "translate(0,0)"
|
button.style.transform = "translate(0,0)";
|
||||||
})
|
});
|
||||||
|
|
||||||
|
const inputs = document.querySelectorAll("input");
|
||||||
|
|
||||||
|
inputs.forEach(input => {
|
||||||
|
input.addEventListener("input", () => {
|
||||||
|
input.style.boxShadow = "0 0 8px rgba(79,172,254,0.6)";
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
input.style.boxShadow = "";
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = document.querySelector("form");
|
||||||
|
|
||||||
|
form.addEventListener("submit", () => {
|
||||||
|
button.innerText = "Logging in...";
|
||||||
|
button.style.opacity = "0.7";
|
||||||
|
});
|
||||||
|
|||||||
+181
-24
@@ -1,51 +1,208 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Dashboard</title>
|
<title>Dashboard</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../static/css/dashboard.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<nav>
|
<!-- 🔝 Navbar -->
|
||||||
<a href="{{ url_for('main.dashboard') }}">Dashboard</a>
|
<nav class="navbar">
|
||||||
<a href="{{ url_for('login.logout') }}">Logout</a>
|
<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>
|
</nav>
|
||||||
|
|
||||||
|
<!-- 📦 Container -->
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
```
|
<!-- 👤 User Card -->
|
||||||
<h1>Dashboard</h1>
|
<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">
|
{% if current_user.email %}
|
||||||
<h3>Your Account</h3>
|
<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>Erstellt:</strong> {{ current_user.created_at }}</p>
|
||||||
<p><strong>Username:</strong> {{ current_user.username }}</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">
|
<form action="{{ url_for('login.logout') }}" method="post">
|
||||||
<button type="submit">Logout</button>
|
<button class="btn danger" type="submit">Logout</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</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>
|
</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 = "";
|
||||||
|
boardDiv.className = "board-grid";
|
||||||
|
|
||||||
|
const conflicts = getConflicts();
|
||||||
|
const letters = ["A", "B", "C", "D", "E", "F", "G", "H"];
|
||||||
|
|
||||||
|
for (let row = -1; row < 8; row++) {
|
||||||
|
for (let col = -1; col < 8; col++) {
|
||||||
|
|
||||||
|
const cell = document.createElement("div");
|
||||||
|
|
||||||
|
// 🔹 Ecke oben links
|
||||||
|
if (row === -1 && col === -1) {
|
||||||
|
cell.classList.add("label");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Buchstaben (oben)
|
||||||
|
else if (row === -1) {
|
||||||
|
cell.textContent = letters[col];
|
||||||
|
cell.classList.add("label");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Zahlen (links)
|
||||||
|
else if (col === -1) {
|
||||||
|
cell.textContent = 8 - row;
|
||||||
|
cell.classList.add("label");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 echtes Spielfeld
|
||||||
|
else {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateQueenList();
|
||||||
|
}
|
||||||
|
|
||||||
|
function placeQueen(row, col) {
|
||||||
|
if (board[row] === col) {
|
||||||
|
board[row] = -1;
|
||||||
|
} else {
|
||||||
|
board[row] = col;
|
||||||
|
}
|
||||||
|
drawBoard();
|
||||||
|
updateQueenList();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
updateQueenList();
|
||||||
|
}
|
||||||
|
|
||||||
|
drawBoard();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>📋 Damen Positionen</h3>
|
||||||
|
<ul id="queenList"></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function updateQueenList() {
|
||||||
|
const list = document.getElementById("queenList");
|
||||||
|
list.innerHTML = "";
|
||||||
|
|
||||||
|
const letters = ["A", "B", "C", "D", "E", "F", "G", "H"];
|
||||||
|
|
||||||
|
let count = 1;
|
||||||
|
|
||||||
|
for (let row = 0; row < 8; row++) {
|
||||||
|
if (board[row] !== -1) {
|
||||||
|
let col = board[row];
|
||||||
|
|
||||||
|
let pos = letters[col] + (8 - row);
|
||||||
|
|
||||||
|
const li = document.createElement("li");
|
||||||
|
li.textContent = `Dame ${count}: ${pos}`;
|
||||||
|
|
||||||
|
list.appendChild(li);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<a href="/">Home</a>
|
<a href="/">Home</a>
|
||||||
<a href="/solver">Solver</a>
|
<a href="/dashboard">Solver</a>
|
||||||
|
|
||||||
{% if session.get('user_id') %}
|
{% if session.get('user_id') %}
|
||||||
<a href="/dashboard">Dashboard</a>
|
<a href="/dashboard">Dashboard</a>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ url_for('login.login') }}"><span>Login</span></a></li>
|
<li><a href="{{ url_for('login.login') }}"><span>Login</span></a></li>
|
||||||
<li><a href="{{ url_for('login.register') }}"><span></span>Create account</span></a></li>
|
<li><a href="{{ url_for('login.register') }}"><span>Create account</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>8-Damen-Problem</title>
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/solver.css') }}">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>8-Damen-Problem Test</h1>
|
|
||||||
<div class="chessboard">
|
|
||||||
{% for row in range(8) %}
|
|
||||||
{% for col in range(8) %}
|
|
||||||
<div class="square {{ 'light' if (row + col) % 2 == 0 else 'dark' }}" data-row="{{ row }}" data-col="{{ col }}">
|
|
||||||
<!-- Queens will be placed here -->
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<button id="solveBtn">Solve</button>
|
|
||||||
<button id="resetBtn" class="secondary">Reset</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in New Issue
Block a user