Skip to content

Commit

Permalink
fix: update stackrabbit to fix rateMove issue
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheeg committed Oct 13, 2024
1 parent 65bf3c5 commit 932e227
Show file tree
Hide file tree
Showing 4 changed files with 301 additions and 11 deletions.
228 changes: 227 additions & 1 deletion public/views/1p/jdish.html
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,29 @@
height: 1080px;
object-fit: cover;
}

.srabbit_rating {
font-family: 'Press Start K', monospace;
font-size: 16px;
position: absolute;
width: 80%;
top: 20%;
left: 50%;
transform-origin: center;
text-align: center;
font-size: 24px;
line-height: 28px;
color: white;
text-shadow: -3px -3px 0 black, 3px -3px 0 black, -3px 3px 0 black,
3px 3px 0 black, 0px -3px 0 black, 0px 3px 0 black, -3px 0px 0 black,
3px 0px 0 black;
transform: translate(-50%, -50%) scale(0); /* Initial scale 0 */
will-change: transform; /* Optimize for animation */
}

.srabbit_rating p {
padding-bottom: 0.5em;
}
</style>
</head>
<body>
Expand Down Expand Up @@ -275,7 +298,7 @@
import QueryString from '/js/QueryString.js';
import '/views/bg.js';
import Connection from '/js/connection.js';
import { readableScoreFomatter } from '/views/utils.js';
import { readableScoreFomatter, shuffle } from '/views/utils.js';
import Player from '/views/Player.js';
import { peerServerOptions } from '/views/constants.js';

Expand Down Expand Up @@ -319,6 +342,142 @@
}
}

// Penner easing
// http://robertpenner.com/easing/
function easeOutElastic(t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t == 0) return b;
if ((t /= d) >= 1) return b + c;
if (!p) p = d * 0.3;
if (a < Math.abs(c)) {
a = c;
var s = p / 4;
} else var s = (p / (2 * Math.PI)) * Math.asin(c / a);
return (
a *
Math.pow(2, -10 * t) *
Math.sin(((t * d - s) * (2 * Math.PI)) / p) +
c +
b
);
}

function getRandomAngle(min, max) {
const randValue = min + Math.random() * (max - min);
const sign = Math.random() < 0.5 ? 1 : -1;
return randValue * sign;
}

// From Greg
// <1 point away or equal: best move
// 1-3 points less than top move: excellent
// 3-6 points away: inaccuracy
// 6-15 points away: mistake
// >15 points away: blunder
const srabbit_ratings = {
best: {
score: 4,
feedbacks: [
'Fantastic!',
'Crushed it!',
'Perfection!',
'So good!',
'Great!',
'Wonderful!',
'Nailed it!',
'Top of the game!',
"Couldn't be better!",
'Masterpiece!',
'10/10, would recommend!',
"You're unstoppable!",
'Absolutely brilliant!',
'Flawless victory!',
],
},
great: {
score: 3,
feedbacks: [
'Damn right!',
'Booya!',
'Ooooh yeah!',
"That's what I'm talking about!",
"You're on fire!",
'Legendary move!',
'This deserves a trophy!',
'Rockstar status!',
'Keep that up!',
'Winner, winner, chicken dinner!',
"I'm impressed!",
'Spectacular!',
'Gold star performance!',
'Knocked it out of the park!',
'Epic win!',
],
},
notbad: {
score: 2,
feedbacks: [
'Well done!',
'Keep going!',
'Near perfect!',
'Pretty good!',
'Good!',
'Solid effort!',
'Almost there!',
'Nice try!',
"You're getting there!",
'Not too shabby!',
'Decent work!',
'You can be proud of that!',
'That works!',
'Smooth sailing!',
'Keep up the good work!',
],
},
oops: {
score: 1,
feedbacks: [
'Huho',
'Errr',
'You sure?',
"Fractal wouldn't have done that",
'Interesting?',
'Dog is laughing!',
'That was... something',
"Let's pretend that didn't happen",
'Oopsie daisy!',
'Close, but no cigar!',
'Did you trip?',
'Yikes, try again!',
'E for effort, I guess?',
'Swing and a miss!',
"It's... a choice!",
],
},
wtf: {
score: 0,
feedbacks: [
'Dude WTF!',
'Serously?',
'Are you even trying?',
'Are you joking right now?',
'AlexT throws a brick your way!',
'Facepalm!',
'This is a new low',
"I'm not mad, just disappointed",
'Wow… just wow',
'We need to talk',
'You did WHAT?!',
'Congratulations, you broke reality',
'Error: brain.exe not found',
'Zero points for style',
'Hahaha!',
],
},
};

const player = new Player(
{
pb: document.querySelector(`.pbs .pb .content`),
Expand Down Expand Up @@ -389,11 +548,76 @@
};

player.onGameStart = () => {
streak = 0;
player.dom.runway_tr_header.textContent = 'TRANSITION RUNWAY';
player.dom.pb_wrapper.style.color = '';
player.dom.top_wrapper.style.color = '';
};

let gradeText;
let streak = 0;
let animId = null;
let disappearId = null;

player.onMoveRating = ({ grade }) => {
if (gradeText) gradeText.remove();
if (animId) cancelAnimationFrame(animId);
if (disappearId) clearTimeout(disappearId);

const feedbacks = Object.values(srabbit_ratings).find(
rating => rating.score === grade
).feedbacks;
if (!feedbacks) return;

const feedback = shuffle(feedbacks)[0];
gradeText = document.createElement('div');
gradeText.classList.add('srabbit_rating');

if (grade >= 3) {
gradeText.innerHTML = `<p>${feedback}</p>${++streak}`;
gradeText.style.color = '#0eff0e';
} else {
gradeText.style.color = grade >= 1 ? '#ffa500' : '#fd0009';
gradeText.innerHTML = `${feedback}`;
streak = 0;
}

player.dom.field.append(gradeText);

let start = null;
const duration = 800;
const initialScale = 0;
const finalScale = 1;
const randomAngle = getRandomAngle(3, 10);

function step(timestamp) {
if (!start) start = timestamp;
let progress = timestamp - start;
let easedScale = easeOutElastic(
progress,
initialScale,
finalScale - initialScale,
duration
);

if (progress < duration) {
animId = requestAnimationFrame(step);
} else {
// Ensure the final state is exactly scale(1)
easedScale = 1;
disappearId = setTimeout(() => {
disappearId = clearTimeout(disappearId);
gradeText.remove();
gradeText = null;
}, duration);
}

gradeText.style.transform = `rotate(${randomAngle}deg) translate(-50%, -50%) scale(${easedScale})`;
}

animId = requestAnimationFrame(step);
};

const API = {
frame(player_idx, data) {
player.setFrame(data);
Expand Down Expand Up @@ -459,6 +683,8 @@
});
});
};

window._player = player;
};
</script>
</body>
Expand Down
4 changes: 4 additions & 0 deletions public/views/Board.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,8 @@ export default class Board {
getField() {
return this.rows.reduce((acc, row) => (acc.push(...row.cells), acc), []);
}

toString() {
return this.rows.map(row => row.cells.join('')).join('\n');
}
}
80 changes: 70 additions & 10 deletions public/views/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ const DEFAULT_OPTIONS = {
const value = QueryString.get('srabbit_playout_length');
return /^[123]$/.test(value) ? parseInt(value, 10) : 2;
})(),
srabbit_rate: QueryString.get('srabbit_rate') === '1',
curtain: 1,
buffer_time,
format_score: (v, size) => {
Expand Down Expand Up @@ -550,6 +551,7 @@ export default class Player extends EventTarget {
onGameOver() {}
onCurtainDown() {}
onTetris() {}
onMoveRating() {}

setHideProfileCardOnNextGame(do_hide) {
this.hide_profile_card_on_next_game = !!do_hide;
Expand Down Expand Up @@ -1270,19 +1272,77 @@ export default class Player extends EventTarget {
currentPiece: piece_evt.piece,
nextPiece: frame.raw.preview,
board: piece_evt.field.map(cell => (cell ? 1 : 0)).join(''),
playoutLength: this.options.srabbit_playout_length,
playoutLength: this.options.srabbit_rate
? 1
: this.options.srabbit_playout_length,
};

const start = Date.now();
this.stackRabbitWorker.rpc('getMove', params).then(recommendation => {
const elapsed = Date.now() - start;
piece_evt.recommendation = recommendation;
console.log({
elapsed,
params,
recommendation,
});
});
this.stackRabbitWorker
.rpc('getMove', params)
.then(recommendation => {
const elapsed = Date.now() - start;
piece_evt.recommendation = recommendation;
console.log({
elapsed,
params,
recommendation,
});
})
.then(() => {
if (!this.options.srabbit_rate) return null;

const prior_piece_evt = peek(frame.pieces, 1);

if (!prior_piece_evt) return null;

const prior_frame = prior_piece_evt.frame;

const moveParams = {
level: prior_frame.raw.level <= 18 ? 18 : 19,
lines: prior_frame.raw.lines,
inputFrameTimeline: this.options.srabbit_input_timeline,
currentPiece: prior_piece_evt.piece,
nextPiece: piece_evt.piece,
board: prior_piece_evt.field.map(cell => (cell ? 1 : 0)).join(''),
secondBoard: params.board,
playoutLength: this.options.srabbit_rate
? 1
: this.options.srabbit_playout_length,
};

this.stackRabbitWorker.rpc('rateMove', moveParams).then(ratings => {
const { playerMoveAfterAdjustment, bestMoveAfterAdjustment } =
ratings;
let grade = null;

if (playerMoveAfterAdjustment >= bestMoveAfterAdjustment - 1) {
grade = 4;
} else if (playerMoveAfterAdjustment >= bestMoveAfterAdjustment - 3) {
grade = 3;
} else if (
playerMoveAfterAdjustment >=
bestMoveAfterAdjustment - 6
) {
grade = 2;
} else if (
playerMoveAfterAdjustment >=
bestMoveAfterAdjustment - 15
) {
grade = 1;
}
else {
grade = 0;
}

this.onMoveRating({ params: moveParams, ratings, grade });
}).catch(err => {
console.error(err);
})
})
.catch(err => {
console.error(err);
})
}

this.dom.drought.textContent = this.options.format_drought(
Expand Down
Binary file modified public/views/stackrabbit/wasmRabbit.wasm
Binary file not shown.

0 comments on commit 932e227

Please sign in to comment.