Program by měl fungovat i na ZX Spectrum všech verzí a s ním kompatibilních strojích jako Timex, Delta, Didaktik Gama, M a Kompakt, a asi stovce různých klonů vyráběných v SSSR.
Podle stejného vývojového diagramu jsem ho přepsal do FORTRANu, skutečného programovacího jazyka pro skutečné počítače, komu není jasné k čemu jsou ty kódy vpravo na konci řádků, ať si zkusí zakopnout s krabicí děrných štítků na schodech:
Kód: Vybrat vše
PROGRAM NIM MAIN01
INTEGER VYHER,POCET,MAXIM,ODBER MAIN02
LOGICAL KONEC MAIN03
CHARACTER*60 NAVOD(5) MAIN04
COMMON /UDAJE/VYHER,POCET,MAXIM,KONEC MAIN05
COMMON /TEXT/NAVOD MAIN06
CALL INICI MAIN07
C VYPIS NAVODU MAIN08
PRINT 600,(NAVOD(I),I=1,5) MAIN09
READ * MAIN10
C HRAJE CLOVEK MAIN11
1 CALL ZOBRAZ(POCET) MAIN12
IF (POCET.GT.1) GOTO 2 MAIN13
PRINT 100 MAIN14
CALL UKONC MAIN15
IF (KONEC) GOTO 9 MAIN16
GOTO 1 MAIN17
C DOTAZ NA ODBER MAIN18
2 PRINT 200,MAXIM MAIN19
READ 300,ODBER MAIN20
ODBER=INT(ODBER) MAIN21
IF (ODBER.LT.1.OR.ODBER.GT.MAXIM.OR.ODBER.GE.POCET) GOTO 2 MAIN22
POCET=POCET-ODBER MAIN23
C HRAJE POCITAC MAIN24
3 CALL ZOBRAZ(POCET) MAIN25
IF (POCET.GT.1) GOTO 4 MAIN26
PRINT 400 MAIN27
VYHER=VYHER+1 MAIN28
CALL UKONC MAIN29
IF (KONEC) GOTO 9 MAIN30
GOTO 3 MAIN31
C VYPOCET ODBERU MAIN32
4 ODBER=MOD(POCET-1,MAXIM+1) MAIN33
IF (ODBER.GT.0) GOTO 5 MAIN34
6 ODBER=MOD(NAHODA(),MAXIM)+1 MAIN35
IF (ODBER.GE.POCET) ODBER=POCET-1 MAIN36
IF (ODBER.LT.POCET) GOTO 5 MAIN37
GOTO 6 MAIN38
C PROVEDENI ODBERU MAIN39
5 PRINT 500,ODBER MAIN40
POCET=POCET-ODBER MAIN41
GOTO 1 MAIN42
100 FORMAT (16H VITEZI POCITAC!,/) MAIN43
200 FORMAT (16H MUZES VZIT 1 AZ,I2,15H, KOLIK BERES? ) MAIN44
300 FORMAT (I10) MAIN45
400 FORMAT (15H VITEZI CLOVEK!,/) MAIN46
500 FORMAT (13H POCITAC BERE,I2/) MAIN47
600 FORMAT (1A60) MAIN48
9 END MAIN49
C VYPIS VYSLEDKU A VOLBA POKRACOVANI NEBO UKONCENI UKONC01
SUBROUTINE UKONC UKONC02
INTEGER HER,VYHER,POCET,MAXIM UKONC03
LOGICAL KONEC UKONC04
CHARACTER VOLBA UKONC05
COMMON /UDAJE/VYHER,POCET,MAXIM,KONEC UKONC06
PRINT 100,HER,VYHER UKONC07
1 PRINT 200 UKONC08
READ 300,VOLBA UKONC09
IF (VOLBA.EQ.'A'.OR.VOLBA.EQ.'a') GOTO 2 UKONC10
IF (VOLBA.NE.'N'.AND.VOLBA.NE.'n') GOTO 1 UKONC11
KONEC=.TRUE. UKONC12
GOTO 2 UKONC13
C POCATECNI INICIALIZACE PROMENNYCH UKONC14
ENTRY INICI UKONC15
HER=0 UKONC16
VYHER=0 UKONC17
KONEC=.FALSE. UKONC18
C VYGENEROVANI NAHODNYCH HODNOT UKONC19
2 POCET=MOD(NAHODA(),6)*2+17 UKONC20
MAXIM=MOD(NAHODA(),4)+2 UKONC21
HER=HER+1 UKONC22
RETURN UKONC23
100 FORMAT (7H HER: ,I8/,7H VYHER:,I8) UKONC24
200 FORMAT (25H0CHCES POKRACOVAT? [A/N] ) UKONC25
300 FORMAT (A1) UKONC26
END UKONC27
C NAKRESLENI ZAPALEK NA STOLE ZOBRAZ01
SUBROUTINE ZOBRAZ(POC) ZOBRAZ02
INTEGER Q,POC,KON,ZAP ZOBRAZ03
CHARACTER RADEK(60) ZOBRAZ04
CHARACTER*2 KONCOVKA(3) ZOBRAZ05
DATA KONCOVKA/2HKA,2HKY,2HEK/ ZOBRAZ06
C HLAVICKY ZOBRAZ07
DO 10 ZAP=1,27 ZOBRAZ08
RADEK(ZAP*2)=' ' ZOBRAZ09
IF (ZAP.LE.POC) RADEK(ZAP*2)='0' ZOBRAZ10
10 CONTINUE ZOBRAZ11
PRINT 100,RADEK ZOBRAZ12
C DRIVKA ZOBRAZ13
DO 20 ZAP=1,27 ZOBRAZ14
RADEK(ZAP*2)=' ' ZOBRAZ15
IF (ZAP.LE.POC) RADEK(ZAP*2)='|' ZOBRAZ16
20 CONTINUE ZOBRAZ17
PRINT 100,((RADEK),I=1,3) ZOBRAZ18
C VYPOCET KONCOVKY ZOBRAZ19
IF (POC.GE.10.AND.POC.LE.20) GOTO 3 ZOBRAZ20
Q=MOD(POC,10) ZOBRAZ21
KON=2 ZOBRAZ22
IF (Q.EQ.1) KON=1 ZOBRAZ23
IF (Q.GT.4) KON=3 ZOBRAZ24
GOTO 2 ZOBRAZ25
3 KON=3 ZOBRAZ26
2 PRINT 200,POC,KONCOVKA(KON) ZOBRAZ27
RETURN ZOBRAZ28
100 FORMAT (60A1) ZOBRAZ29
200 FORMAT (14H0NA STOLE LEZI,I3,6H ZAPAL,A2,1H,) ZOBRAZ30
END ZOBRAZ31
C GENERATOR PSEUDONAHODNEHO CISLA NAHODA01
FUNCTION NAHODA() NAHODA02
INTEGER NAHODA,SEED NAHODA03
SAVE SEED NAHODA04
C INICIALIZACE SEEDU NAHODA05
IF (SEED.GT.0) GOTO 1 NAHODA06
CALL GETDAT(I,J,K) NAHODA07
SEED=I*365+J*12+K NAHODA08
CALL GETTIM(I,J,K,L) NAHODA09
SEED=MOD(SEED+I*3600+I*60+K,134456) NAHODA10
1 SEED=MOD(8121*SEED+28411,134456-1) NAHODA11
NAHODA=SEED NAHODA12
RETURN NAHODA13
END NAHODA14
C NAPLNENI NAVODU DATA01
BLOCK DATA DATA02
COMMON /TEXT/NAVOD DATA03
CHARACTER*60 NAVOD(5) DATA04
DATA NAVOD/ DATA05
1 27H FORTRAN NIM (C)2015 FARAON, DATA06
2 33H0HRU HRAJE CLOVEK PROTI POCITACI,, DATA07
3 53H STRIDAVE ODEBIRAJI ZAPALKY PODLE STANOVENEHO MAXIMA., DATA08
4 41H TEN, NA KOHO ZUSTANE POSLEDNI, PROHRAVA., DATA09
5 17H0STISKNI ENTER.../ DATA10
END DATA11
Program vyžaduje kompilátor Fortranu 77, kvůli jedinému příkazu, zbytek by zpracoval i FORTRAN 66, nebo vyspělejší verze FORTRANu IV. Po malých úpravách by ho měl přeložit jakýkoliv kompilátor od roku 1962 a spustit kterýkoliv sálový počítač nebo minipočítač!
A nakonec, opět podle stále stejného vývojového diagramu, přepis do C, což bylo trochu složitější, protože to už nedokáže některé lahůdkové věci, jako jsou například procedury s více vstupními body. Ale úpravy byly jen nepatrné:
Kód: Vybrat vše
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int her,vyher,pocet,maximum;
/* vygenerování náhodných hodnot */
void nahoda(void)
{
pocet=2*(rand()%6)+17;
maximum=rand()%4+2;
++her;
}
/* počáteční inicializace proměnných */
void inicializace(void)
{
her=vyher=0;
srand(time(NULL));
nahoda();
}
/* výpis výsledků a volba pokračování nebo ukončení */
int ukonceni(void)
{
char konec;
printf("\nHer:\t%d\nVýher:\t%d\nChceš hrát znovu? [A/N] ",her,vyher);
do {
while (!scanf("%1[aAnN]",&konec)) getchar();
if ('n'==konec||'N'==konec) return 1;
} while ('a'!=konec&&'A'!=konec);
nahoda();
return 0;
}
/* výpočet koncovky */
char *koncovka(n)
{
if (n<10||20<n)
{
if (1==(n%=10)) return "ka";
else if (n<5) return "ky";
}
return "ek";
}
/* nakreslení zápalek na stole */
void zobraz(void)
{
static int radek,sloupec;
putchar('\n');
for (radek=0;radek<5;++radek)
{
for (sloupec=0;sloupec<pocet;++sloupec)
printf("%c ",radek?'|':'O');
putchar('\n');
}
printf("\nNa stole leží %d zápal%s.\n",pocet,koncovka(pocet));
}
int main(void)
{
int odber;
inicializace();
/* výpis návodu */
printf("\n C NIM (C)2016 FARAON\n\n"
" Hru hraje člověk proti počítači,\n"
"střídavě odebírají zápalky podle stanoveného maxima.\n"
" Ten, na koho zůstane poslední, prohrává.\n\n"
" Stiskni Enter...");
getchar();
/* hlavní cyklus */
for (;;)
{
/* hraje člověk */
zobraz();
if (pocet>1)
{
do {
/* dotaz na odběr */
printf("Můžeš vzít 1 až %d, kolik bereš? ",maximum<pocet?maximum:pocet-1);
while (!scanf("%d",&odber)) getchar();
} while (odber<1||odber>maximum||odber>=pocet);
pocet-=odber;
loop:
zobraz();
/* hraje počítač */
if (pocet>1)
{
/* výpočet odběru */
odber=(pocet-1)%(maximum+1);
if (!odber) do odber=(rand()%maximum)+1; while (odber>=pocet);
printf("Počítač bere %d\n",odber);
pocet-=odber;
}
else
{
printf("Vítězí člověk!\n");
++vyher;
if (ukonceni()) break;
goto loop;
}
}
else
{
printf("Vítězí počítač!\n");
if (ukonceni()) break;
}
}
return 0;
}
Kdyby se našel kdokoliv, kdo bude chtít ukázat svoje řešení, může se stále přidat, hra je otevřená každému kdo si chce hrát