ゲームを作りたい人のための ソースコード集

私がその日作った短めのソースを簡単な解説とともに載せていきます
ゲーム制作初心者にとって参考になるかもしれないソースが多いです


<< 角が丸い四角(線) | main | 多次元配列の拡張 >>



ゲーム木探索

オセロを使ったゲーム木探索アルゴリズムです

相手が三手先まで見て、最もひっくり返せる石の数が多い手を選びます

黒が自分、白が対戦相手です

 

 

#const global csz 64
#const global mc 8
#const global mr 8
#module
    ;石が置ける場所をチェック
    #defcfunc putcheck int x,int y,array bdmap,array dlst,int p
        ref=0
        d8x=-1,-1,0,1,1,1,0,-1
        d8y=0,-1,-1,-1,0,1,1,1
        if p=0{tp=1}else{tp=0}
        if bdmap(x,y)=-1{
            repeat length(d8x):d=cnt
                dlst(d)=0
                i=x+d8x(d)
                j=y+d8y(d)
                if 0<=i&i<mc&0<=j&j<mr{
                    if bdmap(i,j)=tp{
                        repeat
                            i+d8x(d)
                            j+d8y(d)
                            if 0<=i&i<mc&0<=j&j<mr{
                                if bdmap(i,j)=p{
                                    dlst(d)=1
                                    ref=1
                                    break
                                }else:if bdmap(i,j)=-1{
                                    break
                                }
                            }else{
                                break
                            }
                            await
                        loop
                    }
                }
            loop
        }
        return ref
    ;相手の石を裏返す
    #defcfunc stonechange int x,int y,array bdmap,array dlst,int p
        d8x=-1,-1,0,1,1,1,0,-1
        d8y=0,-1,-1,-1,0,1,1,1
        bdmap(x,y)=p
        ref=0
        repeat length(d8x):d=cnt
            if dlst(d)=0:continue
            i=x:j=y
            repeat
                i+d8x(d)
                j+d8y(d)
                if bdmap(i,j)=p{
                    break
                }else:if bdmap(i,j)=-1{
                    break
                }
                bdmap(i,j)=p
                ref++
            loop
        loop
        return ref
#global
dim bdmap,mc,mr
repeat mr:j=cnt
    repeat mc:i=cnt
        bdmap(i,j)=-1
    loop
loop
bdmap(3,3)=0
bdmap(4,4)=0
bdmap(4,3)=1
bdmap(3,4)=1
d8x=-1,-1,0,1,1,1,0,-1
d8y=0,-1,-1,-1,0,1,1,1
dim dlst,8

turnflg=0
buffer 2,mc*csz,mr*csz:color 1:boxf:color ,125
repeat mr:j=cnt
    y=j*csz+1
    repeat mc:i=cnt
        x=i*csz+1
        boxf x,y,x+csz-2,y+csz-2
    loop
loop

buffer 3,2*csz,csz:celdiv 3,csz,csz:boxf:x=0:y=0
color 1:circle x+4,y+4,x+csz-4,y+csz-4:x+csz
color 255,255,255:circle x+4,y+4,x+csz-4,y+csz-4:x+csz

screen 0,mc*csz,mr*csz:gmode 2
repeat
    if turnflg=0{
        gosub *playerturn
    }else{
        gosub *opponentturn
    }
    redraw:await 17:redraw 0
loop

*playerturn        ;自分ターン
    repeat
        ok1=k1:getkey k1,1:tk1=k1^ok1&k1:rk1=k1^ok1&ok1
        if tk1{
            putx=mousex/csz
            puty=mousey/csz
            putflg=putcheck(putx,puty,bdmap,dlst,0)
            if putflg=1{
                chgnum=stonechange(putx,puty,bdmap,dlst,0)
            }
            if putflg=1{
                turnflg=1
            }
        }
        gosub *boarddraw
        redraw:await 17:redraw 0
        if turnflg=1{
            break
        }
    loop
    return
*opponentturn    ;相手ターン
    bddtlen=mc*mr*4
    dim stbdmap,mc,mr
    dim edbdmap,mc,mr
    dim queue,8,100000
    dim q_bdmap,mc*mr,100000
    dim queuepart,2,3+1:queuepart(0,0)=0,1
    st=0:ed=1:turnflg=0:chkturn=0:turnnum=0
    queue(0,ed)=chgnum,i,j,st,d,turnflg,turnnum
    memcpy q_bdmap,bdmap,bddtlen
    repeat:turnnum=queue(6,st)+1    ;ゲーム木探索
        if turnnum<=3{
            if chkturn<turnnum{
                chkturn=turnnum
                queuepart(0,chkturn)=ed
            }
            memcpy stbdmap,q_bdmap,bddtlen,0,st*bddtlen
            turnflg=queue(5,st)^1
            repeat mr:j=cnt
                repeat mc:i=cnt
                    putflg=putcheck(i,j,stbdmap,dlst,turnflg)
                    if putflg=1{
                        memcpy edbdmap,stbdmap,bddtlen,0,0
                        chgnum=stonechange(i,j,edbdmap,dlst,turnflg)
                        queue(0,ed)=chgnum,i,j,st,d,turnflg,turnnum
                        
                        memcpy q_bdmap,edbdmap,bddtlen,ed*bddtlen,0
                        queuepart(1,chkturn)++
                        ed++
                    }
                loop
            loop
        }
        st++
        if st>=ed:break
        await
    loop
    if chkturn¥2=1{
    }else:if chkturn>1{
        chkturn-1
    }
    evalnum=-1:evalid=0

    ;3手先でひっくり返せる数が最も多い手を選ぶ
    repeat queuepart(1,chkturn),queuepart(0,chkturn)
        if evalnum<queue(0,cnt){
            evalid=cnt
            evalnum=queue(0,cnt)
        }
    loop
    if evalid>0{
        repeat
            if queue(3,evalid)=0{
                break
            }else{
                evalid=queue(3,evalid)
            }
        loop
        memcpy bdmap,q_bdmap,bddtlen,0,evalid*bddtlen
    }
    turnflg=0
    return
*boarddraw    ;盤面表示
    pos 0,0:gcopy 2,,,mc*csz,mr*csz
    repeat mr:j=cnt
        repeat mc:i=cnt
            if bdmap(i,j)>=0{
                pos i*csz,j*csz:celput 3,bdmap(i,j)
            }
        loop
    loop
    return

0
    posted by higashijugem 13:42comments(0)|-|


    この記事に対するコメント