desenvolvimento pre-lancamento
Commit inicial - add do repo privado para o repo NT style: changes header's logo and colors style: changes home page first session layout feat: creates about us home page section chore: creates home page section for whom chore: creates student materails home page section chore: creates teachers materials home page section chore: creates teacher materials home page section style: changes primary color style: changes color at activities page style: changes about page color style: changes name to Decoda fix: changes route to about page at footer fix: changes background color style: changes game page header colors style: changes footer colors chore: adds home page sections title style: changes main font family to Lato style: adds title font fix: changes sizes to be more responsive for mobile ajuste no build vercel atualiza regras envio homol Adiciona instrucoes de uso add JupyterLite fix solucao turtle Add Mole Mash e Modal de Falhas Add Progress Bar na pagina de Atividades fix game name chore: atualiza lockfile removendo vercel analytics inclusão de efeito ao mudar de fase add mecanismo de solução de fases em debug vite config test add BaseGame e refator do MoleMash refatoração turtle refatoração automato refatoração automato add tag bug 1 e 2 automato mostrar apenas games em homologação na pagina de atividades aumentar timeout das fases finais do Turtle fix bug scroll add video refactor semaforo arrumar ordem das cores add build docs update vercel update vercel update vercel update vercel update vercel add vercel jupyter add vercel jupyter fix deploy Vercel fix deploy Vercel fix deploy Vercel add cripto add cripto refatoração fix tour Mole Mash . remover arquivos de controle chore: adds development tag for activity card remover arquivos de status indevidamente versionados atualizar cores nas atividades add Quebra Cabeças add Quebra Cabeças add iniciativas add Iniciativas alteração de fotos pesadas fix menu mobile fix menu mobile fix menu mobile add Aspirador update icons update identidade visual documentação update jupyter add kernel python local add kernel python local add kernel python local feat: add health check feat: add primeiros passos add letramento mover letramento de lugar update path games update path games fix: ajuste clique rapido no botão executar remover dead code fix: refactor: extract shared utilities for storage, phase unlock and mobile detection stabilize context references and fix stale closure extrair GameProgressContext do GameStateContext (SRP) refactor(game): extrair usePhaser e useGameModals de GameBase + corrigir bugs descobertos refactor(game): remove todos os aliases PT/EN duplicados Remover aliases PT/EN da camada de modais refactor + tests security: add CodeSanitizer and integrate into GameInterpreter - CodeSanitizer.js: 4 built-in rules (max_length, infinite_while, infinite_for, excessive_nesting) with pluggable extra rules - GameInterpreter.executeCode: calls sanitizeCode() before js-interpreter, differentiates CodeSanitizationError (warn) from other errors (error) - 21 unit tests for CodeSanitizer (100% coverage) - 4 integration tests in GameInterpreter for sanitization paths add CodeSanitizer fix: fase 10 aspirador fix: bug semaforo teste feat: add version Ajusta a landing page para ficar mais próxima ao protótipo ajusta raio da borda do botão de Acesse nosso Laboratório pequenos ajustes de layout na página de iniciativas atualiza tabela de jogos educativos com os jogos disponíveis atualmente ajustados pequenos detalhes e informações do jogos na seção de guias pedagógicos troca nome playground para laboratório e adiciona imagens do lab adiciona documentação de conceitos básicos de programação ajustado pequenos erros de digitação adiciona tooltip com conceitos escondidos em hover na tag +N de conceitos update docs dev desativar tour setup matriz MoleMash setup matriz MoleMash fix: link update version update docs update docs mudou o layout de quem somos mudei as imgs dos icons e baixei o botao centraliza titulo com imagem e ajusta sessão com gradiente vermelho-rosa adiciona responsividade para a pagina quem somos ajusta botão de conheça nossa história ajustes ajustes na home + add. teclado update version security security feat: add tapume para telas pequenas v1.1.0 feat: decoda offline feat: doc offline offline fix: ajustes para release fix: navbar; config ordenação; versão fix: rotas docs e jupyter para pwa delete private files Co-authored-by: Indra Araujo <indra.araujo.santos@gmail.com> Co-authored-by: solange dos santos <sollangelive71@gmail.com>
This commit is contained in:
175
app/src/atividades/programacao/cripto/config/codeValidations.js
Normal file
175
app/src/atividades/programacao/cripto/config/codeValidations.js
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* @fileoverview Utility module for codeValidations.js
|
||||
*
|
||||
* @module games.cripto.config.codeValidations
|
||||
*/
|
||||
|
||||
// Código de validações para prevenir loops infinitos e erros comuns nas fases do jogo.
|
||||
// As validações são usadas pelo BaseGameScene/config.js para bloquear execuções inseguras.
|
||||
|
||||
/**
|
||||
* Valida se um loop while contém incremento ou decremento do contador
|
||||
* Previne loops infinitos onde o contador nunca muda
|
||||
*/
|
||||
export function validateWhileWithCounter(code) {
|
||||
// Verifica se há um loop while no código
|
||||
const hasWhile = /while\s*\(/i.test(code);
|
||||
if (!hasWhile) return { valid: true };
|
||||
|
||||
// Verifica se o contador é usado na condição do while
|
||||
const whileWithCounter = /while\s*\([^)]*[cC]ontador[^)]*\)/i.test(code);
|
||||
if (!whileWithCounter) {
|
||||
// Se não usa contador na condição, não validamos (pode ser outro tipo de loop)
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
// Verifica se há incremento/decremento do contador dentro do loop
|
||||
const hasCounterIncrement =
|
||||
/(definirContador|contador\s*[+-]=|\+\+contador|contador\+\+|--contador|contador--)/i.test(
|
||||
code,
|
||||
);
|
||||
|
||||
if (!hasCounterIncrement) {
|
||||
return {
|
||||
valid: false,
|
||||
message:
|
||||
'Loop Infinito Detectado!\n\nSeu loop WHILE usa o CONTADOR na condição, mas não há incremento/decremento do CONTADOR dentro do loop.\n\nIsso causará um loop infinito!\n\nSolução: Adicione um bloco "definir CONTADOR" para incrementar o contador dentro do loop.',
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida se o loop while tem uma condição que pode eventualmente se tornar falsa
|
||||
*/
|
||||
export function validateWhileCondition(code) {
|
||||
// Detecta condições sempre verdadeiras óbvias
|
||||
const alwaysTruePatterns = [
|
||||
/while\s*\(\s*true\s*\)/i,
|
||||
/while\s*\(\s*1\s*\)/i,
|
||||
/while\s*\(\s*"[^"]+"\s*\)/i, // string não vazia
|
||||
];
|
||||
|
||||
for (const pattern of alwaysTruePatterns) {
|
||||
if (pattern.test(code)) {
|
||||
return {
|
||||
valid: false,
|
||||
message:
|
||||
'Loop Infinito Detectado!\n\nSua condição do WHILE é sempre verdadeira, o que causará um loop infinito.\n\nSolução: Use uma condição que possa se tornar falsa, como "CONTADOR < comprimento de ENTRADA".',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida se o loop while que usa length() modifica o que está sendo iterado
|
||||
*/
|
||||
export function validateWhileWithLength(code) {
|
||||
const hasWhileWithLength = /while\s*\([^)]*\.length[^)]*\)/i.test(code);
|
||||
if (!hasWhileWithLength) return { valid: true };
|
||||
|
||||
// Verifica se há chamada para obterEntrada() dentro da condição
|
||||
const hasGetInputInCondition = /while\s*\([^)]*obterEntrada\(\)[^)]*\)/i.test(
|
||||
code,
|
||||
);
|
||||
if (!hasGetInputInCondition) return { valid: true };
|
||||
|
||||
// Verifica se há incremento do contador
|
||||
const hasCounterIncrement =
|
||||
/(definirContador|contador\s*[+-]=|\+\+contador|contador\+\+)/i.test(
|
||||
code,
|
||||
);
|
||||
|
||||
if (!hasCounterIncrement) {
|
||||
return {
|
||||
valid: false,
|
||||
message:
|
||||
"Loop Infinito Detectado!\n\nSeu loop usa o comprimento da ENTRADA, mas não incrementa o CONTADOR.\n\nIsso causará um loop infinito!\n\nSolução: Adicione incremento do CONTADOR dentro do loop.",
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida se há pelo menos um loop no código (para fases que exigem iteração)
|
||||
*/
|
||||
export function validateHasLoop(code) {
|
||||
const hasLoop = /while\s*\(|for\s*\(/i.test(code);
|
||||
|
||||
if (!hasLoop) {
|
||||
return {
|
||||
valid: false,
|
||||
message:
|
||||
"Loop Necessário!\n\nEsta fase requer que você use um loop (WHILE) para processar cada caractere da entrada.\n\nSolução: Use um bloco WHILE para percorrer a entrada caractere por caractere.",
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida se o código define a entrada antes de usá-la
|
||||
*/
|
||||
export function validateInputBeforeUse(code) {
|
||||
const hasGetInput = /obterEntrada\(\)/i.test(code);
|
||||
if (!hasGetInput) return { valid: true }; // Não usa entrada, ok
|
||||
|
||||
const hasSetInput = /definirEntrada\(/i.test(code);
|
||||
|
||||
if (!hasSetInput) {
|
||||
return {
|
||||
valid: false,
|
||||
message:
|
||||
'Entrada não definida!\n\nVocê está tentando obter a ENTRADA sem defini-la primeiro.\n\nSolução: Use o bloco "definir ENTRADA" antes de usar "obter ENTRADA".',
|
||||
};
|
||||
}
|
||||
|
||||
// Verifica ordem (definir antes de obter) - simplificado
|
||||
const setInputIndex = code.search(/definirEntrada\(/i);
|
||||
const getInputIndex = code.search(/obterEntrada\(\)/i);
|
||||
|
||||
if (getInputIndex < setInputIndex) {
|
||||
return {
|
||||
valid: false,
|
||||
message:
|
||||
'Ordem incorreta!\n\nVocê está tentando obter a ENTRADA antes de defini-la.\n\nSolução: Mova o bloco "definir ENTRADA" para antes de "obter ENTRADA".',
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Combina múltiplas validações
|
||||
*/
|
||||
export function validateCode(code, validations = []) {
|
||||
for (const validation of validations) {
|
||||
const result = validation(code);
|
||||
if (!result.valid) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Validações padrão para fases com loops
|
||||
*/
|
||||
export const defaultLoopValidations = [
|
||||
validateWhileCondition,
|
||||
validateWhileWithCounter,
|
||||
validateWhileWithLength,
|
||||
validateInputBeforeUse,
|
||||
];
|
||||
|
||||
/**
|
||||
* Validações para fases que exigem loops
|
||||
*/
|
||||
export const requiredLoopValidations = [
|
||||
validateHasLoop,
|
||||
...defaultLoopValidations,
|
||||
];
|
||||
419
app/src/atividades/programacao/cripto/config/config.js
Normal file
419
app/src/atividades/programacao/cripto/config/config.js
Normal file
@@ -0,0 +1,419 @@
|
||||
/**
|
||||
* @fileoverview Utility module for config.js
|
||||
*
|
||||
* @module games.cripto.config.config
|
||||
*/
|
||||
|
||||
export const gameConfig = {
|
||||
gameId: "cripto",
|
||||
gameName: "Cripto",
|
||||
type: "blocks",
|
||||
icon: "🔐",
|
||||
thumbnail: "/images/atividades/programacao/cripto-thumbnail.png",
|
||||
descricao:
|
||||
"Aprenda fundamentos de criptografia e segurança cibernética programando blocos para proteger dados e comunicações.",
|
||||
dificuldade: "Avançado",
|
||||
categoria: "Lógica",
|
||||
tempoEstimado: "45-60 min",
|
||||
conceitos: [
|
||||
"Criptografia",
|
||||
"Repetição",
|
||||
"Variaveis",
|
||||
"Funções",
|
||||
"Condicionais",
|
||||
],
|
||||
route: "/atividades/programacao/cripto",
|
||||
component: "CriptoGame",
|
||||
objectives: [
|
||||
"Entender os conceitos básicos de criptografia",
|
||||
"Implementar algoritmos de criptografia simples",
|
||||
"Aplicar lógica de programação para resolver desafios de segurança",
|
||||
],
|
||||
metadata: {
|
||||
lastUpdated: "2026-02-12",
|
||||
version: "1.0.0",
|
||||
},
|
||||
|
||||
fases: [
|
||||
{
|
||||
id: 1,
|
||||
nome: "De Letra para Número",
|
||||
descricao:
|
||||
'Converta cada letra do alfabeto em sua posição numérica (A=0, B=1, C=2...). Primeiro, defina a ENTRADA como o alfabeto completo "ABCDEFGHIJKLMNOPQRSTUVWXYZ". Depois, use um loop "enquanto" para percorrer cada posição e adicionar o número correspondente à SAÍDA. Dica: o CONTADOR já representa a posição da letra!',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"obter_saida",
|
||||
"text_length",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"math_arithmetic",
|
||||
"text",
|
||||
],
|
||||
/**
|
||||
* Garante que há um loop com incremento do contador para evitar loop infinito
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
expectedOutput: "012345678910111213141516171819202122232425",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
nome: "De Número para Letra",
|
||||
descricao:
|
||||
'Reverta o processo! A ENTRADA contém dígitos "0123456789" (cada dígito é a posição de uma letra). Crie a variável "letra" para guardar cada caractere. Use o bloco "no texto obter letra #" para pegar cada dígito, depois busque no ALFABETO a letra correspondente. Por exemplo: dígito "0" → letra "A", dígito "1" → letra "B".',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"math_arithmetic",
|
||||
"text",
|
||||
"alfabeto",
|
||||
"definir_letra",
|
||||
"obter_letra",
|
||||
],
|
||||
/**
|
||||
* Garante que há um loop com incremento do contador
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "0123456789",
|
||||
expectedOutput: "ABCDEFGHIJ",
|
||||
alfabeto: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
nome: "Cifra de César (+3)",
|
||||
descricao:
|
||||
'Implemente a Cifra de César com deslocamento fixo de +3. Para a ENTRADA "TECNOLOGIA", cada letra deve avançar 3 posições (exemplo: A→D, B→E, C→F). Crie variáveis: "letra" (use "no texto obter letra #"), "posicao" (use "no texto encontrar primeira ocorrência de" para achar a letra no ALFABETO), "nova_posicao" (calcule: (posicao + 3) RESTO DA DIVISÃO POR 26 - use o bloco "resto da divisão de... por..."), e "nova_letra" (pegue do ALFABETO na nova_posicao).',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"text_indexOf",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"math_arithmetic",
|
||||
"math_modulo",
|
||||
"text",
|
||||
"alfabeto",
|
||||
"definir_letra",
|
||||
"obter_letra",
|
||||
"definir_posicao",
|
||||
"obter_posicao",
|
||||
"definir_nova_posicao",
|
||||
"obter_nova_posicao",
|
||||
"definir_nova_letra",
|
||||
"obter_nova_letra",
|
||||
],
|
||||
/**
|
||||
* Garante loop com incremento de contador
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "TECNOLOGIA",
|
||||
expectedOutput: "WHFQRORJLD",
|
||||
alfabeto: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
chave: 3,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
nome: "Cifra de César (-3)",
|
||||
descricao:
|
||||
'Descriptografe uma mensagem cifrada com deslocamento -3. Para a ENTRADA "GHFRGD", volte 3 posições: G→D, H→E, etc. Crie as mesmas variáveis da fase anterior: "letra", "posicao", "nova_posicao" e "nova_letra". Importante: calcule nova_posicao como (posicao - 3 + 26) RESTO DA DIVISÃO POR 26 (use o bloco "resto da divisão de... por..."). O +26 evita números negativos!',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"text_indexOf",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"math_arithmetic",
|
||||
"math_modulo",
|
||||
"text",
|
||||
"alfabeto",
|
||||
"definir_letra",
|
||||
"obter_letra",
|
||||
"definir_posicao",
|
||||
"obter_posicao",
|
||||
"definir_nova_posicao",
|
||||
"obter_nova_posicao",
|
||||
"definir_nova_letra",
|
||||
"obter_nova_letra",
|
||||
],
|
||||
/**
|
||||
* Garante loop com incremento de contador
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "GHFRGD",
|
||||
expectedOutput: "DECODA",
|
||||
alfabeto: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
chave: -3,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
nome: "Criptografia com Chave Variável",
|
||||
descricao:
|
||||
'Use uma chave customizada para criptografar! Para a ENTRADA "NUCLEO" com chave 5, desloque cada letra 5 posições. Crie a variável "chave" com valor 5. Depois use as mesmas variáveis das fases anteriores: "letra", "posicao", "nova_posicao" (use o bloco "resto da divisão" para calcular (posicao + chave) % 26) e "nova_letra". Na fórmula, use a variável "chave" em vez do número fixo 3.',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"text_indexOf",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"math_arithmetic",
|
||||
"math_modulo",
|
||||
"text",
|
||||
"alfabeto",
|
||||
"definir_letra",
|
||||
"obter_letra",
|
||||
"definir_posicao",
|
||||
"obter_posicao",
|
||||
"definir_nova_posicao",
|
||||
"obter_nova_posicao",
|
||||
"definir_nova_letra",
|
||||
"obter_nova_letra",
|
||||
"definir_chave",
|
||||
"obter_chave",
|
||||
],
|
||||
/**
|
||||
* Garante loop com incremento de contador
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "NUCLEO",
|
||||
expectedOutput: "SZHQJT",
|
||||
alfabeto: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
chave: 5,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
nome: "Descriptografia com Chave Variável",
|
||||
descricao:
|
||||
'Desfaça a criptografia anterior! Para a ENTRADA "SZHQJT" com chave 5, volte 5 posições. Use as mesmas variáveis da Fase 5, mas agora calcule nova_posicao como: (posicao - chave + 26) RESTO DA DIVISÃO POR 26 (use o bloco "resto da divisão de... por..."). Lembre-se: sempre some 26 antes do módulo quando subtrair!',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"text_indexOf",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"math_arithmetic",
|
||||
"math_modulo",
|
||||
"text",
|
||||
"alfabeto",
|
||||
"definir_letra",
|
||||
"obter_letra",
|
||||
"definir_posicao",
|
||||
"obter_posicao",
|
||||
"definir_nova_posicao",
|
||||
"obter_nova_posicao",
|
||||
"definir_nova_letra",
|
||||
"obter_nova_letra",
|
||||
"definir_chave",
|
||||
"obter_chave",
|
||||
],
|
||||
/**
|
||||
* Garante loop com incremento de contador
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "SZHQJT",
|
||||
expectedOutput: "NUCLEO",
|
||||
alfabeto: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
chave: 5,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
nome: "Código Leetspeak",
|
||||
descricao:
|
||||
'Use condicionais para substituir letras específicas por números! Para a ENTRADA "SOBERANIA", substitua A→4, E→3, S→5 e I→1, mantendo as outras iguais. Crie a variável "letra" para pegar cada caractere (use "no texto obter letra #"). Depois use blocos SE-SENÃO: se letra = "A" então concatene "4", senão se letra = "E" então concatene "3", senão se letra = "S" então concatene "5", senão se letra = "I" então concatene "1", senão concatene a própria letra.',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"controls_whileUntil",
|
||||
"controls_if",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"text",
|
||||
"definir_letra",
|
||||
"definir_nova_letra",
|
||||
"obter_nova_letra",
|
||||
"obter_letra",
|
||||
],
|
||||
/**
|
||||
* Garante loop com incremento de contador
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "SOBERANIA",
|
||||
expectedOutput: "5OB3R4N14",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
nome: "Mensagem Invertida",
|
||||
descricao:
|
||||
'Inverta a ordem das letras! Para a ENTRADA "DECODA", o resultado deve ser "ADOCED". Duas abordagens: (1) Inicie CONTADOR com (comprimento - 1) e decremente até 0, OU (2) Crie variável "letra", pegue cada caractere e use o bloco "criar texto com" para juntar: primeira entrada = letra, segunda entrada = SAÍDA atual. Isso coloca cada letra ANTES das anteriores.',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"obter_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"text_join",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"math_arithmetic",
|
||||
"text",
|
||||
"definir_letra",
|
||||
"obter_letra",
|
||||
],
|
||||
/**
|
||||
* Garante loop com incremento de contador (ou decremento para inversão)
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*(\+|-)/,
|
||||
expectedInput: "DECODA",
|
||||
expectedOutput: "ADOCED",
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
nome: "Alfabeto Secreto",
|
||||
descricao:
|
||||
'Use um alfabeto embaralhado para cifrar! Para a ENTRADA "FENALUTA", use os blocos ALFABETO (normal) e ALFABETO_SECRETO (embaralhado). Crie variáveis: "letra" (pegue com "no texto obter letra #"), "posicao" (use "no texto encontrar" para buscar a letra no ALFABETO normal), e "letra_secreta" (pegue com "no texto obter letra #" na mesma posição do ALFABETO_SECRETO). Exemplo: R está na posição 17 do normal → posição 17 do secreto é A.',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"text_indexOf",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"text",
|
||||
"alfabeto",
|
||||
"alfabeto_secreto",
|
||||
"definir_letra",
|
||||
"obter_letra",
|
||||
"definir_posicao",
|
||||
"obter_posicao",
|
||||
"definir_letra_secreta",
|
||||
"obter_letra_secreta",
|
||||
],
|
||||
/**
|
||||
* Garante loop com incremento de contador
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "FENALUTA",
|
||||
expectedOutput: "YTFQSXZQ",
|
||||
alfabeto: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
alfabetoSecreto: "QWERTYUIOPASDFGHJKLZXCVBNM",
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
nome: "Somador de Integridade (Hash)",
|
||||
descricao:
|
||||
'Para garantir que uma mensagem não foi alterada, usamos um "Hash" — uma assinatura numérica única. Para cada letra da ENTRADA "CRIPTOGRAFIA", descubra sua posição no ALFABETO e atualize a variável "SOMA" usando a fórmula: (SOMA * 31 + posicao). Para manter o número dentro de um limite, use o RESTO DA DIVISÃO por 1000000007. Dentro do loop, chame "definir SAÍDA como SOMA" para ver o hash atualizando letra a letra.',
|
||||
timeout: 30,
|
||||
allowedBlocks: [
|
||||
"obter_contador",
|
||||
"definir_contador",
|
||||
"definir_entrada",
|
||||
"obter_entrada",
|
||||
"definir_saida",
|
||||
"concatenar_saida",
|
||||
"text_length",
|
||||
"text_charAt",
|
||||
"text_indexOf",
|
||||
"controls_whileUntil",
|
||||
"logic_compare",
|
||||
"math_number",
|
||||
"math_arithmetic",
|
||||
"math_modulo",
|
||||
"text",
|
||||
"alfabeto",
|
||||
"definir_letra",
|
||||
"obter_letra",
|
||||
"definir_posicao",
|
||||
"obter_posicao",
|
||||
"definir_soma",
|
||||
"obter_soma",
|
||||
],
|
||||
/**
|
||||
* Garante loop com incremento de contador
|
||||
*/
|
||||
validationRegex: /(while|for)[\s\S]*definirContador[\s\S]*\+/,
|
||||
expectedInput: "CRIPTOGRAFIA",
|
||||
expectedOutput: "911701368",
|
||||
alfabeto: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
},
|
||||
],
|
||||
mensagens: {
|
||||
entradaIncorreta:
|
||||
"Entrada incorreta. Você deve definir a ENTRADA como o alfabeto completo.",
|
||||
saidaIncorreta:
|
||||
"Saída incorreta. Cada letra deve ser convertida para sua posição numérica (A=0, B=1, C=2...). O CONTADOR já representa essa posição!",
|
||||
erroGeral: "Algo deu errado durante a execução. Verifique seu código.",
|
||||
erroEstrutura:
|
||||
'Loop Infinito Detectado!\n\nSeu código não incrementa o CONTADOR dentro do loop WHILE. Isso causará um loop infinito!\n\n💡 Solução:\nAdicione um bloco "definir CONTADOR como (obter CONTADOR + 1)" dentro do loop para que o contador avance a cada iteração.',
|
||||
sucessoGenerico: "Parabéns! Você completou o desafio!",
|
||||
timeoutExcedido:
|
||||
"O tempo de execução foi excedido. Verifique se não há loops infinitos ou se o contador está sendo incrementado corretamente.",
|
||||
},
|
||||
};
|
||||
2430
app/src/atividades/programacao/cripto/config/debugSolutions.js
Normal file
2430
app/src/atividades/programacao/cripto/config/debugSolutions.js
Normal file
File diff suppressed because it is too large
Load Diff
1910
app/src/atividades/programacao/cripto/config/starterBlocks.js
Normal file
1910
app/src/atividades/programacao/cripto/config/starterBlocks.js
Normal file
File diff suppressed because it is too large
Load Diff
73
app/src/atividades/programacao/cripto/config/tourSteps.js
Normal file
73
app/src/atividades/programacao/cripto/config/tourSteps.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @fileoverview Utility module for tourSteps.js
|
||||
*
|
||||
* @module games.cripto.config.tourSteps
|
||||
*/
|
||||
|
||||
import {
|
||||
createWelcomeStep,
|
||||
createGameAreaStep,
|
||||
createToolboxStep,
|
||||
createWorkspaceStep,
|
||||
createRunButtonStep,
|
||||
createResetInfoStep,
|
||||
createPhaseSelectorStep,
|
||||
createPhaseInfoStep,
|
||||
createHelpButtonStep,
|
||||
gameIcons,
|
||||
defaultGameTourOptions,
|
||||
} from "../../../../utils/tourHelpers";
|
||||
|
||||
export const criptoTourSteps = [
|
||||
createWelcomeStep({
|
||||
gameName: "Jogo Cripto",
|
||||
description:
|
||||
"Bem-vindo ao mundo da criptografia! Aqui você vai aprender os fundamentos de segurança digital e como transformar informações.",
|
||||
challenge:
|
||||
"Use programação em blocos para converter letras em números e implementar algoritmos de criptografia!",
|
||||
iconSvg: gameIcons.lock,
|
||||
}),
|
||||
|
||||
createGameAreaStep({
|
||||
title: "Monitor Criptográfico",
|
||||
description:
|
||||
"Nesta tela você verá três áreas: valores de ENTRADA e SAÍDA. Seus blocos transformarão a entrada em saída criptografada.",
|
||||
}),
|
||||
|
||||
createToolboxStep({
|
||||
description:
|
||||
"Use os blocos disponíveis: definir entrada/saída, obter valores, concatenar texto, contador, loops e condicionais. Arraste-os para criar seu algoritmo.",
|
||||
}),
|
||||
|
||||
createWorkspaceStep({
|
||||
description:
|
||||
"Monte sua sequência lógica aqui. Encaixe os blocos na ordem correta para processar a entrada e gerar a saída esperada.",
|
||||
}),
|
||||
|
||||
createRunButtonStep({
|
||||
description:
|
||||
"Execute seu código! Você verá as animações acontecendo passo a passo: cursor piscando na entrada e caracteres embaralhando na saída.",
|
||||
}),
|
||||
|
||||
createResetInfoStep({
|
||||
description:
|
||||
"Se algo não funcionar como esperado, use o reset para limpar e tentar uma nova solução.",
|
||||
}),
|
||||
|
||||
createPhaseSelectorStep({
|
||||
description:
|
||||
"O jogo tem várias fases com diferentes desafios de criptografia, desde conversão básica até algoritmos mais complexos.",
|
||||
}),
|
||||
|
||||
createPhaseInfoStep({
|
||||
description:
|
||||
"Acompanhe seu progresso e veja informações sobre a fase atual aqui.",
|
||||
}),
|
||||
|
||||
createHelpButtonStep({
|
||||
description:
|
||||
"Acesse este tour novamente clicando no botão de ajuda sempre que precisar de orientação.",
|
||||
}),
|
||||
];
|
||||
|
||||
export const criptoTourOptions = defaultGameTourOptions;
|
||||
Reference in New Issue
Block a user