Dieses Spiel wird in einer senkrechten Ebene von 7 horizontalen und 6 vertikalen Feldern gespielt. Die Spieler setzen abwechselnd einen Stein auf eine bestimmte Spalte. Der Stein fÀllt daraufhin auf das tiefste unbesetzte Feld herunter. Derjenige Spieler, dem es gelingt, zuerst vier Steine horizontal, vertikal oder diagonal miteinandern zu verbinden, hat gewonnen.
In dieser Programmversion tritt der Rechner als Spielpartner an. Der Dialog zwischen Spieler und ATARI findet ĂŒber die Titelzeile des Spielfensters, dessen Infozeile und die Maus statt. In der oberen rechten Bildschirmecke wird die Echtzeituhr samt Datumsangabe angezeigt. Es empfiehlt sich daher, dieselbe vor dem Laden des Programms einzustellen. WĂ€hrend der Bedenkzeit des Computers wird diese Ausgabe nicht aktualisiert, um die Zugzeiten kurz zu halten. Rechts neben dem Spielfeld werden die Bedenkzeiten des Spielers und des Rechners und die aktuelle Spielstufe angezeigt. Das Programm ist vollstĂ€ndig in âC" geschrieben.
Bedient wird das Programm ausschlieĂlich mit der Maus. Folgende Funktionen stehen durch einfaches Anklicken zur VerfĂŒgung:
- Auswahl der zu besetzenden Spalte
- Beginn eines neuen Spielers
- stufenlose paarweise ZugrĂŒcknahme
- erhöhen der SpielstÀrke
- verringern der SpielstÀrke
- Abbruch des Programms mit Sicherheitsabfrage; nur wenn die Taste âjâ gedrĂŒckt wird, bricht das Programm ab
Es stehen fĂŒnf verschiedene SpielstĂ€rken (1 bis 5) zur VerfĂŒgung, wovon 1 die leichteste ist. Die Zugzeiten zu Spielbeginn differieren erheblich. Sie liegen zwischen einer und 400 Sekunden. Mit abnehmender Anzahl der noch zu besetzenden Spalten allerdings, nimmt die Zugzeit des Rechners erheblich ab.
Zu Beginn des Programmes werden sĂ€mtliche Variablen global definiert. Es werden die Typen âshortâ (16 Bit), âintâ (32 Bit) und âcharâ (8 Bit) verwendet.
Nachstehend folgt eine ErlÀuterung der Aufgaben einzelner Funktionen:
main
Initialisierung von VDI, AES und einem Window; Hauptschleife fĂŒr sĂ€mtliche Programmfunktionen.
nowinner
Unentschiedenes Spielende,
playerwins
Spielende bei Sieg des Spielers,
atariwins
Spielende bei Sieg des Rechners,
init
Initialisieren des Spielfeldes, der Zugzeitvariablen, etc; Ausgabe des Spielfeldes
entry
Ăberwachen der Maus; Aufruf der entsprechenden Routinen bei Auswahl einer Funktion.
depth
Ermitteln der ersten freien Zeilenposition innerhalb einer angewÀhlten Spalte.
display
Ausgabe eines durchgefĂŒhrten Zuges,
points
Ermitteln der Nachbarspielsteine fĂŒr einen vom Computer geprĂŒften Zug.
sub1500
Erhöhen der Bewertungspunktzahl in AbhÀngigkeit von der Anzahl der eigenen Nachbarspielsteine.
computer
Hauptroutine fĂŒr den Rechnerzug; entweder wird der allererste Zug zufĂ€llig ausgewĂ€hlt, oder aber die rekursive Funktion rekursion aufgerufen.
rekursion
Ermitteln des besten Zuges auf der Basis einer Zugtiefenschachtelung mit Punktebewertung
print___items
Ausgabe der anwÀhlbaren Funktionen im Window.
get___time
Holen der aktuellen Uhrzeit und Umwandlung in sec.
show____time
Anzeigen der spielerspezifischen Bedenkzeit.
print___max
Ausgabe der Spielstufe.
test
Ermittlung der Anzahl noch besetzbarer Spalten.
show____date
Ausgabe der Echtzeituhr mit Tagesdatum.
abbruch
Sicherheitsabfrage bei Auswahl der Abbruch-Funktion.
short 1,j,x,y,handle1,handle2,key,ar[72],move,xpos,ypos,buttons,index,
pu,w,xx,yy,player,zw,bp,bz,zu,pl,x1,x2,y1,y2,b2,p2,style,myexit,
leer,tmax,tt,fr[91,wr191.Cornerst 41,xr[0],yr[10],br[10],pr[10],
zuege[501;
int dummy,window,work_in[12],work_out[57],datevec[7],time,start,
time_player,time_atari,timebuf;
char buf[20],buf1[20],datum[50];
main()
{ appl_init();
for (j=0; j<10; work_in[j++] = 1); work_int[10] = 2;
handle1=graf_handle(&dummy,&dummy, fitdummy,&dummy);
v_opnvwk(work_in,&handle1,work_out);
v_clrwk(handle1);
window=g_open(1,640,400,"Ihr Zug"," ");
g_window(window,0,0,640,400);
g_reopenCwindow);
handle2=g_vdihandle(window);
dummy=vst_color(handle1,1); dummy=vst_effects(handle 1,4);
v_gtext(handle1,1, 15, "von P.M. & A.Q. (C)1986");
dummy=vst_effects(handle 1,0); print_items();
dummy=graf_mouse(3,&dummy);
do
{ init();
do { test(); if (leer==0) { nowinner(); continue; }
entry();
if (myexit==0)
{ if (pu>=100) { playerwins(); continue; }
test(); if (leer==0) { nowinner(); continue; }
player=1; computer(); player=1; index=bz; depth();
display(); points();
if (pu>=100) { atariwins(); }
}
}
while(myexit==0);
}
while(myexit==1);
dummy=graf_mouse(0,&dummy);
g_exit();
v_clsvwk(handle1);
appl_exit();
}
nowinner()
{ g_info(window, "Sie haben Glck. Das Spiel endet unentschieden.");
myexit=1; g_title(window,"Spielende, bitte Mausknopf drcken!");
do { show_date(); vq_mouse(handle2,&buttons,&xpos,&ypos); } while(buttons==0);
}
playerwins()
{ g_info(window,"Welch bses Schicksal. Sie haben zufllig gewonnen!");
myexit=1; g_title(window,"Spielende, bitte Mausknopf drcken!");
do { show_date(); vq_mouse(handle2,&buttons,&xpos,&ypos); } while(buttons==0);
}
atariwins()
{ g_info(window,"Es tut mir fast leid: SIE HABEN VERLOREN!");
myexit=1; g_title(window,"Spielende, bitte Kausknopf drcken");
do { show_date(); vq_mouse(handle2,&buttons,&xpos,&ypos); } while(buttons==0)
}
init()
{ myexit=0; time_player=0; time_atari=0; tmax=2; zu=0;
g_Info(window," ");
for (i=0; i<72; ar[i++]=99);
for (i = 10; i<=55; i+=9) { for (j=0; j<7; ar[i+j++]=0); }
dummy=vsf_color(handle2,1); dummy=vsf_interior(handle2,2);
vsf_perimeter(handle2,1); dummy=vsf_style(handle2,1);
for (y=1; y<7; y++)
{ for (x=1; x<8; x++)
{ corners[0]=100+x*45; corners[1]=y*45;
corners[2]=corners[0]+40; corners[3]=corners[1]+40;
g_rfbox(window,corners);
}
}
dummy=vsf_interior(handle2, 2) ; print_max();
player=1; show_time(); player= -1; show tlmeO;
}
entry()
{ player= -1; move = -1; v_show_c(handle2,0);
get_time(); start=time;
do
{ g_title(window,"Ihr Zug?");
do { show_date(); vq_mouse(handle2,&buttons,&xpos,&ypos); } while(buttons==0);
if (xpos>11 && xpos<113)
{ if (ypos>353 && ypos<375) { abbruch() continue; }
if (ypos>233 && ypos<255) { myexit=1; continue; }
if (ypos>293 && ypos<315 && tmax<6) {tmax++; print_max(); continue; }
if (ypos>323 && ypos<345 && tmax>2) {tmax-â; print_max(); continue; }
if (ypos>263 && ypos<285 && zu>0)
{ dummy=vsf_style(handle2,1);
for (i=0; i<2; i++)
{ zu--; index=zuege[zu]; depth();
if (move<0) move=1» else move++; ar[move*9+index]=0;
corners[0]=100+index*45; corners[1]=move*45;
corners[2]=corners[0]+40; corners[3]=corners[1]+40;
g_rfbox(window,corners);
}
do { vq_mouse(handle2,&buttons,&xpos,&ypos); } while(buttons!=0);
move= -1;
}
}
if (xpos>144 && xpos<460 && ypos>60) { index=(xpos-100)/45; depth(); }
}
while(move<0 && myexit==0);
v_hide_c(handle2); zuege[zu]=index; zu++;
get_time(); time_player+=time-start; show_time();
if (myexit ==0) { display(); points(); }
}
depth()
{ move= -1;
for (y=7; y>0; yâ) {
if (ar[y*9+index]==0) { move=y; break) }}
display()
{ ar[move*9+index]=player;
if (player<0)
style = 4; else style=8; dummy=vsf_style(handle2,style);
y=1; corners[0]=100+index*45; corners[1]=y*45;
corners[2]=corners[0]+40; corners[3]=corners[1]+40;
g_rfbox(window,corners);
while(y<move)
{ delay(3); y + + ; dummy = vsf_style(handle2,1);
corners[1]=(y-1)*45; corners[3]=corners[1]+40;
g_rfbox(window,corners); dummy=vsf_style(handle2,style);
corners[1]=y*45; corners[3]=corners[1]+40;
g_rfbox(window,corners);
}
for (i=0; i<3; i++)
{ delay(10); dummy=vsf_style(handle2,1); g_rfbox(window,corners);
delay(10); dummy=vsf_style(handle2,style); g_rfbox(window,corners);
}
}
points()
{ pu=0;
for (xx= -1; xx<2; xx++)
{ for (yy= -1) yy<2; yy++)
{ if (xx==0) { if(yy==0) continue) }
w=1; fr[(xx+1)*3+yy+1]=0;
while<ar!move*9+index+xx*w+<yy*9)*w]==player) { w++; }
if (ar[move*9+index+xx*w+(yy*9)*w]==0) fr[(xx+1)*3+yy+1]=1;
wr[(xx+1)*3+yy+1]=w-1;
}
}
for (yy=-1; yy<2; yy++)
{ zw=wr[yy+1]+wr[6-yy+1];
if (zw)=3) { sub1500(); continue; }
if (fr[yy+1]==0 && fr[6-yy+1]==0) zw=0;
sub1500();
}
zw=wr[5]; if (zw<(4-move)) zw=0;
sub1500();
}
sub1500()
{ if (zw==1) pu++;
if (zw==2) pu+=10;
if (zw>=3) pu+=100;
}
computer()
{ g_title(window,"Jetzt bin ich an der Reihe!");
get_time(); start = time; tt=0; player= -1 bz=0; br[1]= -999;
if (zu<2)
{ do
{ date(dummy,&datevec); bz=3+(datevec[6] % 3); }
while(ar[54+bz]!=0);
}
else rekursion();
zuege[zu]=bz; zu++;
get_time(); time_atari+=1+(time-start); player=1; show_time();
}
rekursion()
{ tt++; player*= -1; xr[tt]=1;
label1:
if (ar[xr[tt]+9]!=0) goto label2;
index=xr[tt]; depth(); yr[tt] =move ; points(); pr[tt]=pu;
br[tt+1]=0; pr[tt+1]=0;
if (tt+1< = tmax) br[tt + 1]= -999;
if (tt==1) { if (pu>=100) { bz=xr[1]; return; } }
ar[yr[tt]*9+xr[tt]]=player;
if (pu>=100) { br[tt]=pu; ar[yr[tt]*9+xr[tt]]=0; xr[tt]=7; goto label2; }
if (tt<tmax) rekursion();
if (br[tt+1]== -999) br[tt+1]=0;
if (pr[tt]-br[tt+1]>br[tt])
{ br[tt]=pr[tt]-br[tt+1]; if (tt==1) bz=xr[1]; }
if (pr[tt]-br[tt+1]==br[tt])
{ date(dummy,&datevec);
if (datevec[6]%2==0)
{ br[tt]=pr[tt]-br[tt+1]; if (tt==1) bz=xr[1]; } }
ar[yr[tt]*9+xr[tt]]=0;
label2:
if (xr[tt]<7) { xr[tt]++; goto label1; }
tt--; player*= -1;
}
print_items()
{ dummy=vsf_color(handle1,1); dummy=vsf_interior(handle1,2);
dummy = vsf_style(handle1,4);
corners[0] = 12; corners[2]=corners[0] + 104;
for(y=1; y<6; y++)
{ corners[1]=220+y*30-16; corners[3] = 220+y*30+5;
v_bar(handle1,corners); }
corners[0]=520; corners[2]=corners[0]+71;
for (y=0; y<3; y++)
{ corners[1]=174+y*60; corners[3]=corners[1]+51;
v_bar(handle1,corners); }
v_gtext(handle1,36,370,"ABBRUCH");
v_gtext(handle1,20,250,"Neues Spiel");
v_gtext(handle1,16,310,"Spielstufe +");
v_gtext(handle1, 16,340,"Spielstufe -");
v_gtext(handle1, 16,280,"Zugrcknahme") ;
v_gtext(handle1,528,253,"Spieler");
v_gtext(handle1,524,313,"Computer");
v_gtext(handle1,528,207,"Stufe ");
}
get_time()
{ date(dummy,&datevec);
time=datevec[6]+datevec[5]*60+datevec[4]*3600;
}
show_time()
{ if (player<0)
{ y=274; time=time_player; } else { y=334; time=time_atari; }
timebuf = time/3600; time- = timebuf*3600; itoa(timebuf,&buf1);
if (timebuf<10) { strcat(&buf1,"0"); reverse(&buf1); } strcpy(&buf,buf1);
strcat(&buf,"."); timebuf=time/60; time-=timebuf*60; itoa(timebuf,&buf1);
if (timebuf<10) { strcat(&buf1,"0"); reverse(&buf1); } strcat(&buf,&buf1);
strcat(&buf,":"); itoa(time,&buf1);
if (time<10) { strcat(&buf1,"0"); reverse(&buf1); } strcat(&buf,buf1);
v_gtext(handle1,524,y,buf);
}
print_max()
{ dummy=tmax-1; itoa(dummy,&buf); v_gtext(handle 1,576,207,buf);
do { vq_mouse(handle2,&buttons,&xpos,&ypos); } while(buttons!=0);
}
test()
{ leer=0; for(index=1; index<8; index++)
{ depth(); if (move>0) leer++; }
}
show_date()
{ date(dummy,&datevec);
switch(datevec[3])
{ case 0: strcpy(&datum,"Sonntag"); break;
case 1: strcpy(&datum,"Montag"); break;
case 2: strcpy(&datum,"Dienstagâ); break;
case 3: strcpy(&datum,"Mittwoch"); break;
case 4: strcpy(&datum,"Donnerstag"); break;
case 5: strcpy(&datum,"Freitag"); break;
case 6: strcpyC&datum,"Samstag"); break;
}
strcat(&datum,", der ");
dummy=datevec[2]; itoa(dummy,&buf); strcat(&datum,buf); strcat(&datum, ".");
dummy=datevec[1]; itoaCdummy,&buf); strcatC&datum,buf); strcatC&datum, ".19");
dummy=datevec[0]; itoaCdummy,Abuf); strcatC&datum,buf); strcatC&datum, ", ");
dummy=datevec[4]; itoa(dummy,&buf);
if (dummy<10) { strcat(&buf,"0"); reverse(&buf); } strcat(&datum,buf);
strcat(&datum,";"); dummy=datevec[5]; itoa(dummy,&buf);
if (dummy<10) { strcat(&buf,"0"); reverse(&buf); } strcat(&datum,buf);
strcat(&datum," Uhr");
while(strlen(datum)<37) { strcat(&datum," "); }
v_gtext(handle1,340,15,datum);
}
abbruch()
{ v_hide_c(handle2); g_info(window,"Sie wollen wirklich aufhren? Cj/n)");
key=evnt_keybd(); key=key&255; if (key==74 || key-=106) myexit=2;
g_info(window," "); v_show_c(handle2,0);
}