用 go 写的五子棋预测算法

详细请看Github:https://github.com/shanhuijie/GoWatch/tree...
five in a row(五子棋成功预测)
从横、纵、 左斜升、 左斜降 四个角度判断
欢迎探讨


package fiveinarow

import(
    "sort"
    "math"
)
const(
    Vertical = 100
    Level = 100
    matrix = Vertical * Level
    point  =  4
)
type Coordinat struct{
    X       int
    Y       int
    Color   string
}

type Allinat struct{
    Key     []Coordinat
}

func InArray(need Coordinat, needArr []Coordinat) bool {
    for _,v := range needArr{
       if v == need {
           return true
       }
   }
   return false
}

func inverted(tmp []int) bool {             //倒序检查
    var i int
    for k := len(tmp)-1; k>=0;k--{  
        if k == 0{                          //最后一个下标说明无法对比
            return false
        }
        if tmp[k]-1 == tmp[k]{              //说明值是连续数字
            i++
            if i == point{                  //如果达到连续数就返回
                return true
            }
        }else{
            i = 0
        }
    }
    return false
}

func postive(tmp []int) (bool,int) {            //正序检查
    var i int
    for ck, cv := range tmp {
        if ck == len(tmp)-1{                //最后一个下标说明无法对比
            return false,-1
        }
        if cv+1 == tmp[ck+1] {              //说明值是连续数字
            i++
            if i == point{                  //如果达到连续数就返回
                return true,ck+1
            }
        }else{
            i = 0
        }
    }
    return false,-1
}

func Slope(inat *Allinat,coor Coordinat) (bool,[]Coordinat) {
    var (
        Xmax,Xmin int = coor.X+4,coor.X-4
        Ymax,Ymin int = coor.Y+4,coor.Y-4
        j,p     int
        lrise,lfall  Coordinat
        lrtmp,lftmp []Coordinat
    )
    if Xmin < 0 {
        Xmin = 0
    }
    if Ymin < 0 {
        Ymin = 0
    }
    for i:=1; i<=Xmax-Xmin; i++{
            lrise.X,lrise.Y,lrise.Color = coor.X,coor.Y,coor.Color
            lrise.X = lrise.X+i
            lrise.Y = lrise.Y+i
        if lrise.X > Xmax || lrise.Y > Ymax{
            lrise.X,lrise.Y,lrise.Color = coor.X,coor.Y,coor.Color
            lrise.X = Xmax-i
            lrise.Y = Ymax-i
            if lrise.X > Xmax || lrise.Y < Ymin {
                continue
            }
        } 
        if lrise.X == Xmax || lrise.Y==Ymax {
            if j > 0 && j != point {
                j = 0
                lrtmp = []Coordinat{}
            }
        }
        if InArray(lrise,inat.Key) {
            lrtmp = append(lrtmp,lrise)
            j++
            if j == point{
                lrtmp = append(lrtmp,coor)
                return true,lrtmp
            }
        }else{
            if i>=1 && i<= (Xmax-Xmin)/2 {
                if Xmax < 5{
                    continue
                }
                if coor.X+i>=Xmax && j<point{
                    j = 0
                    lrtmp = []Coordinat{}
                    continue
                }
                    i = int(math.Ceil(float64((Xmax-Xmin)/2)))
                    lrise.X = coor.X-1
                    lrise.Y = coor.Y-1
                    if !InArray(lrise,inat.Key){
                        j = 0
                        lrtmp = []Coordinat{}
                    }
                    continue
            }
            j = 0
            lrtmp = []Coordinat{}
        }
    }

    for ii:=1; ii<=Xmax-Xmin; ii++{
            lfall.X,lfall.Y,lfall.Color = coor.X,coor.Y,coor.Color
            lfall.X = lfall.X+ii
            lfall.Y = lfall.Y-ii
        if lfall.X > Xmax || lfall.Y < Ymin {
            lfall.X,lfall.Y,lfall.Color = coor.X,coor.Y,coor.Color
            lfall.X = Xmax-ii
            lfall.Y = Ymax-Ymin+ii
            if lfall.X > Xmin || lfall.Y > Ymax {
                continue
            }
        }
        if InArray(lfall,inat.Key) {
            lftmp = append(lftmp,lfall)
            p++
            if p == point{
                lftmp = append(lftmp,coor)
                return true,lftmp
            }
        }else{
            if ii>=1 && ii<= (Xmax-Xmin)/2 {
                if Xmax < 5{
                    continue
                }
                    ii = int(math.Ceil(float64((Xmax-Xmin)/2)))
                    lfall.X = coor.X+1
                    lfall.Y = coor.Y-1
                    if !InArray(lfall,inat.Key){
                        p = 0
                        lftmp = []Coordinat{}
                        continue
                    }
                if (coor.X+ii)>=Xmax && p<point{
                    p = 0
                    lftmp = []Coordinat{}
                }
                continue
            }
            p = 0
            lftmp = []Coordinat{}
        }
    }
    return false,[]Coordinat{}
}

func lengthwaysORcrosswise(inat *Allinat,coor Coordinat,S string) (bool,[]Coordinat) {
    var (
        max,min int = coor.X+4,coor.X-4
        tmp     []int
        lcinat  []Coordinat
    )
    if min < 0 {
        min = 0
    }
    for _,c := range inat.Key{
        if S == "c" {
            if (max >= c.X && c.Y == coor.Y && c.Color == coor.Color) || (min >= c.X  && c.Y == coor.Y && c.Color == coor.Color){
                tmp = append(tmp,c.X)
            }
        }else{
            if (max >= c.Y && c.X == coor.X && c.Color == coor.Color) || (min >= c.Y  && c.X == coor.X && c.Color == coor.Color){
                tmp = append(tmp,c.Y)
            }
        }
    }
    sort.Ints(tmp)
    pbool ,pint := postive(tmp)
    if pbool == true {
        ci := pint
        for pi := 0; pi <= point; pi++{
            if S == "c"{
                lcinat = append(lcinat,Coordinat{tmp[ci],coor.Y,coor.Color})
            }else{
                lcinat = append(lcinat,Coordinat{coor.X,tmp[ci],coor.Color})
            }
            ci--
        }
        return true,lcinat
    }else{
        return false,lcinat
    }
    // ibool ,iint := inverted(tmp)
    // if (inverted(tmp) == true) || (postive(tmp) == true) {
    //  return true
    // }
    // return false
}

func IsFive(inat *Allinat,coor Coordinat) (bool,[]Coordinat) {
    // if lengthwaysORcrosswise(inat,coor,"l") == true || lengthwaysORcrosswise(inat,coor,"c") == true || Slope(inat,coor) == true{
    //  return true
    // }
    // return false
    sis,sarr := Slope(inat,coor);if sis == true{
        return true,sarr
    }else{
        return false, []Coordinat{}
    }

    // lis,larr := lengthwaysORcrosswise(inat,coor,"l"); if lis == true{
    //  return true,larr
    // }
    // cis,carr := lengthwaysORcrosswise(inat,coor,"c"); if cis == true{
    //  return true,carr
    // }

}

func (inat *Allinat)AddCoordinat(coor Coordinat) (bool,[]Coordinat) {
    for _,coslice := range inat.Key{
        if coslice.X == coor.X && coslice.Y == coor.Y{
            return false, []Coordinat{}
        }
    }
    c,allfive := IsFive(inat,coor)
    if c == false{                              //not finish five
        inat.Key = append(inat.Key,coor)
        return false, []Coordinat{}
    }
    return true,allfive

}
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 4年前 自动加精
讨论数量: 2

格式炸了

4年前 评论
Frisk-matin (楼主) 4年前
lmaster

go 为什么在 laravel 里面?

go 有论坛的啊

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!