mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-05 06:00:33 -04:00
424 lines
10 KiB
C
424 lines
10 KiB
C
//Toto je pokus programu pro sklonovani jmen.
|
||
//Umi vysklonovat jen jmena z rodu muzskeho zivotneho a zenskeho.
|
||
//vse v cisle jednotnem.
|
||
//Hodi se do ceskych her pro oslovovani hracu.
|
||
|
||
|
||
//Padovani probiha tak:
|
||
/*
|
||
Ke jmenu je treba znat rod: Muzsky/ Zensky
|
||
|
||
Pak podle rodu se hleda ve vzorech pro muzky nebo zesky rod:
|
||
Nejprve se porovnaji dva posledni znaky jmeno s mapou znaku u zkoumaneho
|
||
vzoru. Pokud tyto znaky souhlasi, muze byt jmeno vysklonovano.
|
||
Pri sklonovani se neprve z koncovky odebere urcity, nebo zadny pocet znaku.
|
||
Potom se pripadne upravi konverze dlouheho 'u' s krouzkem na 'o' "Kun"=>"kone".
|
||
Nasledne se pripoji koncovka a nakonec se provede kontrola na znak e pred
|
||
souhlaskou, ktere je nutne vypustit: Marek => Marka.
|
||
Pri sklonovani muzou ale vzniknout chybne dvojznakove spojeni: treba znak 'n'
|
||
s hackem a 'e'. Tyto dvojice jsou vyhledany a nahrazeny dvojici spravnou,
|
||
v nasem pripade 'n' a 'e' s hackem.
|
||
|
||
Ja jen doufam ze tyto upravy maj obecny charakter :-)
|
||
Da se prepokladat ze ve svete existuje plno jmen, ktere nelze takto sklonovat.
|
||
U nekterych ani neni jasny jak tato jmena sklonovat. Treba
|
||
Bredy, Bredyho, Bredymu, Bredy, Bredy, Bredym, Bredym - Co je to za vzor ???
|
||
Uz nemluvim o jmenach cizich.
|
||
*/
|
||
|
||
//Definice knihoven
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
#include <malloc.h>
|
||
|
||
typedef char TPAD[8];
|
||
//typ TPAD predstavuje koncovku pro jeden pad
|
||
|
||
typedef char TZNAKY[40];
|
||
//typ TZNAKY predstavuje mapu znaku se kterymi vzor pracuje.
|
||
//pokud je na prvnim miste znak '*' tak vzor pracuje se vsemy.
|
||
|
||
typedef struct vzor
|
||
{
|
||
TZNAKY znak1;
|
||
TZNAKY znak2;
|
||
char chrdel;
|
||
TPAD pady[7];
|
||
}TVZOR;
|
||
//struktura TVZOR popisuje sklonovani jednoho vzoru
|
||
//znak1 predstavuje mapu znaku pro jmeno v prvnim pade na predposledni pozici
|
||
// ... pokud znak neni v mape, nelze jmeno v tomto vzoru sklonovat
|
||
//znak2 je jako znak1 s tim ze se testuje znak na posledni pozici
|
||
//chrdel je pocet znaku, ktere musi byt odebrany pred pridanim pripony.
|
||
//navic pokud je chrdel=0 uplatnuje se konverze Kun -> kone a podobne.
|
||
//pady predstavuje jednotlive koncovky pro pady
|
||
// pokud je pad roven '-' znamena to ze tvar je schodny jako v 1. pade.
|
||
|
||
TVZOR zena=
|
||
{
|
||
"hkrdtnbflmpsvz",
|
||
"a<EFBFBD>o<EFBFBD>u<EFBFBD><EFBFBD>y<EFBFBD>",
|
||
1,
|
||
"-","y","<EFBFBD>","u","o","<EFBFBD>","ou"
|
||
};
|
||
//Vzor pro zena
|
||
|
||
TVZOR natasa=
|
||
{
|
||
"c<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||
"a<EFBFBD>",
|
||
1,
|
||
"-","i","<EFBFBD>","u","o","<EFBFBD>","ou"
|
||
};
|
||
//Vzor pro zena koncici mekkou souhlaskou a a
|
||
|
||
TVZOR ruze=
|
||
{
|
||
"c<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||
"e<EFBFBD>i<EFBFBD>o<EFBFBD>u<EFBFBD><EFBFBD>",
|
||
1,
|
||
"-","e","i","i","e","i","<EFBFBD>"
|
||
};
|
||
//Vzor pro ruze s mekkou koncovkou
|
||
|
||
TVZOR ruze2=
|
||
{
|
||
"dtn",
|
||
"i<EFBFBD><EFBFBD>",
|
||
1,
|
||
"-","e","i","i","e","i","<EFBFBD>"
|
||
};
|
||
//Vzor pro ruze s tvrdou koncovkou d,t,n s mekkou samohlaskou
|
||
|
||
|
||
TVZOR pisen=
|
||
{
|
||
"*",
|
||
"c<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>flmsx",
|
||
0,
|
||
"-","e","i","-","i","i","<EFBFBD>"
|
||
};
|
||
//vzor pisen
|
||
|
||
TVZOR kost=
|
||
{
|
||
"*",
|
||
"hkrdtnbpvz",
|
||
0,
|
||
"-","i","i","-","i","i","<EFBFBD>"
|
||
};
|
||
//vzor kost
|
||
|
||
TVZOR pan=
|
||
{
|
||
"*",
|
||
"rdtnbflmpsvz",
|
||
0,
|
||
"-","a","ovi","a","e","ovi","em"
|
||
};
|
||
//vzor pan standardni
|
||
|
||
TVZOR pan2=
|
||
{
|
||
"*",
|
||
"hk",
|
||
0,
|
||
"-","a","ovi","a","u","ovi","em"
|
||
};
|
||
//vzor pan pro specialni koncovky h nebo k => pro 5. pad
|
||
// Rumburak => Rumburaku / nikoliv Rumburake.
|
||
|
||
|
||
TVZOR quasimodo=
|
||
{
|
||
"hkrdtnbflmpsvz",
|
||
"o",
|
||
1,
|
||
"o","a","ovi","a","o","ovi","em"
|
||
};
|
||
//vzor quasimodo resici pripad koncovky '-odo'.
|
||
//Odo, oda, odovi, oda, odo, odovi, odem
|
||
|
||
TVZOR pritel=
|
||
{
|
||
"e<EFBFBD>",
|
||
"c<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bflmpsvz",
|
||
0,
|
||
"-","e","i","e","i","i","em"
|
||
};
|
||
//vzor pritel pro vzor muz pro obojetne souhlasky ze samohlaskou e, <20>
|
||
|
||
TVZOR muz=
|
||
{
|
||
"*",
|
||
"c<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||
0,
|
||
"-","e","i","e","i","i","em"
|
||
};
|
||
//vzor muz
|
||
|
||
TVZOR fenix=
|
||
{
|
||
"*",
|
||
"x",
|
||
0,
|
||
"-","e","ovi","e","i","ovi","em"
|
||
};
|
||
//vzor pro jmena koncici -x
|
||
|
||
|
||
|
||
TVZOR predseda=
|
||
{
|
||
"hkrdtnbpvz",
|
||
"a<EFBFBD>o<EFBFBD>u<EFBFBD><EFBFBD>y<EFBFBD>",
|
||
1,
|
||
"a","y","ovi","u","o","ovi","ou"
|
||
};
|
||
//vzor predseda
|
||
|
||
|
||
TVZOR soudce=
|
||
{
|
||
"c<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>flmsx",
|
||
"e<EFBFBD>i<EFBFBD>o<EFBFBD>u<EFBFBD><EFBFBD>",
|
||
1,
|
||
"e","e","i","e","e","i","em"
|
||
};
|
||
//vzor soudce
|
||
|
||
|
||
TVZOR soudce2=
|
||
{
|
||
"dtn",
|
||
"<EFBFBD>i<EFBFBD>",
|
||
1,
|
||
"e","e","i","e","e","i","em"
|
||
};
|
||
//vzor soudce pro tvrdou koncovku s mekkou samohlaskou -di -ti -ni
|
||
//-de -te -ne.
|
||
|
||
//Nasledujici funkce vraci 1 pokud jmeno muze byt sklonovano vzorem vz
|
||
char test_vzor(TVZOR *vz,char *jmeno)
|
||
{
|
||
char *end;
|
||
char testchar;
|
||
|
||
end=strchr(jmeno,0)-2;
|
||
testchar=end[0];
|
||
if (vz->znak1[0]!='*' && strchr(vz->znak1,testchar)==NULL) return 0;
|
||
testchar=end[1];
|
||
if (vz->znak2[0]!='*' && strchr(vz->znak2,testchar)==NULL) return 0;
|
||
return 1;
|
||
}
|
||
|
||
//tato funkce se vola p<>ed odejmut<75>m ur<75>it<69>ho znaku.
|
||
//Pokud to toti<74> je zm<7A>k<EFBFBD>ovac<61> samohl<68>ska, mus<75> se p<><70>padn<64> d,t,n
|
||
//zm<7A>k<EFBFBD>it p<>ed touto samohl<68>skou.
|
||
void odejmi_znak(char *znak)
|
||
{
|
||
if (znak[0]=='<EFBFBD>' || znak[0]=='<EFBFBD>' || znak[0]=='i')
|
||
switch (znak[-1])
|
||
{
|
||
case 'd': znak[-1]='<EFBFBD>';break;
|
||
case 't': znak[-1]='<EFBFBD>';break;
|
||
case 'n': znak[-1]='<EFBFBD>';break;
|
||
}
|
||
}
|
||
|
||
//Tato funkce upravuje nektere pady jen maji predpredposledni samohlasku e
|
||
//Marek => Marka
|
||
//Pisen => Pisne
|
||
//Zdenek => Zdenka
|
||
void uprav_e_nakonci(char *konec)
|
||
{
|
||
char samohlasky[]="a<EFBFBD>e<EFBFBD>i<EFBFBD>o<EFBFBD>u<EFBFBD>y<EFBFBD>";
|
||
char pismena[]="flmn<EFBFBD>r<EFBFBD>s<EFBFBD>xpv";
|
||
char *c;
|
||
|
||
c=konec-2;
|
||
if (strchr(samohlasky,c[2])!=NULL && strchr(samohlasky,c[1])==NULL && strchr(pismena,c[-1])!=NULL)
|
||
if (c[0] =='e'|| c[0]=='<EFBFBD>'|| c[0] =='<EFBFBD>')
|
||
{
|
||
odejmi_znak(c);
|
||
strcpy(c,c+1);
|
||
}
|
||
}
|
||
|
||
|
||
//Naplni buffer spravnym padem jmena podle vzoru vz
|
||
//paduje se od 0 => 1. pad
|
||
void ziskej_pad(char *buffer,char *jmeno,TVZOR *vz,char pad)
|
||
{
|
||
char *end;
|
||
strcpy(buffer,jmeno);
|
||
if (vz->pady[pad][0]=='-') return;
|
||
end=strchr(buffer,0)-vz->chrdel;
|
||
odejmi_znak(end); //odejme znak, pokud je => znak 0 neni znak cesky.
|
||
strcpy(end,vz->pady[pad]);
|
||
if (pad && !vz->chrdel && end[-2]=='<EFBFBD>') end[-2]='o';
|
||
uprav_e_nakonci(end);
|
||
return;
|
||
}
|
||
|
||
|
||
//Tato funkce upravi nektere specialni dvojice znaku do spravne podoby
|
||
//prvni sloupec je puvodni dvojice, druhy sloupec je nova dvojice
|
||
void uprav_dvojice(char *jmeno)
|
||
{
|
||
static char *dvojice[]=
|
||
{
|
||
"<EFBFBD>e","d<EFBFBD>",
|
||
"<EFBFBD>e","t<EFBFBD>",
|
||
"<EFBFBD>e","n<EFBFBD>",
|
||
"<EFBFBD>i","di",
|
||
"<EFBFBD>i","ti",
|
||
"<EFBFBD>i","ni",
|
||
"<EFBFBD><EFBFBD>","d<EFBFBD>",
|
||
"<EFBFBD><EFBFBD>","t<EFBFBD>",
|
||
"<EFBFBD><EFBFBD>","n<EFBFBD>",
|
||
"r<EFBFBD>","<EFBFBD>e",
|
||
"s<EFBFBD>","<EFBFBD>e",
|
||
"c<EFBFBD>","<EFBFBD>e",
|
||
"k<EFBFBD>","ce",
|
||
"<EFBFBD><EFBFBD>","<EFBFBD>e",
|
||
"<EFBFBD><EFBFBD>","<EFBFBD>e",
|
||
"<EFBFBD><EFBFBD>","<EFBFBD>e",
|
||
"<EFBFBD><EFBFBD>","<EFBFBD>e",
|
||
};
|
||
|
||
while (*jmeno)
|
||
{
|
||
int i;
|
||
for(i=0;i<sizeof(dvojice)/sizeof(char *);i+=2)
|
||
{
|
||
if (!strncmp(jmeno,dvojice[i],2))
|
||
{
|
||
strcopy_n(jmeno,dvojice[i+1],2);
|
||
break;
|
||
}
|
||
}
|
||
jmeno++;
|
||
}
|
||
}
|
||
|
||
//Pole padovych predlozek
|
||
char *jmena_padu[]=
|
||
{
|
||
"kdo",
|
||
"bez",
|
||
"k",
|
||
"vid<EFBFBD>m",
|
||
"vol<EFBFBD>m",
|
||
"o",
|
||
"s"
|
||
};
|
||
|
||
//Tato funkce zobrazi vypadovane jmeno
|
||
void show_table(char *jmeno,TVZOR *vz,char tabnum)
|
||
{
|
||
int i;
|
||
char *buff;
|
||
|
||
buff=alloca(strlen(jmeno)+20);
|
||
printf("%d. mo<6D>nost\n\n",tabnum);
|
||
for(i=0;i<7;i++)
|
||
{
|
||
if (i)
|
||
{
|
||
ziskej_pad(buff,jmeno,vz,i);
|
||
uprav_e_nakonci(buff);
|
||
}
|
||
else strcpy(buff,jmeno);
|
||
uprav_dvojice(buff);
|
||
printf(" %d. %-6s %s\n",i+1,jmena_padu[i],buff);
|
||
}
|
||
printf("**** Kl<4B>vesu ****\n");
|
||
getche();
|
||
}
|
||
|
||
//Tato funkce vypise celkovy vysledek.
|
||
void notabs(int i)
|
||
{
|
||
if (i) printf("Program na<6E>el %d mo<6D>most%s.\n",i,(i!=1?(i>1 && i<5?"i":"<EFBFBD>"):""));
|
||
else printf("Program bohu<68>el nena<6E>el <20><>dnou mo<6D>nost jak sklo<6C>ovat toto jm<6A>no.\n");
|
||
puts("-------------------------------------------------------------------------");
|
||
}
|
||
|
||
//Tato funkce zobrazi vsechny moznosti padovani pro rod zensky
|
||
void hledej_zena(char *jmeno)
|
||
{
|
||
int tabnum=0;
|
||
|
||
if (test_vzor(&zena,jmeno)) show_table(jmeno,&zena,++tabnum);
|
||
if (test_vzor(&natasa,jmeno)) show_table(jmeno,&natasa,++tabnum);
|
||
if (test_vzor(&ruze,jmeno)) show_table(jmeno,&ruze,++tabnum);
|
||
if (test_vzor(&ruze2,jmeno)) show_table(jmeno,&ruze2,++tabnum);
|
||
if (test_vzor(&pisen,jmeno)) show_table(jmeno,&pisen,++tabnum);
|
||
if (test_vzor(&kost,jmeno)) show_table(jmeno,&kost,++tabnum);
|
||
notabs(tabnum);
|
||
}
|
||
|
||
//Tato funkce zobrazi vsechny moznosti padovani pro rod muzsky
|
||
void hledej_muz(char *jmeno)
|
||
{
|
||
int tabnum=0;
|
||
|
||
if (test_vzor(&pritel,jmeno)) show_table(jmeno,&pritel,++tabnum);
|
||
if (test_vzor(&pan,jmeno)) show_table(jmeno,&pan,++tabnum);
|
||
if (test_vzor(&pan2,jmeno)) show_table(jmeno,&pan2,++tabnum);
|
||
if (test_vzor(&muz,jmeno)) show_table(jmeno,&muz,++tabnum);
|
||
if (test_vzor(&quasimodo,jmeno)) show_table(jmeno,&quasimodo,++tabnum);
|
||
if (test_vzor(&predseda,jmeno)) show_table(jmeno,&predseda,++tabnum);
|
||
if (test_vzor(&soudce,jmeno)) show_table(jmeno,&soudce,++tabnum);
|
||
if (test_vzor(&soudce2,jmeno)) show_table(jmeno,&soudce2,++tabnum);
|
||
if (test_vzor(&fenix,jmeno)) show_table(jmeno,&fenix,++tabnum);
|
||
notabs(tabnum);
|
||
}
|
||
|
||
//Hlavni cast programu
|
||
void hlavni()
|
||
{
|
||
char jmeno[51];
|
||
char pohlavi;
|
||
do
|
||
{
|
||
printf("Zadej jm<6A>no. Vy<56>aduje se min 3 znaky v <20>e<EFBFBD>tin<69> kodu kamenick<63>ch \n");
|
||
printf("Jm<EFBFBD>no nesm<73> m<>t v<>c ne<6E> 50 znak<61>, a nesm<73> obsahovat mezery:\n");
|
||
printf("Pi<EFBFBD> mal<61>mi p<>smeny, pouze prvn<76> pismeno m<><6D>e b<>t velk<6C>:\n");
|
||
printf("(pouh<75> 'x' je odchod z programu)\n");
|
||
jmeno_chyba:
|
||
gets(jmeno);
|
||
if (jmeno[0]=='x' && jmeno[1]==0) return;
|
||
if (strlen(jmeno)<3)
|
||
{
|
||
printf("Jm<EFBFBD>no mus<75> b<>t min 3 znaky dlouh<75>\n");
|
||
goto jmeno_chyba;
|
||
}
|
||
chyba:
|
||
printf("Jsi mu<6D> nebo <20>ena? (M/Z nebo M/F nebo X):");
|
||
pohlavi=getchar();
|
||
while (getchar()!='\n');
|
||
puts("");
|
||
pohlavi=toupper(pohlavi);
|
||
if (pohlavi=='X') return;
|
||
if (pohlavi=='M') hledej_muz(jmeno);
|
||
else if (pohlavi=='F' || pohlavi=='Z') hledej_zena(jmeno);
|
||
else goto chyba;
|
||
}
|
||
while (1);
|
||
}
|
||
|
||
main()
|
||
{
|
||
hlavni();
|
||
puts("");
|
||
puts("Pokud jsi objevil p<>irozen<65> jm<6A>no (tj re<72>ln<6C> jm<6A>no), kter<65> program\n"
|
||
"nedok<EFBFBD>zal vysklo<6C>ovat, po<70>li mi jeho zn<7A>n<EFBFBD> na adresu:\n"
|
||
"xnovako1@cs.felk.cvut.cz\n");
|
||
puts("Verze Latin2 se p<>ipravuje...\n"
|
||
"O slovensk<73> verzi se zat<61>m neuva<76>uje...\n");
|
||
puts("Napsal: Ond<6E>ej Nov<6F>k za 2 a p<>l hodiny ve WATCOM C\n"
|
||
"Zdroj<EFBFBD>ky maj<61> povahu PUBLIC DOMAIN\n");
|
||
}
|