Jacob wrote:

> James Cameron wrote:

>

>> Hi I'm developing a program and the client is worried about future

>> reuse of the code. Say 5, 10, 15 years down the road. This will be a

>> major factor in selecting the development language. Any comments on

>> past experience, research articles, comments on the matter would be

>> much appreciated. I suspect something like C would be the best based

>> on comments I received from the VB news group.

>

> NOTHING will run 10 years from now!
Ehm....

I have a lot of C programs that run perfectly

after more than 10 years!

E.g. see the following C programs that play Draughts

(Dama in italian) written on september 1989:

You can compile the original untouched C-source

(e.g. using gcc) and play it again immediately!

- Dario

#define linee_bianche (void)printf("\n\n");

#define odd(exp) ((exp)%2)

typedef int scacchiera[9][9];

struct mossa {

int a,b,a1,b1;

int valutatore;

};

static scacchiera s;

static

inizializza(s)

scacchiera s;

{

int r,c;

for (r=1; r<=8; r++)

for (c=1; c<=8; c++)

if (odd(r+c) || (r==4) || (r==5))

s[r][c] = 0;

else

{

if (r>=1 && r<=3)

s[r][c]= -1;

else

s[r][c] = 1;

}

}

static

read_2n(a,b)

int *a;

int *b;

{

char c;

*a = 0;

*b = 0;

do

if (1 != scanf("%c",&c))

c = '0';

while (c<'0' || c>'8');

*a = c-'0';

if (*a)

{

do

if (1 != scanf("%c",&c))

c = '0';

while (c<'0' || c>'8');

*b = c-'0';

if (*b == 0)

*a = 0;

}

}

static

posizione_in_scacchiera(r,c)

int r;

int c;

{

return (r >= 1) && (r <=

&& (c >= 1) && (c <=

;

}

static

muovi(s,r,c,r1,c1)

scacchiera s;

int r,c,r1,c1;

{

s[r1][c1] = s[r][c];

s[r][c] = 0;

if (abs(r1-r) == 2)

s[(r1+r)/2][(c1+c)/2] = 0;

if ( ((r1==1) && (s[r1][c1]== 1))

|| ((r1==

&& (s[r1][c1]==-1))

)

{

s[r1][c1] = s[r1][c1]*2;

(void)printf(" DAMA!\n");

}

}

static

leggi_mossa(s)

scacchiera s;

{

int casella_partenza_giusta;

int r,c;

int fine;

fine = 0;

casella_partenza_giusta = 0;

do

{

linee_bianche;

(void)printf(" DA? ");

read_2n(&r,&c);

if (posizione_in_scacchiera(r,c))

{

if (s[r][c] > 0)

leggi_posizione_arrivo(s,r,c,&casella_partenza_giu sta);

else

(void)printf(" POSIZIONE DI PARTENZA ERRATA.\n");

}

else

{

fine = 1;

linee_bianche;

(void)printf(" HAI ABBANDONATO E QUINDI HAI PERSO.\n");

}

}

while (!(casella_partenza_giusta || fine));

return fine;

}

static

leggi_posizione_arrivo(s,r,c,mossa_giusta)

scacchiera s;

int r,c;

int *mossa_giusta;

{

int r1,c1;

(void)printf(" A? ");

read_2n(&r1,&c1);

if (posizione_in_scacchiera(r1,c1))

{

if (mossa_corretta(s,r,c,r1,c1))

{

*mossa_giusta = 1;

muovi(s,r,c,r1,c1);

if (abs(r1-r) == 2)

leggi_altre_prese(s,r1,c1);

}

else

(void)printf(" MOSSA SCORRETTA.\n");

}

else

(void)printf(" RICOMINCIA DA CAPO.\n");

}

static

mossa_corretta(s,r,c,r1,c1)

scacchiera s;

int r,c,r1,c1;

{

int casella_arrivo_vuota, senso_giusto, presa_corretta;

int rr,cc;

casella_arrivo_vuota = s[r1][c1] == 0;

senso_giusto = (abs(r1-r)==abs(c1-c)) &&

(abs(s[r][c])==2 || (r1-r)*s[r][c] < 0);

rr = (r1+r)/2;

cc = (c1+c)/2;

if (abs(r1-r) == 2)

presa_corretta = (s[r][c]*s[rr][cc] < 0) &&

(abs(s[r][c]) >= abs(s[rr][cc]));

else

presa_corretta = abs(r1-r) == 1;

return casella_arrivo_vuota && senso_giusto && presa_corretta;

}

static

leggi_altre_prese(s,r,c)

scacchiera s;

int r,c;

{

int r1,c1;

do

{

(void)printf(" +A? ");

read_2n(&r1,&c1);

if (posizione_in_scacchiera(r1,c1))

{

if ((abs(r1-r)==2) && mossa_corretta(s,r,c,r1,c1))

{

muovi(s,r,c,r1,c1);

r = r1;

c = c1;

}

else

(void)printf(" PRESA SCORRETTA.\n");

}

}

while (posizione_in_scacchiera(r1,c1));

}

static

stampa_scacchiera(s)

scacchiera s;

{

int r,c;

linee_bianche;

(void)printf(" 1 2 3 4 5 6 7 8\n");

for (r=1; r<=8; r++)

{

(void)printf(" %1d ",r);

for (c=1; c<=8; c++)

switch (s[r][c])

{

case -2: (void)printf("DN"); break;

case -1: (void)printf("-N"); break;

case 0: if (odd(r+c))

(void)printf(" ");

else

(void)printf("--");

break;

case 1: (void)printf("-B"); break;

case 2: (void)printf("DB"); break;

}

(void)printf("\n");

}

}

static

elabora_mossa(s)

scacchiera s;

{

int r,c;

int fine;

struct mossa m;

fine = 0;

m.valutatore = -99;

for (r=1; r<=8; r++)

for (c=1; c<=8; c++)

if (s[r][c] < 0)

esamina_mossa(s,r,c,&m,0);

if (m.valutatore == -99)

{

fine = 1;

linee_bianche;

(void)printf(" HAI VINTO.\n");

}

else

{

/* (void)printf("%c",12); */

linee_bianche;

(void)printf(" DA %1d %1d\n",m.a,m.b);

do

{

(void)printf(" A %1d %1d\n",m.a1,m.b1);

muovi(s,m.a,m.b,m.a1,m.b1);

m.valutatore = -99;

if (abs(m.a1-m.a) == 2)

esamina_mossa(s,m.a1,m.b1,&m,1);

}

while(!( (m.valutatore == -99)

|| ( (m.valutatore <= 1

&& ( (m.a==1) || (m.a==

|| (m.b==1) || (m.b==

)

)

));

}

return fine;

}

static

esamina_mossa(s,r,c,m,mangia_solamente)

scacchiera s;

int r,c;

struct mossa *m;

int mangia_solamente;

{

int r1,c1,dr,dc;

for (dr= -1; dr<=1; dr++)

for (dc= -1; dc<=1; dc++)

if ((dr!=0) && (dc!=0) && ((s[r][c]==-2) || (dr==1)))

{

r1 = r+dr;

c1 = c+dc;

if (posizione_in_scacchiera(r1,c1))

{

if ((s[r1][c1] == 0) && ! mangia_solamente)

valuta_mossa(s,r,c,r1,c1,m);

else

if ( (s[r1][c1] > 0)

&& (abs(s[r][c])>=

abs(s[r1][c1]))

)

{

r1 += dr;

c1 += dc;

if

(posizione_in_scacchiera(r1,c1))

if (s[r1][c1] == 0)

valuta_mossa(s,r,c,r1,c1,m);

}

}

}

}

static

valuta_mossa(s,r,c,r1,c1,m)

scacchiera s;

int r,c;

int r1,c1;

struct mossa *m;

{

int dr,dc,v;

if (r1>r)

dr = 1;

else

dr = -1;

v = 0;

if (r==1)

{

if (s[r][c] == -1)

v-= 8;

else

v-= 1;

}

if (dr ==- 1)

v+= 1;

if (s[r][c] == -1)

v+= 2;

if ((r==

|| (r==1))

v+= 4;

if (s[r][c]==-1 && r1==

v+= 8;

if (abs(r1-r)==2)

v+= 20;

else

if (presa(s,r,c))

v+= 6;

for (dc= -1; dc<=1 ; dc++)

if (dc!=0 && posizione_in_scacchiera(r1+dr,c1+dc))

{

if (s[r1+dr][c1+dc]<0)

v+= 4;

else

if (s[r1+dr][c1+dc]>0 &&

possibile_presa(s,r,c,r1,c1,dr,dc))

v-= 8;

}

if (v > m->valutatore)

{

m->valutatore = v;

m->a = r;

m->b = c;

m->a1 = r1;

m->b1 = c1;

}

}

static

possibile_presa(s,r,c,r1,c1,dr,dc)

scacchiera s;

int r,c,r1,c1,dr,dc;

{

int cas_davanti_vuota;

int cas_dietro_occupata;

int avversario_temibile;

if (posizione_in_scacchiera(r1-dr,c1-dc))

{

cas_davanti_vuota = (s[r1-dr][c1-dc]==0) ||

(r1-dr==r) && (c1-dc==c) ||

(r1-2*dr==r) && (c1-2*dc==c);

avversario_temibile = s[r1+dr][c1+dc] >= -s[r][c];

cas_dietro_occupata = 1;

if (abs(r1-r)==2 && posizione_in_scacchiera(r1+2*dr,c1+2*dc))

cas_dietro_occupata = s[r1+2*dr][c1+2*dc] != 0;

return cas_davanti_vuota && cas_dietro_occupata &&

avversario_temibile;

}

else

return 0;

}

static

presa(s,r,c)

scacchiera s;

int r,c;

{

int dr,dc;

int p;

p = 0;

if ( (r>=2) && (r<=7) && (c>=2) && (c<=7) )

for (dr= -1; dr<=1; dr++)

for (dc= -1; dc<=1; dc++)

if ( (s[r+dr][c+dc] > 0)

&& (s[r-dr][c-dc] == 0)

)

p = p || (dr==1) || (s[r+dr][c+dc]==2);

return p;

}

static

help()

{

(void)printf("Dama (c) 1987 - Dario Dariol\n");

(void)printf("\n");

(void)printf("Il computer (nero) gioca contro l'avversario (bianco)\n");

(void)printf("adottando le regole della Dama italiana.\n");

(void)printf("L'unica eccezione e' che le prese NON sono obbligatorie\n");

(void)printf("\n");

(void)printf("Le mosse vengono comunicate scrivendo riga e colonna\n");

(void)printf("della casella da cui si muove o su cui si arriva.\n");

(void)printf("Uno 0 significa abbandono e/o mossa scorretta.\n");

(void)printf("\n");

}

main()

{

help();

inizializza(s);

while(1)

{

stampa_scacchiera(s);

if (leggi_mossa(s))

break;

if (elabora_mossa(s))

break;

}

}