Skip to content

Instantly share code, notes, and snippets.

@lhoang
Last active November 18, 2020 23:03
Show Gist options
  • Save lhoang/6157785d3356f4d4c00a69e655c4f0b4 to your computer and use it in GitHub Desktop.
Save lhoang/6157785d3356f4d4c00a69e655c4f0b4 to your computer and use it in GitHub Desktop.
Bookmarklet The Crew BGA

Description

Ce bookmarklet permet d'afficher les cartes restantes à jouer pour The Crew - Board Game Arena. Pas vraiment de la triche, à partir de la mission 25, on passe son temps à regarder la log pour savoir ce qu'on a joué. Version FR/EN

From: https://gist.github.com/metaflow/363fda250c6593a671cd328ecd3bb630

Instructions

  1. Créer un favori
  2. Editer l'url et copier la line du fichier thecrew.js : javascript:(function()....
  3. Afficher une partie
  4. Cliquer sur le favori
// FROM https://gist.github.com/metaflow/363fda250c6593a671cd328ecd3bb630
colors = ['blue', 'yellow', 'green', 'pink', 'black'];
function parse(e) {
var entry = {
'type': null,
'player': '',
'cards': [],
};
var text = '';
for (const c of e.childNodes) {
if (c.nodeType == 3) text += c.nodeValue;
if (colors.indexOf(c.className) > -1) {
entry.cards.push({ 'color': c.className, 'value': toint(c.innerText) });
}
}
textToType = new Map([
['plays', 'plays'],
['new mission', 'new mission'],
['wins the trick', 'wins the trick'],
['joue', 'plays'],
['nouvelle mission', 'new mission'],
['remporte le pli', 'wins the trick'],
]);
for (let [key, value] of textToType.entries()) {
if (text.indexOf(key) < 0) continue;
entry.type = value;
break;
}
if (entry.type == null) return null;
if (entry.type == 'plays' && entry.cards.length ==0) return null;
if (e.querySelector('.playername')) {
entry.player = e.querySelector('.playername').innerText;
}
return entry;
}
class State {
constructor() {
this.players = new Set();
this.reset();
}
reset() {
this.cards = new Map();
this.missing = new Map();
for (const p of this.players) this.missing.set(p, new Set());
this.currentColor = '';
for (const c of colors) {
this.cards.set(c, c == 'black' ? [1, 2, 3, 4] : [1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
}
run(action) {
switch (action.type) {
case 'new mission':
this.reset();
break;
case 'plays':
if (!this.players.has(action.player)) {
this.missing.set(action.player, new Set());
this.players.add(action.player);
}
const card = action.cards[0];
this.cards.get(card.color)[card.value - 1] = 0;
if (this.currentColor == '') {
this.currentColor = card.color;
} else {
if (this.currentColor != card.color) this.missing.get(action.player).add(this.currentColor);
}
break;
case 'wins the trick':
this.currentColor = '';
break;
default:
console.error('unknown action type', action.type);
}
}
}
function drawState(s) {
area = document.querySelector('#customTable');
if (!area) {
area = document.createElement('div');
area.id = 'customTable';
area.style = 'width: 280px; height: 150px; padding: 5px; font-weight: bold;';
document.getElementById('playertable_central').appendChild(area);
}
area.innerHTML = '';
for (const c of colors) {
row = document.createElement('div');
row.style = 'display: flex;';
for (const i of s.cards.get(c)) {
tile = document.createElement('div');
tile.innerText = i;
dc = (i < 1) ? 'transparent' : c;
tile.style = `display: block; min-height: 25px; min-width: 25px; margin: 2px; line-height: 25px; color: ${dc}; border: 1px solid ${dc};`;
row.appendChild(tile);
}
area.appendChild(row);
}
for (const p of s.players) {
document.querySelectorAll('.playertablename').forEach(c => {
if (c.innerText.trim().indexOf(p) == -1) return;
m = c.querySelector('.missing');
if (!m) {
m = document.createElement('div');
m.className = 'missing';
m.style = 'display: inline-block; font-size: 14px; ';
c.appendChild(m);
}
m.innerHTML = '';
for (const c of s.missing.get(p)) {
tile = document.createElement('div');
tile.innerText = 'X';
tile.style = `display: inline-block; min-height: 15px; margin: 2px; min-width: 15px; line-height: 15px; color: ${c}; border: 1px solid ${c};`;
m.appendChild(tile);
}
});
}
}
function crewTable() {
logs = Array.from(document.querySelectorAll('#logs .log > div'));
logs = logs.reverse();
const actions = logs.map(parse).filter(a => a);
let s = new State();
actions.forEach(a => {
s.run(a);
});
drawState(s);
};
window.setInterval(crewTable, 1000);
javascript:(function(){colors=['blue','yellow','green','pink','black'];function parse(e){var entry={'type':null,'player':'','cards':[],};var text='';for(const c of e.childNodes){if(c.nodeType==3)text+=c.nodeValue;if(colors.indexOf(c.className)>-1){entry.cards.push({'color':c.className,'value':toint(c.innerText)});}}textToType=new Map([['plays','plays'],['new mission','new mission'],['wins the trick','wins the trick'],['joue','plays'],['nouvelle mission','new mission'],['remporte le pli','wins the trick'],]);for(let[key,value]of textToType.entries()){if(text.indexOf(key)<0)continue;entry.type=value;break;}if(entry.type==null)return null;if(entry.type=='plays'&&entry.cards.length==0)return null;if(e.querySelector('.playername')){entry.player=e.querySelector('.playername').innerText;}return entry;}class State{constructor(){this.players=new Set();this.reset();}reset(){this.cards=new Map();this.missing=new Map();for(const p of this.players)this.missing.set(p,new Set());this.currentColor='';for(const c of colors){this.cards.set(c,c=='black'?[1,2,3,4]:[1,2,3,4,5,6,7,8,9]);}}run(action){switch(action.type){case 'new mission':this.reset();break;case 'plays':if(!this.players.has(action.player)){this.missing.set(action.player,new Set());this.players.add(action.player);}const card=action.cards[0];this.cards.get(card.color)[card.value-1]=0;if(this.currentColor==''){this.currentColor=card.color;}else{if(this.currentColor!=card.color)this.missing.get(action.player).add(this.currentColor);}break;case 'wins the trick':this.currentColor='';break;default:console.error('unknown action type',action.type);}}}function drawState(s){area=document.querySelector('#customTable');if(!area){area=document.createElement('div');area.id='customTable';area.style='width:%20280px;%20height:%20150px;%20padding:%205px;%20font-weight:%20bold;';document.getElementById('playertable_central').appendChild(area);}area.innerHTML='';for(const%20c%20of%20colors){row=document.createElement('div');row.style='display:%20flex;';for(const%20i%20of%20s.cards.get(c)){tile=document.createElement('div');tile.innerText=i;dc=(i<1)?'transparent':c;tile.style=`display:block;min-height:25px;min-width:25px;margin:2px;line-height:25px;color:${dc};border:1px%20solid%20${dc};`;row.appendChild(tile);}area.appendChild(row);}for(const%20p%20of%20s.players){document.querySelectorAll('.playertablename').forEach(c=>{if(c.innerText.trim().indexOf(p)==-1)return;m=c.querySelector('.missing');if(!m){m=document.createElement('div');m.className='missing';m.style='display:%20inline-block;%20font-size:%2014px;%20';c.appendChild(m);}m.innerHTML='';for(const%20c%20of%20s.missing.get(p)){tile=document.createElement('div');tile.innerText='X';tile.style=`display:inline-block;min-height:15px;margin:2px;min-width:15px;line-height:15px;color:${c};border:1px%20solid%20${c};`;m.appendChild(tile);}});}}function%20crewTable(){logs=Array.from(document.querySelectorAll('#logs%20.log%20>%20div'));logs=logs.reverse();const%20actions=logs.map(parse).filter(a=>a);let%20s=new%20State();actions.forEach(a=>{s.run(a);});drawState(s);};window.setInterval(crewTable,1000);})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment