Skip to content

Instantly share code, notes, and snippets.

@faogustavo
Last active August 17, 2019 20:03
Show Gist options
  • Save faogustavo/9285969f5a200e0f9007bad2f13547bb to your computer and use it in GitHub Desktop.
Save faogustavo/9285969f5a200e0f9007bad2f13547bb to your computer and use it in GitHub Desktop.
<html>
<script type="text/javascript">
const KEY_START = "CURRENT_STATE"
const KEY_AUTH = "AUTHENTICATE"
const KEY_PAINT = "PAINT"
const KEY_MY_ID = "e4bd5af89ee5f4ed"
const isMine = (data) => data.painterId == KEY_MY_ID
const log = (className = "", message, complement) => {
const date = new Date()
const hour = prettyfyNumber(date.getHours())
const minute = prettyfyNumber(date.getMinutes())
const seconds = prettyfyNumber(date.getSeconds())
const newChild = document.createElement("p")
newChild.className = className
newChild.innerHTML = `[${hour}:${minute}:${seconds}] ${message} ${complement}`
const container = document.getElementById("output")
container.insertBefore(newChild, container.firstChild)
}
const prettyfyNumber = (number) => {
if (+number < 10) {
return `0${number}`
} else {
return number
}
}
console.log = (message, complement) => {
log("", message, complement || "")
}
console.warn = (message, complement) => {
log('warn', message, complement || "")
}
console.error = (message, complement) => {
log('error', message, complement || "")
}
const seconds = (val) => (+val) * 1000
const getAction = (data) => {
try {
const finalData = data.split(/ /)
return {
action: finalData[0],
data: JSON.parse(finalData[1])
}
} catch (e) {
return null
}
}
const makeAction = (data) => [ data.action, JSON.stringify(data.data) ].join(" ")
const updateScore = (board) => {
const myItems = board.filter(isMine).length
const missingItems = board.length - myItems
document.getElementById("mine").innerHTML = `${myItems}`
document.getElementById("missing").innerHTML = `${missingItems}`
const count = board.reduce((acc, item) => {
return {
...acc,
[item.painterId]:(acc[item.painterId] || 0) + 1
}
}, {})
const sortedCount = Object.keys(count)
.map((key) => ([key, count[key]]))
.sort((a, b) => b[1] - a[1])
.map((item) => `<ul>${item.join(" - ")}</ul>`)
.slice(0, 5)
document.getElementById("ranking").innerHTML = sortedCount.join("")
}
const start = (appUrl) => {
console.log("trying to connect")
document.cookie = "SESSION=id%3D%2523s85f8219c5c909169; path=/"
let rows = 0
let columns = 0
let board = []
let auth = false
let lastPaintedPosition = [-1, -1]
let mineIsScheduled = false
const ws = new WebSocket(appUrl)
const send = (message) => {
console.log("Sending -> ", message)
ws.send(message)
}
ws.onclose = () => {
console.log("The connection was closed. ")
console.log("Reconnecting in 5 seconds..")
setTimeout(() => {
start(appUrl)
}, seconds(5))
}
ws.onopen = () => {
document.getElementById("btn").remove()
console.log('Service started')
const sendColor = ({ row, col, hexColor }) => {
const finalRow = row || parseInt(Math.random() * rows)
const finalCol = col || parseInt(Math.random() * columns)
const finalHexColor = hexColor || "#999999"
lastPaintedPosition = [ row, col ]
send(makeAction({
action: KEY_PAINT,
data: {
row: finalRow,
col: finalCol,
hexColor: finalHexColor
}
}))
}
const findSquareToPaint = () => {
const othersSquares = board.filter((item) => !item.isMine)
if (othersSquares.length == 0) {
console.log("No more squares to paint. Waiting new changes.")
return
}
sendColor(othersSquares[parseInt(Math.random() * othersSquares.length)])
}
const indexOfItem = (col, row) => board.findIndex((item) => item.col == col && item.row == row)
const markItem = (data) => {
const index = indexOfItem(data.col, data.row)
board[index] = {
...board[index],
hexColor: `#${data.color}`
}
updateScore(board)
}
const normalizeSquare = (item) => ({
row: item.row,
col: item.col,
painterId: item.painterId,
hexColor: `#${item.color}`
})
const scheduleNext = () => {
mineIsScheduled = true
setTimeout(() => {
mineIsScheduled = false
findSquareToPaint()
}, seconds(12))
}
const keepAliveBot = () => {
setTimeout(() => {
if (!mineIsScheduled) {
findSquareToPaint()
}
keepAliveBot()
}, 30000);
}
const onConnect = (data) => {
rows = data.rowsCount
columns = data.colsCount
board = data.cells.map(normalizeSquare)
updateScore(board)
send(makeAction({
action: KEY_AUTH,
data: {
name: ""
}
}))
}
const onAuth = (data) => {
if (data.success) {
findSquareToPaint()
} else {
console.log("You were not able to authenticate");
ws.close()
}
}
const onPaint = (data) => {
markItem(data)
if (isMine(data)) {
lastPaintedPosition = [-1, -1]
scheduleNext()
} else {
if (!mineIsScheduled) scheduleNext()
}
}
ws.onmessage = (data) => {
const action = getAction(data.data)
if (!action) return
if (action.action != KEY_START) {
console.log("Received Action", JSON.stringify(action))
}
switch(action.action) {
case KEY_START:
onConnect(action.data.data)
break
case KEY_AUTH:
onAuth(action.data)
break
case KEY_PAINT:
onPaint(action.data.data)
break
}
}
}
}
const appStart = () => start("wss://kotlin-kolors.herokuapp.com:443/interact/")
</script>
<style>
.error { color: red; }
.warn { color: darkgoldenrod; }
#header {
position: absolute;
top: 0;
font-size: 48px;
}
ul { font-size: 20px; }
#output {
margin-top: 400px;
}
</style>
<body>
<div id="header">
<p>My items <span id="mine">0</span> </p>
<p>Missing items <span id="missing">0</span> </p>
<ul id="ranking"></ul>
<button onclick="javascript:appStart()" id="btn">Run We socket</button>
</div>
<div id="output" />
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment