关于五子棋,胜负判断的优化(绕圈圈问题有感)

基础

搭建棋盘(粗略的过一遍)

ROUND_SIZE=7 #棋盘大小
MAX_COUNT=5 #胜利条件
board=[]

#画棋盘
def initBorad():
    for i in range(ROUND_SIZE):
       row = [' □  '] * ROUND_SIZE
       board.append(row)


#在控制台输出棋盘的方法
def printBoard():
    for i in range(ROUND_SIZE):
        for j in range(ROUND_SIZE):
            print(board[i][j],end="")

        print()
				
if __name__ == '__main__':
    initBorad()
    printBoard()
    inputStr = input("请输入你下棋的坐标,应以x,y的格式:\n")
		  #注意构建的棋盘是以(0,0)为起点的,输入的时候是以(1,1)为起点的
    while inputStr != None:
        x_str, y_str = inputStr.split(sep=",") 
				board[int(y_str) - 1][int(x_str) - 1] = ' ●  '
        printBoard()
        inputStr = input("请继续输入你下棋的坐标,应以x,y的格式:\n")       

判断重复落子问题

def repeatBoad(x,y):
    str = board[int(y)-1][int(x)-1]
    if str == ' ●  ':
        print("\t 棋子重复")
        return False
    else:
        return True

(重点)判断胜负问题

胜利条件是同色五子连线

每次你落子时,此时棋子的坐标为(x,y)以此点为基点,可分为横向,纵向,斜向上,斜向下,4个方向,此时我们把每一个方向都看作一个一维list,这样就避免考虑了边界问题,以及各种判断问题,问题就简化为以下两个方面

1 求各个方向的list
2 求各个list的最大重数问题

接下来我们先解决最大重复数问题

求一个list的最大重复数
import itertools

a=[1,1,1,1,2,2,2,2,2,3,3,1,1,1,3]

print ( max([len(list(v)) for k, v in itertools.groupby(a) ]) )

求一个list的指定数字的最大重复数

#求1的自大重复数
import itertools

a=[1,1,1,1,2,2,2,2,2,3,3,1,1,1,3]

print ( max([len(list(v)) for k, v in itertools.groupby(a) if k==1]) )

横向检测

求当前落子x轴的所有元素

#检测横线方向
def hengxian(x,y):
    hen_list =[]
    for i  in range(ROUND_SIZE):
        str = board[int(y)][int(i)]
        hen_list.append(str)
    max_count = max([len(list(v)) for k, v in itertools.groupby(hen_list) if k ==' ●  '])
    if max_count==MAX_COUNT:
        print("玩家胜利")
        return True
    else:
        return False

纵向检测

求当前落子y轴的所有元素

#检测纵向
def zongxiang(x,y):
    zong_list=[]
    for i in range(ROUND_SIZE):
        str = board[int(i)][int(x)]
        zong_list.append(str)

    max_count = max([len(list(v)) for k, v in itertools.groupby(zong_list) if k ==' ●  '])
    if max_count==MAX_COUNT:
        print("玩家胜利")
        return True
    else:
        return False

斜线向上检测

这里以7*7的棋盘举例以(1,7),(2,6),(3,5),(4,4),(5,3),(6,2),(7,1)这条斜线通过观察我们可的斜线上的x+y的值都相等
#对角检测(即斜向上)
def duijiao(x,y):
    duijiao_list = []
    for i in range(ROUND_SIZE):
        for j in range(ROUND_SIZE):
            if  x+y == j+i:
                str = board[int(j)][int(i)]
                duijiao_list.append(str)

    max_count = max([len(list(v)) for k, v in itertools.groupby(duijiao_list) if k == ' ●  '])
    if max_count == MAX_COUNT:
        print("玩家胜利")
        return True
    else:
        return False

斜向下检测

这里还是以7*7的棋盘举例以(6,1),(7,2)这条斜线 以及(1,6),(2,7)为例 可以发现|x-y|的绝对值都相等

#(x>=y)时
#斜线检测
def xiexian_down(x,y):
    xiexian_list=[]
    for i  in range(ROUND_SIZE):
        for j in range(ROUND_SIZE):
             if x>=y and (x-y ==(i-j)):
                 str = board[int(j)][int(i)]
                 xiexian_list.append(str)

    max_count = max([len(list(v)) for k, v in itertools.groupby(xiexian_list) if k ==' ●  '])
    if max_count==MAX_COUNT:
        print("玩家胜利")
        return True
    else:
        return False
				
#(x<y)时
#斜线检测				
def xiexian_up(x, y):
    xiexian_list = []
    for i in range(ROUND_SIZE):
        for j in range(ROUND_SIZE):
            if x <= y and (y - x == (j - i)):
                str = board[int(j)][int(i)]
                xiexian_list.append(str)

    max_count = max([len(list(v)) for k, v in itertools.groupby(xiexian_list) if k == ' ●  '])
    if max_count == MAX_COUNT:
        print("玩家胜利")
        return True
    else:
        return False				

修改主程序

if __name__ == '__main__':
    initBorad()
    printBoard()
    inputStr = input("请输入你下棋的坐标,应以x,y的格式:\n")
    while inputStr != None:
        x_str, y_str = inputStr.split(sep=",")
        if repeatBoad(x_str,y_str):
            # 为对应的列表元素赋值' ●  '
            board[int(y_str) - 1][int(x_str) - 1] = ' ●  '
            printBoard()
            if sucess_failure(int(x_str) - 1, int(y_str) - 1): #判断胜负
                break
            else:
                inputStr = input("请继续输入你下棋的坐标,应以x,y的格式:\n")

        else:
            printBoard()
            inputStr = input("请重新输入你下棋的坐标,应以x,y的格式:\n")

完整demo

胜负判断问题搞定,还有很多未完善的地方,未完待续

评论