-
LinkedIn - Mini Sudoku Solver (userScript)
Bu script LinkedIn'de bulunan Mini Sudoku oyununa "Bulmacayı çöz" adında bir buton ekler.
Kullanım
Bu bir userScript betiğidir, çalıştırabilmek için kullandığınız tarayıcıda Tampermonkey, Violentmonkey vb. gibi bir komut dosyası yöneticisi yüklü olmalıdır.

Bilgilendirme
userScript bir tarayıcı komut dosyası olarak çalışır, yani sadece yüklediğiniz tarayıcı ile bu betiği kullanabilirsiniz. userScript hakkında detaylı bilgi edinmek için buraya tıklayabilirsiniz.
Yükleme adımlarını görmek için tıklayın
- Kullandığınız tarayıcıya Tampermonkey, Violentmonkey vb. gibi bir komut dosyası yöneticisi yükleyin.
- Yükledikten sonra uzantı seçeneklerinden "Kullanıcı Betiklerine İzin Ver" seçeneğini etkinleştirin.
- Chromium tabanlı bir tarayıcı kullanıyorsanız "Uzantılar" sayfasından geliştirici modunu etkinleştirin.
- Tarayıcınızı yeniden başlatın.
- Aşağıdaki snippetin sağ üst köşesinde bulunan "Aç" butonuna tıklayın.
- Karşınıza yükleme ekranı çıkacaktır, Yükle butonuna tıklayarak yükleme işlemini tamamlayabilirsiniz. Olası bir güncelleme yayınlanması durumunda bu ekran otomatik olarak tekrar karşınıza çıkacaktır.
// ==UserScript==
// @name LinkedIn Mini Sudoku Auto Solver
// @version 1.0
// @description LinkedIn Mini Sudoku için otomatik çözücü butonu ekler.
// @author Burak Şipşak
// @match https://www.linkedin.com/*
// @icon data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzM0MTU4XzI3NzEzNikiPgo8cmVjdCB4PSIxLjUiIHk9IjEuNSIgd2lkdGg9IjQ1IiBoZWlnaHQ9IjQ1IiByeD0iNCIgZmlsbD0iIzM0N0Y0MSIvPgo8ZyBjbGlwLXBhdGg9InVybCgjY2xpcDFfMzQxNThfMjc3MTM2KSI+CjxyZWN0IHdpZHRoPSIyMi4xMjUiIGhlaWdodD0iMTQuNSIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIC0xIDIzLjYyNSAxNikiIGZpbGw9IiM4Q0VEQ0MiLz4KPHBhdGggZD0iTTEyLjE0NzkgMTFWNi45Mjc3M0gxMi4wNzg0TDEwLjgwNCA3Ljc4ODMzVjYuNjMxMUwxMi4xNDc5IDUuNzE1NThIMTMuNDkxOVYxMUgxMi4xNDc5WiIgZmlsbD0iIzM0N0Y0MSIvPgo8L2c+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMl8zNDE1OF8yNzcxMzYpIj4KPHJlY3Qgd2lkdGg9IjIyLjEyNSIgaGVpZ2h0PSIxNC41IiB0cmFuc2Zvcm09Im1hdHJpeCgtMSAwIDAgLTEgNDYuNSAzMS4yNSkiIGZpbGw9IiM4Q0VEQ0MiLz4KPHBhdGggZD0iTTMzLjE4NDYgMjIuNjI4MkMzMy4xODQ2IDIxLjU1NTIgMzQuMDMwNSAyMC44MjI4IDM1LjI2NDYgMjAuODIyOEMzNi40ODc4IDIwLjgyMjggMzcuMjE2NiAyMS40ODU2IDM3LjIxNjYgMjIuMzkwMUMzNy4yMTY2IDIzLjAxNjQgMzYuOTM4MiAyMy40MzAyIDM2LjA5NTkgMjQuMTkxOUwzNS4wNTU5IDI1LjEzMzFWMjUuMjAyNkgzNy4yNzg4VjI2LjI1SDMzLjI2MTVWMjUuMzUyOEwzNS4xNTExIDIzLjY0MjZDMzUuODAzIDIzLjA0NTcgMzUuOTEyOCAyMi44MTg2IDM1LjkxMjggMjIuNTA3M0MzNS45MTI4IDIyLjE0MTEgMzUuNjU2NSAyMS44MzcyIDM1LjE5NTEgMjEuODM3MkMzNC43MDQzIDIxLjgzNzIgMzQuNDE1IDIyLjE3MDQgMzQuNDE1IDIyLjYyODJIMzMuMTg0NloiIGZpbGw9IiMzNDdGNDEiLz4KPC9nPgo8ZyBjbGlwLXBhdGg9InVybCgjY2xpcDNfMzQxNThfMjc3MTM2KSI+CjxyZWN0IHdpZHRoPSIyMi4xMjUiIGhlaWdodD0iMTQuNSIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIC0xIDIzLjYyNSA0Ni41KSIgZmlsbD0iIzhDRURDQyIvPgo8cGF0aCBkPSJNMTEuNjQ2MiAzOS4yNDc4VjM4LjMzOTZIMTIuMzIzN0MxMi43NzA1IDM4LjMzOTYgMTMuMDU5OCAzOC4wNzk2IDEzLjA1OTggMzcuNjk4N0MxMy4wNTk4IDM3LjMzOTggMTIuNzg1MiAzNy4wNzYyIDEyLjMzMTEgMzcuMDc2MkMxMS44NTUgMzcuMDc2MiAxMS41NjU3IDM3LjMyODkgMTEuNTQzNyAzNy43NTczSDEwLjMyMDZDMTAuMzM4OSAzNi43NDI5IDExLjE0MDkgMzYuMDcyOCAxMi4zOTcgMzYuMDcyOEMxMy42MzQ4IDM2LjA3MjggMTQuMzEyMyAzNi43MjA5IDE0LjMwODYgMzcuNTA4M0MxNC4zMDg2IDM4LjE0NTUgMTMuODk4NCAzOC41NjY3IDEzLjMxOTggMzguNzAyMVYzOC43NzE3QzE0LjA4MTUgMzguODc3OSAxNC41MjEgMzkuMzUwMyAxNC41MjEgNDAuMDQ2MUMxNC41MjEgNDAuOTkxIDEzLjYyMDEgNDEuNjQyOCAxMi4zNDk0IDQxLjY0MjhDMTEuMDkzMyA0MS42NDI4IDEwLjI0IDQwLjk2NTMgMTAuMTkyNCAzOS45MjUzSDExLjQ3NDFDMTEuNDkyNCA0MC4zMzE4IDExLjgyMiA0MC41ODQ1IDEyLjMzMTEgNDAuNTg0NUMxMi44MjE4IDQwLjU4NDUgMTMuMTU1IDQwLjMxNzEgMTMuMTU1IDM5LjkxOEMxMy4xNTUgMzkuNTAwNSAxMi44NDAxIDM5LjI0NzggMTIuMzIzNyAzOS4yNDc4SDExLjY0NjJaIiBmaWxsPSIjMzQ3RjQxIi8+CjwvZz4KPHJlY3Qgd2lkdGg9IjIyLjEyNSIgaGVpZ2h0PSIxNC41IiB0cmFuc2Zvcm09Im1hdHJpeCgtMSAwIDAgLTEgNDYuNSAxNikiIGZpbGw9IiNFNUZERUMiLz4KPHJlY3Qgd2lkdGg9IjIyLjEyNSIgaGVpZ2h0PSIxNC41IiB0cmFuc2Zvcm09Im1hdHJpeCgtMSAwIDAgLTEgMjMuNjI1IDMxLjI1KSIgZmlsbD0iI0U1RkRFQyIvPgo8cmVjdCB3aWR0aD0iMjIuMTI1IiBoZWlnaHQ9IjE0LjUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgMCAtMSA0Ni41IDQ2LjUpIiBmaWxsPSIjRTVGREVDIi8+CjwvZz4KPHJlY3QgeD0iMC43NSIgeT0iMC43NSIgd2lkdGg9IjQ2LjUiIGhlaWdodD0iNDYuNSIgcng9IjQuNzUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS1vcGFjaXR5PSIwLjkiIHN0cm9rZS13aWR0aD0iMS41Ii8+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzM0MTU4XzI3NzEzNiI+CjxyZWN0IHg9IjEuNSIgeT0iMS41IiB3aWR0aD0iNDUiIGhlaWdodD0iNDUiIHJ4PSI0IiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8Y2xpcFBhdGggaWQ9ImNsaXAxXzM0MTU4XzI3NzEzNiI+CjxyZWN0IHdpZHRoPSIyMi4xMjUiIGhlaWdodD0iMTQuNSIgZmlsbD0id2hpdGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgMCAtMSAyMy42MjUgMTYpIi8+CjwvY2xpcFBhdGg+CjxjbGlwUGF0aCBpZD0iY2xpcDJfMzQxNThfMjc3MTM2Ij4KPHJlY3Qgd2lkdGg9IjIyLjEyNSIgaGVpZ2h0PSIxNC41IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIC0xIDQ2LjUgMzEuMjUpIi8+CjwvY2xpcFBhdGg+CjxjbGlwUGF0aCBpZD0iY2xpcDNfMzQxNThfMjc3MTM2Ij4KPHJlY3Qgd2lkdGg9IjIyLjEyNSIgaGVpZ2h0PSIxNC41IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIC0xIDIzLjYyNSA0Ni41KSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo=
// @grant none
// ==/UserScript==
(function() {
'use strict';
let isSolving = false;
function injectButton() {
const isBoardDisabled = document.querySelector('.sudoku-board.grid-board--disabled');
const hasShareFooter = document.querySelector('.games-share-footer');
const existingBtn = document.getElementById('auto-solve-btn');
if (isBoardDisabled || hasShareFooter) {
if (existingBtn) {
existingBtn.remove();
}
return;
}
if (existingBtn) return;
const container = document.querySelector('.sudoku-input-buttons-container');
if (container) {
const btn = document.createElement('button');
btn.id = 'auto-solve-btn';
btn.className = 'sudoku-input-button';
btn.style.cssText = 'width: 100%; height: 48px; margin-top: 12px;';
const span = document.createElement('span');
span.innerText = 'Bulmacayı çöz';
btn.appendChild(span);
btn.addEventListener('click', toggleSolving);
container.parentNode.insertBefore(btn, container.nextSibling);
}
}
function solveSudoku(board) {
const emptyCell = board.findIndex(val => val === 0);
if (emptyCell === -1) return true;
const r = Math.floor(emptyCell / 6);
const c = emptyCell % 6;
for (let num = 1; num <= 6; num++) {
if (isValid(board, r, c, num)) {
board[emptyCell] = num;
if (solveSudoku(board)) return true;
board[emptyCell] = 0;
}
}
return false;
}
function isValid(board, r, c, num) {
for (let i = 0; i < 6; i++) {
if (board[r * 6 + i] === num) return false;
if (board[i * 6 + c] === num) return false;
}
const blockR = Math.floor(r / 2) * 2;
const blockC = Math.floor(c / 3) * 3;
for (let i = 0; i < 2; i++) {
for (let j = 0; j < 3; j++) {
if (board[(blockR + i) * 6 + (blockC + j)] === num) return false;
}
}
return true;
}
function triggerClick(element) {
if (!element) return;
['mousedown', 'mouseup', 'click'].forEach(eventType => {
element.dispatchEvent(new MouseEvent(eventType, {
bubbles: true,
cancelable: true,
view: window
}));
});
}
async function toggleSolving() {
const btn = document.getElementById('auto-solve-btn');
if (!btn) return;
const span = btn.querySelector('span');
if (isSolving) {
isSolving = false;
if (span) span.innerText = 'Bulmacayı çöz';
return;
}
isSolving = true;
if (span) span.innerText = 'Durdur';
let baseBoard = new Array(36).fill(0);
let hasPrefilled = false;
for (let i = 0; i < 36; i++) {
const cellElem = document.querySelector(`.sudoku-cell[data-cell-idx="${i}"]`);
if (cellElem && cellElem.classList.contains('sudoku-cell-prefilled')) {
const contentElem = cellElem.querySelector('.sudoku-cell-content');
if (contentElem) {
const val = parseInt(contentElem.innerText.trim(), 10);
if (!isNaN(val) && val >= 1 && val <= 6) {
baseBoard[i] = val;
hasPrefilled = true;
}
}
}
}
if (!hasPrefilled) {
for (let i = 0; i < 36; i++) {
const cellElem = document.querySelector(`.sudoku-cell[data-cell-idx="${i}"]`);
if (cellElem) {
const contentElem = cellElem.querySelector('.sudoku-cell-content');
if (contentElem) {
const val = parseInt(contentElem.innerText.trim(), 10);
if (!isNaN(val) && val >= 1 && val <= 6) {
baseBoard[i] = val;
}
}
}
}
}
const solvedBoard = [...baseBoard];
if (!solveSudoku(solvedBoard)) {
alert("Bu bulmaca için geçerli bir çözüm bulunamadı!");
isSolving = false;
if (span) span.innerText = 'Bulmacayı çöz';
return;
}
for (let i = 0; i < 36; i++) {
if (!isSolving) break;
const targetVal = solvedBoard[i];
const cellElem = document.querySelector(`.sudoku-cell[data-cell-idx="${i}"]`);
if (cellElem) {
const contentElem = cellElem.querySelector('.sudoku-cell-content');
const currentVal = contentElem ? parseInt(contentElem.innerText.trim(), 10) : 0;
if (currentVal !== targetVal) {
triggerClick(cellElem);
await new Promise(r => setTimeout(r, 50));
if (!isSolving) break;
const numBtn = document.querySelector(`button.sudoku-input-button[data-number="${targetVal}"]`);
if (numBtn && !numBtn.disabled) {
triggerClick(numBtn);
await new Promise(r => setTimeout(r, 100));
}
}
}
}
isSolving = false;
if (span) {
span.innerText = 'Bulmacayı çöz';
}
}
const observer = new MutationObserver(() => {
injectButton();
});
observer.observe(document.body, { childList: true, subtree: true });
})();