Jacob said:
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 <= 8) && (c >= 1) && (c <= 8);
}
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==8) && (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_giusta);
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 <= 18)
&& ( (m.a==1) || (m.a==8) || (m.b==1) || (m.b==8) )
)
));
}
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==8) || (r==1))
v+= 4;
if (s[r][c]==-1 && r1==8)
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;
}
}