#define WS_CHILD 0x40000000 /*Specifies a child window. This should not be changed after the window is created.*/ #define WS_VISIBLE 0x10000000 /*Specifies a window that is initially visible. This style can be turned on and off to change window visibility.*/ #define WS_BORDER 0x00800000 /*draw a border around the control*/ /* icon */ #resource 1 "/reversi/reversi.ico" /* Interface Control -- Button */ #define BS_3STATE 0x0005 #define BS_AUTO3STATE 0x0006 #define BS_AUTOCHECKBOX 0x0003 #define BS_AUTORADIOBUTTON 0x0009 #define BS_CHECKBOX 0x0002 #define BS_DEFPUSHBUTTON 0x0001 #define BS_GROUPBOX 0x0007 #define BS_PUSHBUTTON 0x0000 #define BS_RADIOBUTTON 0x0004 #define BS_BOTTOM 0x0800 #define BS_CENTER 0x0300 #define BS_FLAT 0x8000 #define BS_LEFT 0x0100 #define BS_PUSHLIKE 0x1000 #define BS_RIGHT 0x0200 #define BS_RIGHTBUTTON 0x0100 #define BS_TOP 0x0400 #define BS_VCENTER 0x0C00 #define PM_BUTTONUP 5 #define PM_COMMAND 8 #define UM_SKIP 40030 #define UM_SWAP 40031 #define UM_HINT 40032 #define UM_RESIGN 40033 #define UM_QUIT 40034 int b[64]; int c[64]; int black; int white; int playside; int compside; int skipmove; otherside(int side) { if (side==1) { return 2; } else { return 1; } } posadjoins(int pos, int side) { int retval; int x; int y; y=(pos/8); x=(pos-(y*8)-1); retval=0; if(x>0) { if(b[pos-1]==side) { retval=1; } } if(x<7) { if(b[pos+1]==side) { retval=1; } } if(y>0) { if(b[pos-8]==side) { retval=1; } } if(y<7) { if(b[pos+8]==side) { retval=1; } } if((x>0)&&(y>0)) { if(b[pos-9]==side) { retval=1; } } if((x<7)&&(y>0)) { if(b[pos-7]==side) { retval=1; } } if((x>0)&&(y<7)) { if(b[pos+7]==side) { retval=1; } } if((x<7)&&(y<7)) { if(b[pos+9]==side) { retval=1; } } return retval; } pause(int wait) { int secs; int now; while(wait) { secs=getsec(); now=secs; while(secs==now) now=getsec(); wait=wait-1; } } drawatxy(int side, int x, int y) { if(side==0) { setpenattr(0, 1, 255, 255, 255); setbrushattr(255, 255, 255); } if(side==1) { setpenattr(0, 1, 0, 0, 0); setbrushattr(0, 0, 0); } if(side==2) { setpenattr(0, 1, 128, 128, 128); setbrushattr(128, 128, 128); } circle(x*20+70, y*20+50, 9); } drawpiece(int side, int pos) { int x; int y; y=(pos/8); x=(pos-(y*8)-1); drawatxy(side, x, y); } countpieces() { int loop; black=0; white=0; for(loop=0; loop<64; loop++) { if(b[loop]==1) { black++; } if(b[loop]==2) { white++; } } text(290, 80, black + " "); text(290, 120, white + " "); } drawboard() { int x; int y; clearg(); setpenattr(0, 1, 0, 0, 0); for(x=2; x<11; x++) { for(y=2; y<11; y++) { line(x*20, 40, x*20, 200); line(40, y*20, 200, y*20); } } setpenattr(0, 1, 0, 0, 0); setbrushattr(255, 255, 255); roundrect(345,45,435,195,5,5); roundrect(245,165,315,190,5,5); roundrect(245,75,315,145,5,5); createctrl("BUTTON","SKIP",WS_BORDER|WS_CHILD|WS_VISIBLE,0,350, 50, 80, 20, UM_SKIP); createctrl("BUTTON","SWAP",WS_BORDER|WS_CHILD|WS_VISIBLE,0,350, 80, 80, 20, UM_SWAP); createctrl("BUTTON","HINT",WS_BORDER|WS_CHILD|WS_VISIBLE,0,350, 110, 80, 20, UM_HINT); createctrl("BUTTON","RESIGN",WS_BORDER|WS_CHILD|WS_VISIBLE,0,350, 140, 80, 20, UM_RESIGN); createctrl("BUTTON","QUIT",WS_BORDER|WS_CHILD|WS_VISIBLE,0,350, 170, 80, 20, UM_QUIT); } initgame() { int loop; for(loop=0; loop<64; loop++) { b[loop]=0; } b[27]=1; drawpiece(1, 27); b[28]=2; drawpiece(2, 28); b[35]=2; drawpiece(2, 35); b[36]=1; drawpiece(1, 36); drawatxy(1, 10, 2); drawatxy(2, 10, 4); countpieces(); } linecaptured(int side, int pos, int offset, int stop, int capture) { int cont; int count; int lpos; int loop; int other; int retval; retval=0; other=otherside(side); cont=1; count=0; for(lpos=pos+offset; ((lpos>=0)&&(lpos<=63)&&(cont==1)); lpos=lpos+offset) { if(b[lpos]==0) { cont=0; } if(b[lpos]==other) { count++; } if((b[lpos]==side)&&(cont!=0)) { cont=0; if((capture==1)&&(count>0)) { for(loop=pos; loop!=lpos; loop=loop+offset) { b[loop]=side; drawpiece(side, loop); } } retval=count; } if(lpos==stop) { cont=0; } } return retval; } piecescaptured(int side, int pos, int capture) { int x; int y; int captured; int minnw; int minne; int minsw; int minse; captured=0; y=(pos/8); x=(pos-(y*8)); if(x0) { captured=captured+linecaptured(side, pos, -1, pos-x, capture); } if (x<7) { captured=captured+linecaptured(side, pos, 1, pos+7-x, capture); } if (y>0) { captured=captured+linecaptured(side, pos, -8, pos-(y*8), capture); } if (y<7) { captured=captured+linecaptured(side, pos, 8, pos+((7-y)*8), capture); } if ((x>0)&&(y>0)) { captured=captured+linecaptured(side, pos, -9, pos-(minnw*9), capture); } if ((x>0)&&(y<7)) { captured=captured+linecaptured(side, pos, 7, pos+(minsw*7), capture); } if ((x<7)&&(y>0)) { captured=captured+linecaptured(side, pos, -7, pos-(minne*7), capture); } if ((x<7)&&(y<7)) { captured=captured+linecaptured(side, pos, 9, pos+(minse*9), capture); } return captured; } isvalid(int side, int pos) { int other; int retval; int adjoins; retval= 0; if((pos>-1)&&(pos<64)) { other=otherside(side); if(b[pos]==0) { adjoins=posadjoins(pos, other); if(adjoins==1) { if(piecescaptured(side, pos, 0)>0) { retval= 1; } } } } return retval; } getmove(int side) { int loop; int max; int move; max=-1; move=-1; if(isvalid(side, 0)) { move=0; } if(isvalid(side, 7)) { move=7; } if(isvalid(side, 55)) { move=55; } if(isvalid(side, 63)) { move=63; } if(move==-1) { for(loop=0; loop<64; loop++) { if(isvalid(side, loop)) { c[loop]=piecescaptured(side, loop, 0); if (c[loop]>max) { max=c[loop]; move=loop; } if ((c[loop]==max)&&(random(10)>5)) { max=c[loop]; move=loop; } } else { c[loop]=0; } } } return move; } domenu() { int flash; int hint; int m; beep(2); m=menu(); if(m==UM_SKIP) { skipmove=1; } if (m==UM_SWAP) { compside=playside; playside=otherside(playside); } if (m==UM_HINT) { text(250,170,"THINKING"); hint=getmove(1); if(hint==-1) { alert("No hint available."); } else { for(flash=0; flash<2; flash++) { drawpiece(1, hint); pause(1); drawpiece(0, hint); } text(250,170," "); } } if (m==UM_RESIGN) { if(confirm("Wimp !!\nAnother game?")) { drawboard(); initgame(); } else { quit(); } } if (m==UM_QUIT) { quit(); } } getplayermove() { int pos; int e; int x; int y; int valid; skipmove=0; pos = -1; valid=0; while((valid==0)&&(skipmove==0)) { e=event(0); if (e==PM_COMMAND) { domenu(); } if (e==PM_BUTTONUP) { x=((mousex() - 40) / 20); y=((mousey() - 40) / 20); if((x>-1)&&(x<8)&&(y>-1)&&(y<8)) { pos=((y*8)+x); } else { pos=-1; } valid=isvalid(playside, pos); } } if((pos>=0)&&(pos<=63)&&(skipmove==0)) { b[pos]=playside; drawpiece(playside, pos); piecescaptured(playside, pos, 1); countpieces(); } } getcompmove() { int move; int flash; text(250,170,"THINKING"); move=getmove(compside); if(move>-1) { b[move]=compside; for(flash=0; flash<2; flash++) { drawpiece(0, move); pause(1); drawpiece(compside, move); pause(1); } piecescaptured(compside, move, 1); countpieces(); } else { alert("I can't go.\nSkipping my move."); } text(250,170," "); } main() { int play; string msg; title("Reversi"); about("Reversi by Dave Derrick"); showabout(); play=1; playside=1; compside=2; while(play) { drawboard(); initgame(); while((black+white<64)&&(black>0)&&(white>0)) { getplayermove(); getcompmove(); } if(black>white) { if(playside==1) { msg="You win, replay"; } else { msg="I win, replay"; } } else if(white>black) { if(playside==1) { msg="I win, replay"; } else { msg="You win, replay"; } } else if(white=black) { msg="Draw, replay"; } play=confirm(msg); } quit(); }