## Even-Odd Effect rev.2 written by ‚x‚³ function rnd(N){ return int(N * rand()); } ## —” BEGIN{ srand(); ## —”‚̉Šú‰» # ƒQ[ƒ€ƒ‚[ƒhŒˆ’è gm=GAMEMODE; if(gm!="0" && gm!="1" && gm!="2"){ print " - 0" print " " print " first move - 1" print " 2'nd - 2" printf("\nWhich?[0-2]> "); do{ gm=""; getline gm; gm=tolower(gm); }while(gm!="0" && gm!="1" && gm!="2"); } GAMEMODE=gm+0; print "\n"; # CPUƒŒƒxƒ‹Œˆ’è SEARCHSTART=4; gm=CPULEVEL; if(GAMEMODE!=0 && gm!="0" && gm!="1"){ print " " print " beginner - 0" print " expert - 1" printf("\nWhich?[0-1]> "); do{ gm=""; getline gm; gm=tolower(gm); }while(gm!="0" && gm!="1"); CPULEVEL=gm+0; print "\n"; } ## Turn; ## ‡”Ô 0:l,1:COM Turn=(GAMEMODE!=1)?(0):(-1); #ƒQ[ƒ€ŠJŽnŽž‚É+1 Times=0; #‰ñ” ## Sc[2]; ## “¾“_ 0=l,1=COM Sc[0]=Sc[1]=0; ## Bit[9]; ## Žw [l<1:¶,3:‰E>, COM<9:¶,7:‰E>] Bit[1]=Bit[9]=0; Bit[3]=Bit[7]=1; ## ꊔ»•Ê ‘¼ pNo[1,1]=7; pNo[1,0]=9; pNo[0,0]=1; pNo[0,1]=3; cnvPos[10]=pNo[0,1]; cnvPos[11]=pNo[1,1]; cnvPos[12]=pNo[1,0]; cnvPos[30]=pNo[0,0]; cnvPos[31]=pNo[1,0]; cnvPos[32]=pNo[1,1]; cnvPos[70]=pNo[1,0]; cnvPos[71]=pNo[0,0]; cnvPos[72]=pNo[0,1]; cnvPos[90]=pNo[1,1]; cnvPos[91]=pNo[0,1]; cnvPos[92]=pNo[0,0]; mv["LR"]=mv[12]=10; mv["LU"]=mv[14]=11; mv["LX"]=mv[15]=12; mv["RL"]=mv[32]=30; mv["RU"]=mv[36]=31; mv["RX"]=mv[35]=32; mv[78]=70; mv[74]=71; mv[75]=72; mv[98]=90; mv[96]=91; mv[95]=92; ## ƒQ[ƒ€ƒƒCƒ“ for(;;){ #󋵕\Ž¦ ++Times; dispHands(0); #GAME OVER / 1‰ñ‹x‚Ý”»’è if(gameOver(Turn)>0) exit; if(GAMEMODE!=0) if(++Turn>1) Turn=0; setSkip(); do{ #ˆÚ“®Žw’è -> ‰e‹¿”»’è sw=(Turn==0)?(man()):(com()); ev=canMove(sw); if(Turn==0 && ev<0){ printf(" No effect, retry."); pushEnter(); dispHands(0); } }while(ev<0); #•Ï‰» change(sw,ev); } exit; } END{ print "\n"; if(finish(0)) printf(" Congratulations !! (SCORE:%05d0)\n", Sc[0]); else{ printf(" ****** GAME OVER ******\n"); printf(" ...YOU LOSE (SCORE:%05d0)\n", Sc[0]); } print ""; } function pushEnter( tmp){ printf(" "); getline tmp; } function yorn( yn) { do{ yn=""; getline yn; yn=toupper(yn); }while(yn!="Y" && yn!="N"); return yn; } ## ## 󋵕\Ž¦ ## function dispHands(sw, d,ev,i) { delete d; delete ev; makeDispTbl(sw,d,ev); print ""; for(i=((GAMEMODE==0)?(6):(0)); i<=8; ++i) print d[i]; print ""; } function makeDispTbl(sw,d,ev, s0,s1) { #0....5....0....5....0....5....0... d[0]=" . . "; d[1]=" : : "; d[2]=" : zzzzz xxxxx : COM [cccc0]"; d[3]=" . zzzzz xxxxx ."; d[4]=" . ."; d[5]=d[4]; d[6]=" . @@@@@ &&&&& ."; d[7]=" : @@@@@ &&&&& : YOU [yyyy0]"; d[8]=" [L] [R] "; if(sw>=90){ s0= mkBitStr(Bit[9],1); s1= mkBitStr(Bit[9],0); }else if(sw>=70){ s0=rev(mkBitStr(Bit[7],1)); s1=rev(mkBitStr(Bit[7],0)); }else if(sw>=30){ s0= mkBitStr(Bit[3],0); s1= mkBitStr(Bit[3],1); }else if(sw>=10){ s0=rev(mkBitStr(Bit[1],0)); s1=rev(mkBitStr(Bit[1],1)); } #0....5....0....5....0....5....0... if(sw==90){ d[2]=" : zzzzz" s0 " : COM [cccc0]"; d[3]=" . zzzzz" s1 " ."; } if(sw==70){ d[2]=" : " s0 "xxxxx : COM [cccc0]"; d[3]=" . " s1 "xxxxx ."; } if(sw==30){ d[6]=" . @@@@@" s0 " ."; d[7]=" : @@@@@" s1 " : YOU [yyyy0]"; } if(sw==10){ d[6]=" . " s0 "&&&&& ."; d[7]=" : " s1 "&&&&& : YOU [yyyy0]"; } #0....5....0....5....0.... if(sw==31 || sw==91){ d[4]=" . " s0 " ."; d[5]=" . " s1 " ."; } if(sw==32 || sw==92){ d[4]=" . " s0 " ."; d[5]=" . " s1 " ."; } if(sw==12 || sw==72){ d[4]=" . " s0 " ."; d[5]=" . " s1 " ."; } if(sw==11 || sw==71){ d[4]=" . " s0 " ."; d[5]=" . " s1 " ."; } #0.... #0.... cnvHandStr(7,"zzzzz",sw,1,d,3,2); cnvHandStr(9,"xxxxx",sw,0,d,3,2); cnvHandStr(1,"@@@@@",sw,1,d,6,7); cnvHandStr(3,"&&&&&",sw,0,d,6,7); setAllEval(ev); # YOU sub(/s0/, ev[0], d[7]); sub(/yyyy/, sprintf("%04d",Sc[0]), d[7]); # COM sub(/s1/, ev[1], d[0]); sub(/s2/, ev[2], d[0]); sub(/s3/, ev[3], d[0]); sub(/s4/, ev[4], d[0]); sub(/s5/, ev[5], d[2]); sub(/cccc/, sprintf("%04d",Sc[1]), d[2]); } function cnvHandStr(hand,regexp, dispSw,revSw,dTbl,ln1,ln2, s0,s1) { #0.... if(unpackUpper(dispSw)==hand && unpackLower(dispSw)!=0) s0=s1=" "; else{ s0=mkBitStr(Bit[hand],0); s1=mkBitStr(Bit[hand],1); if(revSw){ s0=rev(s0); s1=rev(s1); } } sub(regexp, s0, dTbl[ln1]); sub(regexp, s1, dTbl[ln2]); } function mkBitStr(n,pos, s,i) { if(pos==0){ for(i=1; i<=n; ++i) s=s "I"; return substr(" " s " ", 1, 5); } if(pos==1) return (n==5)?("- 5 )"):(sprintf("( %d )", n)); } function rev(src, dst,len) { for(len=length(src); len>0; --len) dst=dst substr(src, len, 1); if(substr(dst, 1, 1)==")") dst="(" substr(dst, 2); if(substr(dst, 5, 1)=="(") dst=substr(dst, 1, 4) ")"; return dst; } function setAllEval(ev ) { delete ev; ev[0]=evenOddStr(Bit[1], Bit[3]); ev[1]=evenOddStr(Bit[3], Bit[7]); ev[2]=evenOddStr(Bit[1], Bit[7]); ev[3]=evenOddStr(Bit[3], Bit[9]); ev[4]=evenOddStr(Bit[1], Bit[9]); ev[5]=evenOddStr(Bit[7], Bit[9]); } function evenOdd(b1,b2){ return ((b1+b2)%2); } function evenOddStr(b1,b2){ return ((evenOdd(b1,b2))?("od"):("ev")); } ## ## ‰e‹¿”»’è ## function canMove(sw){ return canMoveFromTo(unpackUpper(sw),cnvPos[sw],Turn); } function canMoveFromTo(from,to,who) { # ‰Žè if(Times<=2) if(other(who,to)) return -1; # Šï” if(evenOdd(Bit[from],Bit[to])) return ((Bit[from]<5)?(1):(-1)); # ‹ô” if((Bit[to]<1) || (Bit[from]>=4)) return -2; return 2; } function other(who,to, oth){ oth=another(who); if(to==pNo[oth,0] || to==pNo[oth,1]) return 1; return 0; } function another(who){ return ((who==0)?(1):(0)); } function total(who){ return (Bit[pNo[who,0]] + Bit[pNo[who,1]]); } function finish(who){ return (total(who)==10); } function noEffectLR(l,r){ return (Bit[l]==4 && Bit[r]==4); } function noEffect(who){ return noEffectLR(pNo[who,0],pNo[who,1]); } function gameOver(who) { if(finish(who)) return 3; if(finish(another(who))) return 2; if(noEffect(0) && (GAMEMODE==0 || noEffect(1))) return 1; return 0; } function setSkip() { if(isSkip(Turn)){ Turn=another(Turn); printf(" Can't effect."); pushEnter(); } } function isSkip(who) { return ((noEffect(who) && evalOddEven(another(who))==4)?(1):(0)) } function evalOddEven(who){ return evalOddEvenLR(pNo[who,0],pNo[who,1]); } function evalOddEvenLR(l,r, minOE, maxOE) { minOE=Bit[getMinPos(l,r)]%2; maxOE=Bit[getMaxPos(l,r)]%2; if(minOE==1 && maxOE==0) return 1; # Šï < ‹ô if(minOE==0 && maxOE==1) return 2; # ‹ô < Šï if(minOE==1 && maxOE==1) return 3; # Šï <= Šï if(minOE==0 && maxOE==0) return 4; # ‹ô <= ‹ô return 0; # err } function getMinPos(l,r){ return ((Bit[l]=1 && Bit[from]<4){ --Bit[to]; Bit[from]+=2; } } } function cnvMoveNo(from,to, dir,n) { n=from*10; for(dir=0; dir<=2; ++dir) if(cnvPos[n+dir]==to) return n+dir; return -1; # err } function find(bit,who, dir) { for(dir=0; dir<=1; ++dir) if(Bit[pNo[who,dir]]==bit) return pNo[who,dir]; return -1; # not found } function findOEPos(dir,tgtOE,who, list,p,st,iim) { delete list; list[0]=getMinPos(pNo[who,0],pNo[who,1]); list[1]=findOtherPos(list[0],pNo[who,0],pNo[who,1]); st=(dir==1)?(0):(1); lim=(dir==1)?(2):(-1); for(p=st; p!=lim; p+=dir) if(Bit[list[p]]%2==tgtOE) return list[p]; return -1; # not found } function findOtherPos(tgt,l,r) { if(tgt==l) return r; if(tgt==r) return l; return -1; # not found } function move(from,to){ return moveMain(cnvMoveNo(from,to),from,to); } function moveBySW(sw){ return moveMain(sw,unpackUpper(sw),cnvPos[sw]); } function moveMain(sw,from,to) { dispHands(sw); printf("[#%02d] ... %s to %s.", Times, dirName(from), dirName(to)); pushEnter(); return sw; } function dirName(pos) { return sprintf("%s %s", ((pos>=7)?("My"):("Your")), ((pos==1 || pos==9)?("Left"):("Right"))); } ## ## lŠÔmain ## function man( sw) { #0... do{ sw=which(); dispHands(sw); printf(" OK?[Y/N]> "); }while(yorn()!="Y"); return sw; } function which( sw,tmp) { printf("[#%02d] Which", Times); for(;;){ printf("?> "); tmp=""; getline tmp; sw=mv[toupper(tmp)]; if(sw+0==0) sw=mv[tmp+0]; if(GAMEMODE==0){ if(sw==10 || sw==30) return sw; }else{ if((10<=sw && sw<=12) || (30<=sw && sw<=32)) return sw; } } return 0; # err } ## ## COM main ## function com() { if(CPULEVEL==0) return beginner(); return expert(); } function beginner( ev,minP,maxP,yEv,yMin,yMax,me,you) { me=1; you=0; ev=evalOddEven(me); minP=getMinPos(pNo[me,0],pNo[me,1]); maxP=findOtherPos(minP,pNo[me,0],pNo[me,1]); yEv=evalOddEven(you); yMin=getMinPos(pNo[you,0],pNo[you,1]); yMax=findOtherPos(yMin,pNo[you,0],pNo[you,1]); if(yEv!=4) if((Bit[minP]==3 && Bit[maxP]==5) || (Bit[minP]==4 && Bit[maxP]==4)) return move(minP, findOEPos(1,1,you)); if((Bit[minP]==3 && (Bit[maxP]==4 || Bit[maxP]==3)) && (Bit[yMin]==3 && Bit[yMax]==5)) return move(minP,yMin); if(Bit[minP]==2 && Bit[maxP]==5){ if(yEv!=3 && Bit[findOEPos(1,0,you)]>0) return move(minP, findOEPos(1,0,you)); return move(minP,maxP); } if(Bit[minP]==2 && Bit[maxP]==4 && Bit[yMin]==2 && Bit[yMax]==5) return move(minP,maxP); if(Bit[minP]==3 && Bit[maxP]==3 && Bit[yMin]==3 && Bit[yMax]==3) return move(minP,yMin) if(Bit[minP]==1 && Bit[maxP]==1 && Bit[yMin]==1 && Bit[yMax]==1) return move(minP,yMin); if(Times>2 && ev!=4 && yEv!=4){ if(Bit[minP]%2) return move(minP,findOEPos(1,1,you)); if(Bit[maxP]<5 && Bit[maxP]%2) return move(maxP,findOEPos(1,1,you)); } if(Bit[yMin]==4 && Bit[yMax]==5) if((Bit[minP]==0 || Bit[minP]==2) && (Bit[maxP]==0 || Bit[maxP]==2 || Bit[maxP]==4)) return move(minP,yMin); if(Bit[yMin]==4 && Bit[yMax]==5){ from=find(3,1); if(from>0) return move(from,yMax); from=find(1,1); if(from>0) return move(from,yMax); } if(ev==1 || ev==2){ from=findOEPos(1,0,me); to=findOtherPos(from,pNo[me,0],pNo[me,1]); }else{ from=minP; to=maxP; } return move(from,to); } function expert( mv,alpha,beta,cnt,v,p,lev) { #0....5 printf("\n ... thinking"); srand(); st=srand(); mv=0; alpha=-999; beta=999; cnt=((Times>SEARCHSTART)?(setApproach(1, 0, (lev=99))):(0)); if(cnt>0) backUp(lev); for(p=0; palpha){ alpha=v; mv=unpackUpper(approach[lev, p]); } if(alpha>=beta) break; } srand(); ed=srand(); printf(" (%dsec)\n", ed-st); if(mv) return moveBySW(mv); return beginner(); } function search(who,lev,alpha,beta, cnt,v,p,oth) { if((v=gameOver(who))>0) return phaseEvaluate(v,lev); oth=another(who); cnt=setApproach(who, oth, lev); if(cnt==0) return search(oth, lev, alpha, beta); backUp(lev); for(p=0; palpha) alpha=v; if(alpha>=beta) return alpha; } return alpha; } function phaseEvaluate(v,lev) { if(v==3) return 500+(99-lev); # Žè”Ôwho‚ÌŸ‚¿ if(v==2) return -500-lev; # Žè”Ôanother(who)‚ÌŸ‚¿ = Žè”Ôwho‚Ì•‰‚¯ return 0; # ‘o•ûŽè‹l‚Ü‚è = ˆø•ª } function tryMove(tgt, sw) { sw=unpackUpper(tgt); countUp(unpackLower(tgt), unpackUpper(sw), cnvPos[sw]); } # bkBit[ƒŒƒxƒ‹, 1`9] (ƒŒƒxƒ‹‚̓Xƒ^ƒbƒN‘ã‚è) function backUp(lev) { bkBit[lev,7]=Bit[7]; bkBit[lev,9]=Bit[9]; bkBit[lev,1]=Bit[1]; bkBit[lev,3]=Bit[3]; } function restore(lev) { Bit[7]=bkBit[lev,7]; Bit[9]=bkBit[lev,9]; Bit[1]=bkBit[lev,1]; Bit[3]=bkBit[lev,3]; } # approach[ƒŒƒxƒ‹, “YŽš] (ƒŒƒxƒ‹‚̓Xƒ^ƒbƒN‘ã‚è) function setApproach(who,oth,lev, cnt,sw,p,d,lr,dLast,hLast,ev) { cnt=0; dLast=((Bit[pNo[oth,0]]==Bit[pNo[oth,1]])?(1):(2)); hLast=((Bit[pNo[who,0]]==Bit[pNo[who,1]])?(0):(1)); for(d=0; d<=dLast; ++d) for(lr=0; lr<=hLast; ++lr){ sw=pack(pNo[who,lr], d); ev=canMoveFromTo(pNo[who,lr],cnvPos[sw]); if(ev>0) approach[lev, cnt++]=pack(sw,ev); } return cnt; } function pack(upper, lower){ return (upper*10+lower); } function unpackUpper(src){ return int(src/10); } function unpackLower(src){ return (src%10); }