Last active
March 15, 2025 20:07
-
-
Save neopunisher/a0ea9c46ef58624b0002729d948dd896 to your computer and use it in GitHub Desktop.
https://www.word-battle.com/ unofficial api and helper tools; vibe coded with love
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const endpoint = "https://htbgzenw76.execute-api.us-east-1.amazonaws.com/dev/app"; | |
const callApi = async (funcName, data) => { | |
const response = await fetch(endpoint, { | |
body: JSON.stringify({ funcName, data }), | |
method: "POST", | |
headers: { "Content-Type": "application/json" } | |
}); | |
if (!response.ok) { | |
throw new Error(`API call failed: ${response.status} ${response.statusText}`); | |
} | |
return response.json(); | |
}; | |
const createApiFunction = (funcName, argNames) => { | |
return async (...args) => { | |
if (args.length !== argNames.length) { | |
throw new Error(`Expected ${argNames.length} arguments, got ${args.length}`); | |
} | |
const data = Object.fromEntries(argNames.map((name, i) => [name, args[i]])); | |
return await callApi(funcName, data); | |
}; | |
}; | |
const register = createApiFunction("REGISTER_USER", ["username", "word"]); | |
const battle = createApiFunction("BATTLE", ["uuid"]); | |
const topPlayers = createApiFunction("LIST_TOP_USERS",[]); | |
const stats = async () => { | |
try { | |
window.players = (await topPlayers()).userRecords; | |
} catch (error) { | |
console.error('Failed to load player stats:', error); | |
} | |
}; | |
// Global variables | |
window.battleId = '3f980ee9-f0b3-4437-9ccb-b4f786726b47'; | |
window.running = false; | |
// Battle loop function | |
const runBattles = async () => { | |
if (window.running) return; // Prevent multiple loops from starting | |
window.running = true; | |
while (window.running) { | |
window.carterData.incrementBattle(window.battleId); | |
let { eloChange, message } = await battle(window.battleId); | |
console.log(eloChange, message); | |
await new Promise(resolve => setTimeout(resolve, 1000)); // Optional delay | |
} | |
console.log("Battle loop stopped."); | |
}; | |
// Function to start the battle loop | |
window.startBattles = () => { | |
if (!window.running) { | |
console.log("Starting battle loop..."); | |
runBattles(); | |
} else { | |
console.log("Battle loop is already running."); | |
} | |
}; | |
window.carterData = {}; | |
window.carterData.battleCounts = window.carterData.battleCounts || {}; | |
// Create increment function | |
window.carterData.incrementBattle = (id) => { | |
carterData.battleCounts[id] = (carterData.battleCounts[id] || 0) + 1; | |
return carterData.battleCounts[id]; | |
}; | |
// Optional: Add getter methods | |
window.carterData.getBattleCount = (id) => carterData.battleCounts[id] || 0; | |
window.carterData.getAllBattleCounts = () => ({ ...carterData.battleCounts }); | |
// Function to stop the battle loop | |
window.stopBattles = () => { | |
console.log("Stopping battle loop..."); | |
window.running = false; | |
}; | |
// Function to set the battle ID dynamically | |
window.setBattleId = (newBattleId) => { | |
console.log(`Setting battle ID to ${newBattleId}`); | |
window.battleId = newBattleId; | |
}; | |
function randomElementsInRange(arr, minNum, maxNum) { | |
// Validate input | |
if (minNum < 0 || maxNum > arr.length || minNum > maxNum) { | |
throw new Error("Invalid min or max for the given array"); | |
} | |
// Pick a random number n between minNum and maxNum (inclusive) | |
const n = Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum; | |
// Make a copy so we don't modify the original array | |
const arrCopy = [...arr]; | |
// Fisher-Yates (Knuth) shuffle | |
for (let i = arrCopy.length - 1; i > 0; i--) { | |
const j = Math.floor(Math.random() * (i + 1)); | |
[arrCopy[i], arrCopy[j]] = [arrCopy[j], arrCopy[i]]; | |
} | |
// Return the first n elements from the shuffled array | |
return arrCopy.slice(0, n); | |
} | |
players = (await topPlayers())["userRecords"]; | |
carters = players.filter((c)=>c["username"]=="carter") | |
const randCarter = ()=>setBattleId(randomElementsInRange(carters, 1,1)[0]["uuid"]); | |
function getUsernameCounts() { | |
if (!window.players || !Array.isArray(window.players)) { | |
console.error('Players data not found or invalid format'); | |
return []; | |
} | |
// Count occurrences | |
const countMap = window.players.reduce((acc, player) => { | |
const username = player.username || 'anonymous'; | |
acc[username] = (acc[username] || 0) + 1; | |
return acc; | |
}, {}); | |
// Convert to sorted array | |
return Object.entries(countMap) | |
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])) | |
.map(([username, count]) => ({ username, count })); | |
} | |
// Add to window object for access | |
window.getUsernameCounts = getUsernameCounts; | |
function getCarterEloLeaderboard() { | |
if (!window.players || !Array.isArray(window.players)) { | |
console.error('Players data not found'); | |
return []; | |
} | |
return window.players | |
.filter(player => | |
player.username === "carter" && | |
player.word?.endsWith('" and this player wins.') && | |
typeof player.elo === 'number' | |
) | |
.map(player => ({ | |
emoji: player.word?.charAt(0) || '❌', | |
elo: player.elo, | |
uuid: player.uuid, | |
word: player.word | |
})) | |
.sort((a, b) => { | |
// Primary sort: ELO descending | |
if (b.elo !== a.elo) return b.elo - a.elo; | |
// Secondary sort: UUID ascending for ties | |
return a.uuid.localeCompare(b.uuid); | |
}); | |
} | |
// Add to window object | |
window.getCarterEloLeaderboard = getCarterEloLeaderboard; | |
randCarter(); | |
startBattles(); | |
t = setInterval(randCarter,20000); | |
// Add to your existing code | |
let updateInterval; | |
async function updateStats() { | |
await stats(); | |
} | |
function renderLeaderboard() { | |
const leaderboardData = window.getCarterEloLeaderboard(); | |
const container = document.getElementById('carter-leaderboard') || createLeaderboardContainer(); | |
// Clear existing content | |
container.innerHTML = ''; | |
// Create title | |
const title = document.createElement('h2'); | |
title.textContent = `Carter's Emoji Leaderboard (Updated: ${new Date().toLocaleTimeString()})`; | |
container.appendChild(title); | |
// Create list | |
const list = document.createElement('ul'); | |
list.style.listStyleType = 'none'; | |
list.style.padding = '0'; | |
leaderboardData.forEach(player => { | |
const li = document.createElement('li'); | |
li.style.margin = '10px 0'; | |
li.style.padding = '10px'; | |
li.style.backgroundColor = '#f5f5f5'; | |
li.style.borderRadius = '5px'; | |
li.innerHTML = ` | |
<span style="font-size: 1.5em">${player.emoji}</span> | |
<span style="margin-left: 10px; font-weight: bold">ELO: ${player.elo.toFixed(2)}</span> | |
<div style="color: #666; margin-top: 5px">${player.word}</div> | |
`; | |
list.appendChild(li); | |
}); | |
if (leaderboardData.length === 0) { | |
const empty = document.createElement('div'); | |
empty.textContent = 'No carter players found'; | |
list.appendChild(empty); | |
} | |
container.appendChild(list); | |
} | |
function createLeaderboardContainer() { | |
const existing = document.getElementById('carter-leaderboard'); | |
if (existing) return existing; | |
const container = document.createElement('div'); | |
container.id = 'carter-leaderboard'; | |
container.style.position = 'fixed'; | |
container.style.top = '20px'; | |
container.style.right = '20px'; | |
container.style.background = 'white'; | |
container.style.padding = '20px'; | |
container.style.borderRadius = '10px'; | |
container.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)'; | |
container.style.maxWidth = '400px'; | |
container.style.zIndex = '1000'; | |
document.body.appendChild(container); | |
return container; | |
} | |
async function renderAutoUpdatingLeaderboard() { | |
// Initial setup | |
await updateStats(); | |
renderLeaderboard(); | |
// Set up periodic updates | |
updateInterval = setInterval(async () => { | |
await updateStats(); | |
renderLeaderboard(); | |
}, 10000); | |
} | |
// Add controls to window | |
window.startLeaderboard = renderAutoUpdatingLeaderboard; | |
window.stopLeaderboard = () => { | |
clearInterval(updateInterval); | |
console.log("Leaderboard updates stopped"); | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment