Created
June 15, 2025 23:22
-
-
Save corlaez/39b74508645b33f399f39c036a1b23d4 to your computer and use it in GitHub Desktop.
Carrera C++ con musica
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "pch.h" | |
#include <iostream> | |
#include <conio.h> | |
#include <Windows.h> | |
#include <ctime> | |
#include <thread> | |
#include <vector> | |
using namespace System; | |
using namespace std; | |
const int ANCHO = 90; // columnas | |
const int ALTO = 34; // filas | |
const int numerocarros = 6; | |
const int carros_alto = 2; | |
const int carros_ancho = 14; | |
const ConsoleColor paleta[numerocarros] = | |
{ | |
ConsoleColor::Red, | |
ConsoleColor::Blue, | |
ConsoleColor::Green, | |
ConsoleColor::Cyan, | |
ConsoleColor::Magenta, | |
ConsoleColor::Yellow | |
}; | |
ConsoleColor color[numerocarros]; | |
int posX[numerocarros]; | |
int posY[numerocarros]; | |
int vel[numerocarros]; | |
int wins[numerocarros] = { 0 }; | |
bool der[numerocarros]; | |
int limIzq[numerocarros]; | |
int limDer[numerocarros]; | |
int etapa[numerocarros]; | |
const int filaMeta[6] = { 20,22,24,26,28,30 }; | |
const int metaFinalX = 0; | |
const int paso[6] = { 120000, 130000, 150000, 150000, 180000, 190000 }; | |
/* Bloquea la ejecucion del codigo hasta que detecta que la tecla ha sido presionada */ | |
void esperarTecla(char tecla) { | |
while (true) { | |
if (kbhit) | |
{ | |
if (getch() == tecla) | |
{ | |
break; | |
} | |
} | |
} | |
} | |
/* Bloquea la ejecucion del codigo hasta que detecta que una de las teclas ha sido presionada y retorna su indice */ | |
int esperarTeclas(std::initializer_list<char> teclas) { | |
while (true) { | |
if (kbhit) | |
{ | |
char teclaPresionada = getch(); | |
for (size_t i = 0; i < teclas.size(); ++i) { | |
if (teclaPresionada == teclas.begin()[i]) | |
{ | |
return i; | |
} | |
} | |
} | |
} | |
} | |
void moverCursor(int x, int y) { | |
if (x >= 0 && x < ANCHO && y >= 0 && y < ALTO) | |
Console::SetCursorPosition(x, y); | |
} | |
const char* carroDer[numerocarros][carros_alto] = { | |
{ | |
"_/¯¯¯¯¯¯¯¯\\__", | |
"\\--O-----O--/" | |
}, | |
{ | |
"---------- ", | |
"-@-[O_O]-@-- " | |
}, | |
{ | |
" #-------->> ", | |
"--[]--------[]" | |
}, | |
{ | |
" >>═══════ ", | |
"¯¯(_)¯¯¯(_)¯¯ " | |
}, | |
{ | |
" /¯¯¯¯\\___ ", | |
"/\\(o¯¯o)__/ " | |
}, | |
{ | |
"_________ ", | |
"\\(_)---(_)-/ " | |
} | |
}; | |
const char* carroIzq[numerocarros][carros_alto] = { | |
{ | |
"__/¯¯¯¯¯¯¯¯\\_", | |
"\\--O-----O--/" | |
}, | |
{ | |
" ----------", | |
" --@-[O_O]-@-" | |
}, | |
{ | |
" <<--------# ", | |
"[]--------[]--" | |
}, | |
{ | |
" ═══════<< ", | |
" ¯¯(_)¯¯¯(_)¯¯" | |
}, | |
{ | |
" ___/¯¯¯¯¯\\ ", | |
" \\__(o¯¯o)/\\" | |
}, | |
{ | |
" _________", | |
" \\-(_)---(_)/" | |
} | |
}; | |
void asignarVelocidades() | |
{ | |
for (int i = 0; i < numerocarros; ++i) | |
{ | |
int v; | |
bool repetido; | |
do { | |
v = rand() % 6; // ahora 0..5 | |
repetido = false; | |
for (int j = 0; j < i; j++) { | |
if (vel[j] == v) { // ¿está tomado? | |
repetido = true; | |
break; | |
} | |
} | |
} while (repetido); // repite hasta ser único | |
vel[i] = v; // guarda velocidad del auto i | |
} | |
} | |
void configurarVentana() { | |
Console::SetWindowSize(ANCHO, ALTO); | |
Console::CursorVisible = false; // con esto cambias la ventana ddf | |
} | |
void opciones() { | |
moverCursor(24, 17); cout << "[1] Carrera"; | |
moverCursor(38, 17); cout << "[2] Creditos"; | |
moverCursor(53, 17); cout << "[3] Salir"; | |
} | |
void nombreJuego() { | |
moverCursor(10, 5); cout << " ____ _ ____ ____ _____ ____ ___ ____ _ _ _____ ____"; | |
moverCursor(10, 6); cout << "/ ___| / \\ | _ \\ | _ \\| ____/ ___|_ _/ ___| \\ | | ____| _ \\."; | |
moverCursor(10, 7); cout << "| | / _ \\ | |_) | | | | | _ |\\___\\ | | | _| \\| | _| | |_) |"; | |
moverCursor(10, 8); cout << "| |___/ ___ \\| _ < | |_| | |___ ___) | | |_| | |\\ | |___| _ <"; | |
moverCursor(10, 9); cout << "\\____/_/ \\_\\_| \\_\\ |____/|_____|____/___\\____|_| \\_|_____|_| \\_\\."; | |
} | |
void creditos() { | |
Console::SetCursorPosition(10, 10); | |
cout << "Hecho por Andres Espejo, Piero Burgos y Fabio Silva"; | |
} | |
void asignarColores() | |
{ | |
for (int i = 0; i < numerocarros; i++) { | |
int paletacarros; | |
bool repetido; | |
do { | |
paletacarros = rand() % 6; // elige un color de 0..5 | |
repetido = false; | |
for (int j = 0; j < i; j++) { // ¿ya se usó? | |
if (color[j] == paleta[paletacarros]) { | |
repetido = true; | |
break; | |
} | |
} | |
} while (repetido); // repite hasta que no se repita | |
color[i] = paleta[paletacarros]; // guarda el color único | |
} | |
} | |
void dibujarAuto(int id, int x, int y, bool derecha) | |
{ | |
Console::ForegroundColor = color[id]; // color único | |
const char** linea = derecha ? carroDer[id] : carroIzq[id]; | |
for (int r = 0; r < carros_alto; ++r) { | |
moverCursor(x, y + r); | |
cout << linea[r]; | |
} | |
Console::ForegroundColor = ConsoleColor::Gray; | |
} | |
void colocarAutosInicio() { | |
/* límites personalizados – ajusta si lo deseas */ | |
int izq[6] = { 1, 16, 30, 1, 16, 31 }; | |
int der[6] = { 50, 63, 72, 50, 63, 72 }; | |
for (int id = 0; id < numerocarros; ++id) { | |
limIzq[id] = izq[id]; | |
limDer[id] = der[id]; | |
posX[id] = limIzq[id]; // arranca pegado al límite izq. | |
posY[id] = 2 + (id / 3) * (carros_alto + 2); | |
der[id] = true; | |
etapa[id] = 0; | |
dibujarAuto(id, posX[id], posY[id], true); | |
} | |
} | |
void borrarCarro(int id) { | |
for (int r = 0; r < carros_alto; r++) { | |
moverCursor(posX[id], posY[id] + r); | |
cout << string(carros_ancho, ' '); | |
} | |
} | |
void dibujarmeta(int x, int y) { | |
char b = 219; | |
Console::SetCursorPosition(x, y + 20); | |
cout << " " << b << " " << b << " " << b << endl; | |
cout << b << " " << b << " " << b << " " << endl; | |
cout << " " << b << " " << b << " " << b << endl; | |
cout << b << " " << b << " " << b << " " << endl; | |
cout << " " << b << " " << b << " " << b << endl; | |
cout << b << " " << b << " " << b << " " << endl; | |
cout << " " << b << " " << b << " " << b << endl; | |
cout << b << " " << b << " " << b << " " << endl; | |
cout << " " << b << " " << b << " " << b << endl; | |
cout << b << " " << b << " " << b << " " << endl; | |
cout << " " << b << " " << b << " " << b << endl; | |
cout << b << " " << b << " " << b << " " << endl; | |
cout << " " << b << " " << b << " " << b << endl; | |
} | |
void iniciarcarrera() {}; | |
void bucleCarrera() { | |
int frame = 0; | |
bool hayGanador = false; | |
while (!hayGanador) { | |
for (int id = 0; id < numerocarros; ++id) { | |
/* Avanza solo cada vel[id] frames */ | |
if (frame % paso[vel[id]] == 0) { | |
borrarCarro(id); | |
if (etapa[id] == 0) { | |
if (posX[id] < limDer[id]) { | |
++posX[id]; | |
der[id] = true; | |
} | |
else { | |
etapa[id] = 1; | |
} | |
} | |
else if (etapa[id] == 1) { | |
if (posY[id] < filaMeta[id]) ++posY[id]; | |
else etapa[id] = 2; | |
der[id] = false; | |
} | |
else { | |
if (posX[id] > metaFinalX) { | |
--posX[id]; | |
} | |
else { | |
wins[id]++; hayGanador = true; | |
moverCursor(0, ALTO - 2); | |
cout << "Ganador: Auto #" << id + 1; | |
} | |
} | |
dibujarAuto(id, posX[id], posY[id], der[id]); | |
} | |
} | |
Sleep(0); | |
++frame; | |
} | |
} | |
void ranking() {}; | |
void dibujarpista(int x, int y) { | |
char g = 238; | |
Console::SetCursorPosition(x, y + 10); | |
cout << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g; | |
Console::SetCursorPosition(x + 48, y + 10); | |
cout << "|"; | |
Console::SetCursorPosition(x + 48, y + 11); | |
cout << "|"; | |
Console::SetCursorPosition(x + 48, y + 12); | |
cout << "|"; | |
Console::SetCursorPosition(x + 48, y + 13); | |
cout << "|"; | |
Console::SetCursorPosition(x + 48, y + 14); | |
cout << "|"; | |
Console::SetCursorPosition(x + 48, y + 15); | |
cout << "|"; | |
Console::SetCursorPosition(x + 48, y + 16); | |
cout << "|"; | |
Console::SetCursorPosition(x + 48, y + 17); | |
cout << "|"; | |
Console::SetCursorPosition(x + 48, y + 18); | |
cout << "|"; | |
Console::SetCursorPosition(x, y + 19); | |
cout << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g << g; | |
} | |
void simulacion_carrera() { | |
dibujarpista(0, 0); | |
dibujarmeta(0, 0); | |
asignarColores(); | |
asignarVelocidades(); | |
colocarAutosInicio(); // pinta autos y pone límites | |
bucleCarrera(); // ← ¡ahora sí se mueven! | |
cout << "\nPulsa una tecla..."; | |
_getch(); | |
} | |
void inicio() { | |
Console::Clear(); | |
nombreJuego(); | |
opciones(); | |
int i = esperarTeclas({ '1', '2', '3' }); | |
if (i == 0) { | |
Console::Clear(); | |
simulacion_carrera(); | |
} | |
if (i == 1) { | |
Console::Clear(); | |
creditos(); | |
esperarTecla(27); | |
inicio(); | |
} | |
if (i == 2) { | |
std::exit(0); | |
} | |
} | |
struct NotaMusical { | |
unsigned int frecuencia_hz;// 0 es un silencio | |
unsigned int duracion_ms; | |
}; | |
const std::vector<NotaMusical> melodia = { | |
// Frase 1: Intro | |
{622, 75}, // D#5 | |
{0, 25}, | |
{698, 75}, // F5 | |
{0, 25}, | |
{784, 75}, // G5 | |
{0, 25}, | |
{932, 100},// A#5 | |
// Frase 2: Rapidez! | |
{880, 50}, // A5 | |
{784, 50}, // G5 | |
{698, 50}, // F5 | |
{0, 50}, | |
// Frase 3: Anticipacion | |
{587, 75}, // D5 | |
{0, 25}, | |
{698, 75}, // F5 | |
{0, 25}, | |
{784, 75}, // G5 | |
{0, 25}, | |
{880, 100},// A5 | |
// Frase 4: Resolucion que nos impulsa a reiniciar | |
{784, 50}, // G5 | |
{622, 50}, // D#5 | |
{523, 50}, // C5 | |
{0, 100} | |
}; | |
// Funcion que toca la melodia en bucle (bloquea el thread) | |
void tocarMelodiaEnBucle() { | |
while (true) { // Loopea indefinidamente | |
for (const auto& note : melodia) { | |
if (note.frecuencia_hz == 0) { // Descanzo | |
std::this_thread::sleep_for(std::chrono::milliseconds(note.duracion_ms)); | |
} | |
else { // It's a note | |
Beep(note.frecuencia_hz, note.duracion_ms); | |
} | |
} | |
} | |
} | |
/* ─── Programa principal ─── */ | |
int main() { | |
// toca musica | |
std::thread melodiaHilo(tocarMelodiaEnBucle); | |
melodiaHilo.detach();// no nos importa que este thread se cancele si main se cancela | |
srand(time(0)); | |
configurarVentana(); | |
Console::Clear(); | |
inicio(); | |
//moverCursor(0, ALTO - 1); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment