include unistd for swab.
[AROS-Contrib.git] / fish / fiveinline / fiveinline.c
blobbd42ee562d61926a3b8cfc3a95cbdb866671ce4a
1 #include <aros/oldprograms.h>
2 #include "exec/types.h"
3 #include "intuition/intuition.h"
4 #include <stdlib.h>
5 #include "stdio.h"
6 #include "string.h"
8 struct IntuitionBase *IntuitionBase;
9 struct GfxBase *GfxBase;
10 struct RastPort *r,*r2;
11 struct Window *Wind,*abWind;
12 struct NewWindow NewWindow,NewWindow2;
13 struct IntuiMessage *mesg;
14 struct IntuiText prompt,yprompt,t0,t1;
15 struct Menu Menu1;
16 struct MenuItem m0,m1;
17 struct TextFont *topazfont;
19 #define INTUITION_REV 29
20 #define GRAPHICS_REV 29
21 #define n 19
23 #define CELLWIDTH 20
24 #define CELLHEIGHT 16
26 #define y0 myy0
27 #define y1 myy1
29 BOOL gamewon=FALSE,firstmove=TRUE;
30 USHORT mclass,mcode,msx,msy;
31 SHORT d,i,j,k,l,x,y,amx,amy,start;
32 SHORT lx,ly,pla,opp,x0,x1,y0,y1,max,value;
33 SHORT AttackFactor;
34 SHORT Board[n+1][n+1],Aline[4][n+1][n+1][2],Value[n+1][n+1][2];
35 int ov,xv,len;
36 char text[10];
37 static SHORT Weight[]={0,0,4,20,100,500,0};
38 WORD wintop = 11;
40 void OpenALL(),Human(),AddUp(),UpdateValue(),MakeMove(),FindMove();
41 void CreateMes(),DrawFrame(),make_window(),init_newgame();
42 void setup_menu(),show_About();
44 struct TextAttr topaz8 =
46 "topaz.font", 8, 0, 0
49 int main(int argc, char **argv)
52 AttackFactor=4;
53 start=0;
55 OpenALL();
56 make_window();
58 setup_menu();
59 SetMenuStrip(Wind,&Menu1);
61 r=Wind->RPort;
63 CreateMes(&yprompt,3,3," OK ");
65 NewGame:
67 init_newgame();
68 if(start == 0) goto Human_first;
70 Loop:
71 pla=1;
72 opp=0;
73 FindMove();
74 MakeMove();
75 Board[x][y]=2;
77 if (! firstmove) {
78 SetAPen(r,0);
79 DrawFrame();
81 else firstmove=FALSE;
83 x0=(x-1)*20;
84 y0=(y-1)*CELLHEIGHT;
85 SetAPen(r,1);
86 Move(r,x0+14,y0+wintop+5);
87 Draw(r,x0+26,y0+wintop+13);
88 Move(r,x0+14,y0+wintop+13);
89 Draw(r,x0+26,y0+wintop+5);
91 amx=x0+13;
92 amy=y0+wintop+4;
93 SetAPen(r,3);
94 DrawFrame();
96 if (gamewon) {
97 ov=ov+1;
99 CreateMes(&prompt,50,5,"I won");
100 AutoRequest(Wind,&prompt,&yprompt,&yprompt,0,0,160,50);
102 goto NewGame;
105 Human_first:
107 pla=0;
108 opp=1;
109 Human();
110 MakeMove();
112 if (gamewon) {
113 xv=xv+1;
114 CreateMes(&prompt,37,5,"You won!");
115 AutoRequest(Wind,&prompt,&yprompt,&yprompt,0,0,160,50);
117 goto NewGame;
120 goto Loop;
124 VOID Human()
127 /* Set Up an IDCMP Read Loop */
128 HumanLoop:
129 Wait (1 << Wind->UserPort->mp_SigBit);
131 while((mesg=(struct IntuiMessage *) GetMsg(Wind->UserPort)) != NULL) {
132 mclass=mesg->Class;
133 mcode=mesg->Code;
134 msx=mesg->MouseX;
135 msy=mesg->MouseY;
136 ReplyMsg((struct Message *)mesg);
139 switch(mclass) {
140 case MENUPICK: {
141 if(ITEMNUM(mcode) == 0) {
142 ClearMenuStrip(Wind);
143 show_About();
145 while(((mesg=(struct IntuiMessage *) GetMsg(Wind->UserPort)) != NULL)) ReplyMsg((struct Message *)mesg);
147 SetMenuStrip(Wind,&Menu1);
148 goto HumanLoop;
150 else if(ITEMNUM(mcode) == 1) { /* Quit */
151 ClearMenuStrip(Wind);
152 CloseWindow(Wind);
153 exit(FALSE);
154 break;
156 else goto HumanLoop;
158 case MOUSEBUTTONS: {
159 if(ReadPixel(r,msx,msy) == 2) goto HumanLoop; /* black line */
160 if(msx < 10 || msx > 10+n*20) goto HumanLoop; /* outside board */
161 if(msy < wintop+1 || msy > wintop+1+n*CELLHEIGHT) goto HumanLoop; /* outside board */
163 y=((msy-wintop-1)/CELLHEIGHT)+1;
164 x=((msx-10)/20)+1;
165 if(Board[x][y] > 0) goto HumanLoop; /* occupied square */
167 Board[x][y]=1;
168 i=(x-1)*20+16;
169 j=(y-1)*CELLHEIGHT+wintop+5;
171 SetAPen(r,1);
172 Move(r,i+1,j);
173 Draw(r,i+6,j);
174 Move(r,i+7,j+1);
175 Draw(r,i+7,j+7);
176 Move(r,i+6,j+8);
177 Draw(r,i+1,j+8);
178 Move(r,i,j+7);
179 Draw(r,i,j+1);
185 VOID MakeMove()
188 gamewon=FALSE;
190 d=0;
191 for(k=0;k<=4;k++) {
192 x1=x-k;
193 y1=y;
194 if(x1>=1 && x1<=n-4) {
195 AddUp();
196 for(l=0;l<=4;l++)
197 UpdateValue();
201 d=1;
202 for(k=0;k<=4;k++) {
203 x1=x-k;
204 y1=y-k;
205 if((x1>=1 && x1<=n-4) && (y1>=1 && y1<=n-4)) {
206 AddUp();
207 for(l=0;l<=4;l++)
208 UpdateValue();
212 d=3;
213 for(k=0;k<=4;k++) {
214 x1=x+k;
215 y1=y-k;
216 if((x1>=5 && x1 <= n) && (y1>=1 && y1<=n-4)) {
217 AddUp();
218 for(l=0;l<=4;l++)
219 UpdateValue();
223 d=2;
224 for(k=0;k<=4;k++) {
225 x1=x;
226 y1=y-k;
227 if(y1>=1 && y1<=n-4) {
228 AddUp();
229 for(l=0;l<=4;l++)
230 UpdateValue();
236 VOID AddUp()
239 Aline[d][x1][y1][pla] = Aline[d][x1][y1][pla] + 1;
241 if(Aline[d][x1][y1][pla] == 5) gamewon=TRUE;
245 VOID UpdateValue()
248 if(d==0) {
249 lx=l;
250 ly=0;
252 else if(d==1) {
253 lx=l;
254 ly=l;
256 else if(d==2) {
257 lx=0;
258 ly=l;
260 else {
261 lx=-l;
262 ly=l;
265 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]];
266 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];
270 VOID FindMove()
273 max=-32767;
274 x=(n+1)/2;
275 y=(n+1)/2;
276 if(Board[x][y] == 0) max=4;
278 for(i=1;i<=n;i++) {
279 for(j=1;j<=n;j++) {
280 if(Board[i][j] == 0) {
281 value=Value[i][j][pla] * (16 + AttackFactor) / 16 + Value[i][j][opp];
282 if(value > max) {
283 x=i;
284 y=j;
285 max=value;
293 VOID OpenALL() /* Open required libraries */
296 IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",INTUITION_REV);
298 if(IntuitionBase == NULL) exit(FALSE);
300 GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",GRAPHICS_REV);
302 if(GfxBase == NULL) exit(FALSE);
306 VOID CreateMes(x,left,top,mes)
308 struct IntuiText *x;
309 SHORT left,top;
310 UBYTE *mes;
312 x->FrontPen=0;
313 x->BackPen=1;
314 x->DrawMode=JAM1;
315 x->LeftEdge=left;
316 x->TopEdge=top;
317 x->ITextFont=NULL;
318 x->IText=mes;
319 x->NextText=NULL;
323 VOID DrawFrame()
326 Move(r,amx,amy);
327 Draw(r,amx+14,amy);
328 Draw(r,amx+14,amy+10);
329 Draw(r,amx,amy+10);
330 Draw(r,amx,amy);
334 VOID make_window() /* Open a plain window */
337 struct Screen *scr;
339 scr = LockPubScreen(NULL);
340 if (scr)
342 wintop = scr->WBorTop + scr->Font->ta_YSize + 1;
343 UnlockPubScreen(NULL, scr);
346 NewWindow.LeftEdge=0;
347 NewWindow.TopEdge=0;
348 NewWindow.Width=480;
349 NewWindow.Height=311 + wintop; //159 + wintop;
350 NewWindow.DetailPen=-1;
351 NewWindow.BlockPen=-1;
352 NewWindow.Title="Five In Line";
353 NewWindow.Flags=ACTIVATE|WINDOWDRAG|WINDOWDEPTH|SMART_REFRESH;
354 NewWindow.IDCMPFlags=MOUSEBUTTONS|MENUPICK;
355 NewWindow.Type=WBENCHSCREEN;
356 NewWindow.FirstGadget=NULL;
357 NewWindow.CheckMark=NULL;
358 NewWindow.Screen=NULL;
359 NewWindow.BitMap=NULL;
360 NewWindow.MinWidth=0;
361 NewWindow.MinHeight=0;
362 NewWindow.MaxWidth=640;
363 NewWindow.MaxHeight=200;
365 topazfont = OpenFont(&topaz8);
367 Wind=(struct Window *) OpenWindow(&NewWindow);
368 if (topazfont) SetFont(Wind->RPort, topazfont);
372 VOID init_newgame()
375 start=1-start; /* toggle between computer and human */
377 for(x=1;x<=n;x++) {
378 for(y=1;y<=n;y++)
379 Board[x][y]=0;
382 for(d=0;d<=3;d++) {
383 for(x=1;x<=n;x++) {
384 for(y=1;y<=n;y++) {
385 for(pla=0;pla<=1;pla++)
386 Aline[d][x][y][pla]=0;
391 for(x=1;x<=n;x++) {
392 for(y=1;y<=n;y++) {
393 for(pla=0;pla<=1;pla++)
394 Value[x][y][pla]=0;
398 SetAPen(r,0);
399 RectFill(r,10,wintop+1,400,Wind->Height-Wind->BorderBottom - 1); /* blank board */
401 firstmove=TRUE;
403 /* draw new grid */
405 SetAPen(r,2);
407 for(x=10;x<=10+n*20;x=x+20) {
408 Move(r,x,wintop+1);
409 Draw(r,x,wintop+1+n*CELLHEIGHT);
412 for(y=wintop+1;y<=wintop+1+n*CELLHEIGHT;y=y+CELLHEIGHT) {
413 Move(r,10,y);
414 Draw(r,10+n*20,y);
417 /* print scores */
419 SetAPen(r,1);
420 Move(r,420,19+wintop);
421 Text(r,"You:",4);
422 Move(r,450,19+wintop);
423 len=sprintf(text,"%3d",xv);
424 Text(r,text,len);
426 Move(r,420,34+wintop);
427 Text(r,"I :",4);
428 Move(r,450,34+wintop);
429 len=sprintf(text,"%3d",ov);
430 Text(r,text,len);
434 VOID setup_menu()
437 CreateMes(&t0,0,0,"About");
439 m0.NextItem=&m1;
440 m0.LeftEdge=5;
441 m0.TopEdge=0;
442 m0.Width=50;
443 m0.Height=10;
444 m0.Flags=ITEMTEXT|HIGHCOMP|ITEMENABLED;
445 m0.MutualExclude=0;
446 m0.ItemFill=(APTR)&t0;
447 m0.SelectFill=NULL;
448 m0.Command=0;
449 m0.SubItem=NULL;
451 CreateMes(&t1,0,0,"Quit");
453 m1.NextItem=NULL;
454 m1.LeftEdge=5;
455 m1.TopEdge=15;
456 m1.Width=50;
457 m1.Height=10;
458 m1.Flags=ITEMTEXT|HIGHCOMP|ITEMENABLED;
459 m1.MutualExclude=0;
460 m1.ItemFill=(APTR)&t1;
461 m1.SelectFill=NULL;
462 m1.Command=0;
463 m1.SubItem=NULL;
465 Menu1.NextMenu=NULL;
466 Menu1.LeftEdge=0;
467 Menu1.TopEdge=0;
468 Menu1.Width=60;
469 Menu1.Height=100;
470 Menu1.Flags=MENUENABLED;
471 Menu1.MenuName="Project";
472 Menu1.FirstItem=&m0;
477 VOID show_About()
480 NewWindow2.LeftEdge=Wind->LeftEdge + 40;
481 NewWindow2.TopEdge=Wind->TopEdge + 45;
482 NewWindow2.Width=400;
483 NewWindow2.Height=69+wintop;
484 NewWindow2.DetailPen=-1;
485 NewWindow2.BlockPen=-1;
486 NewWindow2.Title="About Five In Line";
487 NewWindow2.Flags=ACTIVATE|WINDOWCLOSE|SMART_REFRESH;
488 NewWindow2.IDCMPFlags=CLOSEWINDOW;
489 NewWindow2.Type=WBENCHSCREEN;
490 NewWindow2.FirstGadget=NULL;
491 NewWindow2.CheckMark=NULL;
492 NewWindow2.Screen=NULL;
493 NewWindow2.BitMap=NULL;
494 NewWindow2.MinWidth=0;
495 NewWindow2.MinHeight=0;
496 NewWindow2.MaxWidth=640;
497 NewWindow2.MaxHeight=200;
499 abWind=(struct Window *) OpenWindow(&NewWindow2);
500 r2=abWind->RPort;
501 if (topazfont) SetFont(r2, topazfont);
503 SetAPen(r2,1);
504 Move(r2,10,wintop+9);
505 Text(r2,"Placed in Public Domain 1988",28);
506 Move(r2,10,wintop+19);
507 Text(r2,"by Njål Fisketjøn.",18);
509 Move(r2,10,wintop+39);
510 Text(r2,"Algorithm from a",16);
512 SetAPen(r2,3);
513 Move(r2,146,wintop+39);
514 Text(r2,"Borland Turbo Pascal",20);
516 SetAPen(r2,1);
517 Move(r2,314,wintop+39);
518 Text(r2,"program.",8);
520 Move(r2,10,wintop+59);
521 Text(r2,"Close window to continue playing.",33);
523 Wait (1 << abWind->UserPort->mp_SigBit);
524 while((mesg=(struct IntuiMessage *) GetMsg(abWind->UserPort)) != NULL) ReplyMsg((struct Message *)mesg);
525 CloseWindow(abWind);