#include "exec/types.h" #include "intuition/intuition.h" #include "stdio.h" #include "string.h" struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct RastPort *r,*r2; struct Window *Wind,*abWind; struct NewWindow NewWindow,NewWindow2; struct IntuiMessage *mesg; struct IntuiText prompt,yprompt,t0,t1; struct Menu Menu1; struct MenuItem m0,m1; #define INTUITION_REV 29 #define GRAPHICS_REV 29 #define n 19 BOOL gamewon=FALSE,firstmove=TRUE; USHORT mclass,mcode,msx,msy; SHORT d,i,j,k,l,x,y,amx,amy,start; SHORT lx,ly,pla,opp,x0,x1,y0,y1,max,value; SHORT AttackFactor; SHORT Board[n+1][n+1],Aline[4][n+1][n+1][2],Value[n+1][n+1][2]; int ov,xv,len; char text[10]; static SHORT Weight[]={0,0,4,20,100,500,0}; VOID _main() { VOID OpenALL(),Human(),AddUp(),UpdateValue(),MakeMove(),FindMove(); VOID CreateMes(),DrawFrame(),make_window(),init_newgame(); VOID setup_menu(),show_About(); AttackFactor=4; start=0; OpenALL(); make_window(); setup_menu(); SetMenuStrip(Wind,&Menu1); r=Wind->RPort; CreateMes(&yprompt,3,3," OK "); NewGame: init_newgame(); if(start == 0) goto Human_first; Loop: pla=1; opp=0; FindMove(); MakeMove(); Board[x][y]=2; if (! firstmove) { SetAPen(r,0); DrawFrame(); } else firstmove=FALSE; x0=(x-1)*20; y0=(y-1)*8; SetAPen(r,1); Move(r,x0+14,y0+14); Draw(r,x0+26,y0+18); Move(r,x0+14,y0+18); Draw(r,x0+26,y0+14); amx=x0+13; amy=y0+13; SetAPen(r,3); DrawFrame(); if (gamewon) { ov=ov+1; CreateMes(&prompt,50,5,"I won"); AutoRequest(Wind,&prompt,&yprompt,&yprompt,NULL,NULL,160,50); goto NewGame; } Human_first: pla=0; opp=1; Human(); MakeMove(); if (gamewon) { xv=xv+1; CreateMes(&prompt,37,5,"You won!"); AutoRequest(Wind,&prompt,&yprompt,&yprompt,NULL,NULL,160,50); goto NewGame; } goto Loop; } VOID Human() { /* Set Up an IDCMP Read Loop */ HumanLoop: Wait (1 << Wind->UserPort->mp_SigBit); while((mesg=(struct IntuiMessage *) GetMsg(Wind->UserPort)) != NULL) { mclass=mesg->Class; mcode=mesg->Code; msx=mesg->MouseX; msy=mesg->MouseY; ReplyMsg(mesg); } switch(mclass) { case MENUPICK: { if(ITEMNUM(mcode) == 0) { ClearMenuStrip(Wind); show_About(); while((mesg=(struct IntuiMessage *) GetMsg(Wind->UserPort)) != NULL) ReplyMsg(mesg); SetMenuStrip(Wind,&Menu1); goto HumanLoop; } else if(ITEMNUM(mcode) == 1) { /* Quit */ ClearMenuStrip(Wind); CloseWindow(Wind); exit(FALSE); break; } else goto HumanLoop; } case MOUSEBUTTONS: { if(ReadPixel(r,msx,msy) == 2) goto HumanLoop; /* black line */ if(msx < 10 || msx > 10+n*20) goto HumanLoop; /* outside board */ if(msy < 12 || msy > 12+n*8) goto HumanLoop; /* outside board */ y=((msy-12)/8)+1; x=((msx-10)/20)+1; if(Board[x][y] > 0) goto HumanLoop; /* occupied square */ Board[x][y]=1; i=(x-1)*20+16; j=y*8+6; SetAPen(r,1); Move(r,i+1,j); Draw(r,i+6,j); Move(r,i+7,j+1); Draw(r,i+7,j+3); Move(r,i+6,j+4); Draw(r,i+1,j+4); Move(r,i,j+3); Draw(r,i,j+1); } } } VOID MakeMove() { gamewon=FALSE; d=0; for(k=0;k<=4;k++) { x1=x-k; y1=y; if(x1>=1 && x1<=n-4) { AddUp(); for(l=0;l<=4;l++) UpdateValue(); } } d=1; for(k=0;k<=4;k++) { x1=x-k; y1=y-k; if((x1>=1 && x1<=n-4) && (y1>=1 && y1<=n-4)) { AddUp(); for(l=0;l<=4;l++) UpdateValue(); } } d=3; for(k=0;k<=4;k++) { x1=x+k; y1=y-k; if((x1>=5 && x1 <= n) && (y1>=1 && y1<=n-4)) { AddUp(); for(l=0;l<=4;l++) UpdateValue(); } } d=2; for(k=0;k<=4;k++) { x1=x; y1=y-k; if(y1>=1 && y1<=n-4) { AddUp(); for(l=0;l<=4;l++) UpdateValue(); } } } VOID AddUp() { Aline[d][x1][y1][pla] = Aline[d][x1][y1][pla] + 1; if(Aline[d][x1][y1][pla] == 5) gamewon=TRUE; } VOID UpdateValue() { if(d==0) { lx=l; ly=0; } else if(d==1) { lx=l; ly=l; } else if(d==2) { lx=0; ly=l; } else { lx=-l; ly=l; } if(Aline[d][x1][y1][opp] == 0) Value[x1+lx][y1+ly][pla] = Value[x1+lx][y1+ly][pla] + Weight[Aline[d][x1][y1][pla]+1] - Weight[Aline[d][x1][y1][pla]]; else if(Aline[d][x1][y1][pla] == 1) Value[x1+lx][y1+ly][opp] = Value[x1+lx][y1+ly][opp] - Weight[Aline[d][x1][y1][opp]+1]; } VOID FindMove() { max=-32767; x=(n+1)/2; y=(n+1)/2; if(Board[x][y] == 0) max=4; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(Board[i][j] == 0) { value=Value[i][j][pla] * (16 + AttackFactor) / 16 + Value[i][j][opp]; if(value > max) { x=i; y=j; max=value; } } } } } VOID OpenALL() /* Open required libraries */ { IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",INTUITION_REV); if(IntuitionBase == NULL) exit(FALSE); GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",GRAPHICS_REV); if(GfxBase == NULL) exit(FALSE); } VOID CreateMes(x,left,top,mes) struct IntuiText *x; SHORT left,top; UBYTE *mes; { x->FrontPen=0; x->BackPen=1; x->DrawMode=JAM1; x->LeftEdge=left; x->TopEdge=top; x->ITextFont=NULL; x->IText=mes; x->NextText=NULL; } VOID DrawFrame() { Move(r,amx,amy); Draw(r,amx+14,amy); Draw(r,amx+14,amy+6); Draw(r,amx,amy+6); Draw(r,amx,amy); } VOID make_window() /* Open a plain window */ { NewWindow.LeftEdge=0; NewWindow.TopEdge=0; NewWindow.Width=480; NewWindow.Height=170; NewWindow.DetailPen=-1; NewWindow.BlockPen=-1; NewWindow.Title="Five In Line"; NewWindow.Flags=ACTIVATE|WINDOWDRAG|WINDOWDEPTH|SMART_REFRESH; NewWindow.IDCMPFlags=MOUSEBUTTONS|MENUPICK; NewWindow.Type=WBENCHSCREEN; NewWindow.FirstGadget=NULL; NewWindow.CheckMark=NULL; NewWindow.Screen=NULL; NewWindow.BitMap=NULL; NewWindow.MinWidth=0; NewWindow.MinHeight=0; NewWindow.MaxWidth=640; NewWindow.MaxHeight=200; Wind=(struct Window *) OpenWindow(&NewWindow); } VOID init_newgame() { start=1-start; /* toggle between computer and human */ for(x=1;x<=n;x++) { for(y=1;y<=n;y++) Board[x][y]=0; } for(d=0;d<=3;d++) { for(x=1;x<=n;x++) { for(y=1;y<=n;y++) { for(pla=0;pla<=1;pla++) Aline[d][x][y][pla]=0; } } } for(x=1;x<=n;x++) { for(y=1;y<=n;y++) { for(pla=0;pla<=1;pla++) Value[x][y][pla]=0; } } SetAPen(r,0); RectFill(r,10,12,400,168); /* blank board */ firstmove=TRUE; /* draw new grid */ SetAPen(r,2); for(x=10;x<=10+n*20;x=x+20) { Move(r,x,12); Draw(r,x,12+n*8); } for(y=12;y<=12+n*8;y=y+8) { Move(r,10,y); Draw(r,10+n*20,y); } /* print scores */ SetAPen(r,1); Move(r,420,30); Text(r,"You:",4); Move(r,450,30); len=sprintf(text,"%3d",xv); Text(r,text,len); Move(r,420,45); Text(r,"I :",4); Move(r,450,45); len=sprintf(text,"%3d",ov); Text(r,text,len); } VOID setup_menu() { CreateMes(&t0,0,0,"About"); m0.NextItem=&m1; m0.LeftEdge=5; m0.TopEdge=0; m0.Width=50; m0.Height=10; m0.Flags=ITEMTEXT|HIGHCOMP|ITEMENABLED; m0.MutualExclude=NULL; m0.ItemFill=(APTR)&t0; m0.SelectFill=NULL; m0.Command=NULL; m0.SubItem=NULL; CreateMes(&t1,0,0,"Quit"); m1.NextItem=NULL; m1.LeftEdge=5; m1.TopEdge=15; m1.Width=50; m1.Height=10; m1.Flags=ITEMTEXT|HIGHCOMP|ITEMENABLED; m1.MutualExclude=NULL; m1.ItemFill=(APTR)&t1; m1.SelectFill=NULL; m1.Command=NULL; m1.SubItem=NULL; Menu1.NextMenu=NULL; Menu1.LeftEdge=0; Menu1.TopEdge=0; Menu1.Width=60; Menu1.Height=100; Menu1.Flags=MENUENABLED; Menu1.MenuName="Project"; Menu1.FirstItem=&m0; } VOID show_About() { NewWindow2.LeftEdge=Wind->LeftEdge + 40; NewWindow2.TopEdge=Wind->TopEdge + 45; NewWindow2.Width=400; NewWindow2.Height=80; NewWindow2.DetailPen=-1; NewWindow2.BlockPen=-1; NewWindow2.Title="About Five In Line"; NewWindow2.Flags=ACTIVATE|WINDOWCLOSE|SMART_REFRESH; NewWindow2.IDCMPFlags=CLOSEWINDOW; NewWindow2.Type=WBENCHSCREEN; NewWindow2.FirstGadget=NULL; NewWindow2.CheckMark=NULL; NewWindow2.Screen=NULL; NewWindow2.BitMap=NULL; NewWindow2.MinWidth=0; NewWindow2.MinHeight=0; NewWindow2.MaxWidth=640; NewWindow2.MaxHeight=200; abWind=(struct Window *) OpenWindow(&NewWindow2); r2=abWind->RPort; SetAPen(r2,1); Move(r2,10,20); Text(r2,"Placed in Public Domain 1988",28); Move(r2,10,30); Text(r2,"by Njål Fisketjøn.",18); Move(r2,10,50); Text(r2,"Algorithm from a",16); SetAPen(r2,3); Move(r2,146,50); Text(r2,"Borland Turbo Pascal",20); SetAPen(r2,1); Move(r2,314,50); Text(r2,"program.",8); Move(r2,10,70); Text(r2,"Close window to continue playing.",33); Wait (1 << abWind->UserPort->mp_SigBit); while((mesg=(struct IntuiMessage *) GetMsg(abWind->UserPort)) != NULL) ReplyMsg(mesg); CloseWindow(abWind); }