7 ms·
One of my favorite things to do with these neat little games is to build something that plays them for me by just pasting stuff into the browser JS console. ht
by nathas 5y ago
One of my favorite things to do with these neat little games is to build something that plays them for me by just pasting stuff into the browser JS console.
https://pastebin.com/aTYuaNVS https://pastebin.com/aTYuaNVS
At a score of 1,619 the ball is moving so fast it no longer works! I switched to a new tab (hoping that the event loop would be sent to the background/context switch/whatever) and ta-da - it misclicked. High score of 1,637.
- fisherjeff 5y agoLate to the party, but I prefer the more manual version: loopTapApp.setArc=function(){this.arc=[0,359];}
- eatbitseveryday 5y agoPasting here in case the pastebin disappears: function autoPlay() { const fakeClick = { preventDefault: function() {}, stopPropagation: function() {} } const ballAngle = loopTapApp.getBallAngle(); if (ballAngle + 6 > loopTapApp.arc[0] && ballAngle - 6 < loopTapApp.arc[1]) { loopTapApp.tap(fakeClick) } } const autoPlayer = setInterval(autoPlay, 10)
- shelbyKiraM 5y agoI got 1,683 in Firefox on a new M1 Pro MacBook Pro with your code… I'm gonna try the next guy's in Safari now. How optimal can I get haha!
- vthallam 5y agothat works. If there was a leaderboard, this thing will win for sure :)
- only4here 5y agothis is the reason that most FOSS games (especially browser games in JS) don't really do well with a leaderboard. Still a neat trick to mess around with!
- alfon 5y agoYou beat me to it, haha, This is what I just did: function intersectRect(rectA, rectB) { return !( rectB.left >= rectA.right || rectB.right <= rectA.left || rectB.top >= rectA.bottom || rectB.bottom <= rectA.top ); } const arc = document.getElementById("arc"); const ball = document.getElementById("ball"); setInterval(() => { if (intersectRect(arc.getBoundingClientRect(), ball.getBoundingClientRect())) { window.dispatchEvent(new KeyboardEvent('keypress', { keyCode: 32, })); } }, 10); My code seems to go on forever, closed the tab after it reached 60K
- mhio 5y agoThis overwrites the games internal `arc` variable so the arc no longer updates, hence the forever-ness.
- nathas 5y agoOh neat! You did the Harder version and didn't use the game's own code to check it. I find that with JS games it's better to imitate the game's exact logic and call it's functions to make sure the state is working/updates correctly. Of course, for how delightfully simple this one is, your approach is definitely faster/better!
- capableweb 5y agoDefinitely seems like alfon's solution is faster/better, as it's more accurate when the game speeds up. However, it's also more resource intensive! getBoundingClientRect (used to at least, long time I go I did browser performance stuff) forces a new layout calculation each time it's called, which is one of the most expensive things you can do in the DOM, and can lead to jank in the website. Some more information here: https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing https://developers.google.com/web/fundamentals/performance/r... Just adding this information for the ones who don't know and like to know more about browser performance :)
- afiori 5y ago
- acidburnNSA 5y agoBrilliant, thanks. Are you usually able to do this when e.g. it's more of a SPA and you have to drill down more to get to the state of some deeply nested component?
- nathas 5y agoI haven't really tried. Most of the time I do this and use the actual game functions for autoclicker games like e.g. Cookie Clicker. It makes progression a lot simpler and I get to see the "fun" aspects of the game (like the super weird late game stuff) without actually breaking the fundamental game code. I like operating within the game's own code boundaries.
- 2Gkashmiri 5y agosad. i got stuck in a loop at 1477. it just kept going round and round.
- deleted 5y ago[deleted]
- Minor49er 5y agoThis effectively turns this game into a spinning animation that appears to get increasingly frustrated that whatever is being loaded hasn't completed yet
- riidom 5y agoCorrect.. what it is loading, is effectively your score though. Or rather, measuring it, which takes some time? No idea, this is nonsense:)
- paxys 5y agoMine gave up at 1683
- deleted 5y ago[deleted]
- CobrastanJorji 5y agoThis is neat. Also, in retrospect, I probably should have read the code before pasting it into my console.
- nathas 5y agoMost definitely :D
- zamadatix 5y agoCode run in the console has the same restrictions as code on the page it is for so it's not really any riskier than clicking the post link in this case. For sites you have (or will have) a presence on (bank, HN, email, etc) it's a very risky idea though.
- Wingy 5y agoIt's not exactly playing the game, but this was my approach: setInterval(() => { loopTapApp.arc = [ -Infinity, Infinity ] loopTapApp.tap({ preventDefault: () => {}, stopPropagation: () => {} }) })
- jagged-chisel 5y ago1,665 and the dot is just sitting in the center where the play button goes. Safari Version 15.2 (16612.3.6.1.8, 16612) macOS Big Sur 11.6.2 (20G314) iMac Pro 2017
- dheera 5y agoMine was this loopTapApp.startPlay(); setInterval(() => { if(loopTapApp.getBallAngle() > loopTapApp.arc[0] && loopTapApp.getBallAngle() < loopTapApp.arc[1]) { loopTapApp.tap({preventDefault: ()=>{}, stopPropagation: ()=>{}}); } }, 50);
- elwell 5y agoNo requestAnimationFrame?
- capableweb 5y agoBasically the same in this case, as the setInterval is set with 10ms between firings, and requestAnimationFrame would (most likely, depending on computer/display) fire every ~16ms. It would be more efficient though, that's for sure, but most likely basically the same :)
- air7 5y agoThank you! I didn't peek and ended up with the same solution as you, so for an extra bit of fun I tried to golf it to be as short as possible. There's probably room for much improvement: (94 chars) setInterval("l=loopTapApp;b=l.getBallAngle();a=l.arc;b+6>a[0]&b-6<a[1]&&l.tap(new Event(1))")
- axiosgunnar 5y agoThis entire comment thread is hilarious
- Datagenerator 5y agoStrangely enough this shorter version reads and clicks better into my tiny brain
- ElbertF 5y agoNice! Managed to shave off a couple of bytes: setInterval("l=loopTapApp;b=l.getBallAngle();[a,c]=l.arc;b+6>a&b-6<c&&l.tap(new Event(1))")
- hbn 5y agoHere's my solution: loopTapApp.score = Number.MAX_SAFE_INTEGER;
- ruined 5y agohigh score!
- zeepzeep 5y agoNot anymore loopTapApp.score = Infinity
- anthonyjdella 5y agoloopTapApp.score = Infinity^Infinity
- easrng 5y agoYou want loopTapApp.score = Infinity*Infinity, yours is 0 because ^ is XOR na anything XORed with itself is zero