Mecanografi-eitor

Eduardo de Lorenzo Poza

Este es un programa de mecanografía (más o menos). Van cayendo palabras desde la parte de arriba de la pantalla y tienes que teclearlas antes de que alcancen la marca de la parte de abajo. No sé cómo funcionará en ordenadores más lentos porque en mi i7 va a tirones. Dependiendo de cuándo le des a la tecla, al programa le da la gana le da tiempo a pillar la tecla que has pulsado o no. Una lotería. Si por algún motivo alguien quisiera cambiar las palabras que salen, o hacer que haya más variedad (o menos), simplemente hay que añadir o quitar palabras al archivo lista.txt, cuidando que los índices de las palabras sean correlativos. Además hay que modificar un número en la función newPalabra. Hasta otra.

palabras.h

#ifndef PALABRAS_H_INCLUDED
#define PALABRAS_H_INCLUDED

#include <cstdio>
#include <cstdlib>
#include <windows.h>
#include <ctime>
#include <conio.h>

#define BLANCO 7
#define ROJO 0xC
#define VERDE 0xA

struct PALABRA
{
    int pos, stage;
    char text[20];
    int done;
    bool enCurso;
    bool fallada;
    PALABRA* sig;
    PALABRA* ant;
};

//Pivotes que están al principio y al final de la lista
PALABRA ini, fin;

PALABRA* newPalabra(FILE* f)
{
    PALABRA* temp;
    temp = new PALABRA;
    temp->pos = rand()%40;
    temp->stage = 0;

    //Elegimos una palabra aleatoria entre las del fichero
    int nPal = rand()%30;
    char read[20], seek[20];
    itoa(nPal, seek, 10);
    do {
        fscanf(f, "%s", read);
    } while (strcmp(read, seek));
    fscanf(f, "%s", read);
    strcpy(temp->text, read);
    rewind(f);

    temp->done = 0;
    temp->enCurso = false;
    temp->fallada = false;

    //Colocamos la nueva palabra entre el pivote final y la hasta ahora última palabra
    //La primera vez que ejecutamos la función fin.ant apunta a ini
    PALABRA* ult = fin.ant;
    temp->sig = &fin;
    temp->ant = ult;
    fin.ant = temp;
    ult->sig = temp;

    return temp;
}

int deletePalabra(PALABRA* p)
{
    p->ant->sig = p->sig; printf("\a");
    p->sig->ant = p->ant; printf("\a");
    delete p; printf("\a");
    return 0;
}

int printp(PALABRA* p)
{
    for (int i=0; i<p->pos; i++) printf(" ");
    if (p->fallada)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ROJO);
        printf("%s", p->text);
    } else {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), VERDE);
        for (int i=0; i<p->done && p->text[i]!='\0'; i++) printf("%c", p->text[i]);
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BLANCO);
        for (int i=p->done; p->text[i]!='\0'; i++) printf("%c", p->text[i]);
    }
    return 0;
}

int scrUpdate()
{
    system("CLS");

    int fila = 0;
    //Empezamos por la primera palabra a mostrar, que es la última generada
    PALABRA* p = fin.ant;
    //Mostramos todas las palabras que haya, cuando lleguemos a ini habremos acabado
    while (p != &ini)
    {
        for (int i=fila; i<p->stage; i++) printf("\n");
        fila = p->stage;
        printp(p);
        p = p->ant;
    }
    //Saltamos hasta la fila 12 y ahí escribimos el final del recorrido de las palabras
    for (int i=fila; i<13; i++) printf("\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BLANCO);
    printf("-----------------------------------------------------");

    return 0;
}

#endif // PALABRAS_H_INCLUDED

main.cpp

#include "palabras.h"

int main()
{
    srand(time(NULL));
    //Damos a ini y a fin los valores pertinentes
    ini.ant = NULL; ini.sig = &fin; ini.enCurso = false; ini.stage = 2;
    fin.ant = &ini; fin.sig = NULL; fin.enCurso = false;

    //Abrimos el fichero con las palabras
    FILE* lista = fopen("lista.txt", "r");

    //Declaramos los contadores
    int acertadas = 0, falladas = 0, perdidas = 0;

    //Comenzamos el cuentasegundos que regula las actualizaciones de la pantalla
    clock_t t = clock();
    time_t tiempo = time(NULL);
    char tecla = 0;

    //Presentamos el juego
    printf("\t\t\t----------------------------\n");
    printf("\t\t\t      MECANOGRAFIEITOR      \n");
    printf("\t\t\t----------------------------\n\n\n");
    printf("Tipica mecanografia. Acierta las palabras. Si fallas ya no puedes conseguir esa palabra.\n");
    printf("60 segundos, no more, no less, you don't have to guess. 60 is the magic number.\n");
    printf("En cualquier momento puedes pulsar la tecla ESC para abandonar el juego y ver el resultado.\n\n");
    system("PAUSE");

    //Ejecutamos el bucle mientras no se pulse la tecla ESC
    while (tecla != 27 && time(NULL) - tiempo <= 60)
    {
        //Generamos una palabra nueva cada vez que la última llega a la segunda fila
        if (fin.ant->stage>1)
        {
            newPalabra(lista);
            scrUpdate();
        }
        //Cada segundo las palabras bajan
        if (clock()-t > 500)
        {
            PALABRA* p = fin.ant;
            while (p != &ini)
            {
                p->stage++;
                p = p->ant;
            }
            t = clock();
            scrUpdate();
        }
        //Las palabras que tocan la barra de abajo son destruidas
        if (ini.sig->stage>12)
        {
            if (ini.sig->fallada == false) perdidas++;
            deletePalabra(ini.sig);
            scrUpdate();
        }
        //Detectamos las pulsaciones en el teclado
        if (kbhit())
        {
            tecla = getch();
            PALABRA* p = ini.sig;
            while (p != &fin)
            {
                if (p->enCurso) break;
                else p = p->sig;
            }
            if (!(p->enCurso)) p = ini.sig;
            while (p != &fin)
            {
                if (tecla == p->text[p->done])
                {
                    p->done++;
                    p->enCurso = true;
                    if (p->text[p->done] == '\0' && p->fallada == false) {deletePalabra(p); acertadas++;}
                    scrUpdate();
                    break;
                } else
                {
                    if (p->enCurso) {p->fallada = true; falladas++;}
                    p = p->sig;
                }
            }
        }
    }

    system("CLS");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BLANCO);
    printf("\t\t\t----------------------------\n");
    printf("\t\t\t         RESULTADOS         \n");
    printf("\t\t\t----------------------------\n\n\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), VERDE);
    printf("Acertadas:\t\t%d\n\n", acertadas);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ROJO);
    printf("Falladas:\t\t%d\n\n", falladas);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BLANCO);
    printf("Perdidas:\t\t%d\n\n", perdidas);

    //Liberamos toda la memoria
    PALABRA* borrar = ini.sig;
    while(borrar != &fin)
    {
        deletePalabra(borrar);
        borrar = ini.sig;
    }

    //Cerramos el fichero
    fclose(lista);

    return 0;
}

lista.txt

0 perro
1 casa
2 gato
3 coche
4 guiso
5 deseo
6 susurro
7 perplejo
8 ruta
9 perfume
10 nitrato
11 trabajo
12 mojigato
13 fecha
14 inicio
15 prosopopeya
16 nota
17 pata
18 fruta
19 bisel
20 lavadora
21 trama
22 usurero
23 distintivo
24 falso
25 ganador
26 menhir
27 azahar
28 horquilla
29 heno

Anuncios
Esta entrada fue publicada en Informática e Internet. Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s