连接四游戏逻辑

-2 投票
1 回答
583 浏览
提问于 2025-04-18 10:58

我正在用Python和tkinter开发一个四子连珠游戏。

我已经设计好了棋盘和两个玩家的棋子。现在我想检查一下游戏是否结束。我实现了以下逻辑,但似乎没有效果。

def checkWin():
        for row in range(canvas.data.rows):
            for col in range(canvas.data.cols):
                checkWinFromCell(row, col)

def checkWinFromCell(row, col):
        if canvas.data.board[row][col] == 0:
            return False
        dirs = [[0,1], [1,0], [1,1], [1,-1], [0,-1], [-1,0], [-1,-1], [-1,1]]
        for direction in dirs:
            checkWinFromCellInDir(row, col, direction)
        return False

def checkWinFromCellInDir(row, col, direction):
        drow, dcol = direction[0], direction[1]
        for i in range(1,4):
            if row+i*drow<0 or row+i*drow>=canvas.data.rows or col+i*dcol<0 or col+i*dcol>=canvas.data.cols:
                return False
            if canvas.data.board[row][col] != canvas.data.board[row+i*drow][col+i*dcol]:
                return False
        return canvas.data.board[row][col]

我需要知道怎么判断我的游戏是否结束,也就是四个棋子是否已经连成一线。

1 个回答

0

我对Tkinter不是很熟悉,所以这算是个不太完整的回答。不过因为已经快一个小时了还没有人回答,我就给你写了一个。

class Map(list):
    def __init__(self, tiles, width, height):
        """This object functions exactly as a tile map for your connect four
        game. It is a subclass of list, so you can iterate through its rows.
        "y" increases from top to bottom and "x" increases from left to right"""
        for y in range(height):
            self.append([random.choice(tiles) for x in range(width)])
            # for ease of use, we're generating a random tile map here
    def __str__(self):
        return '\n'.join([' '.join([ch for ch in row]) for row in self])
        # this will make print(map_object) show something pretty

Vector = collections.namedtuple("Vector", ['x','y'])
# build a namedtuple to contain our directions. It's a bit easier on the eyes
# to use object access, IMO. YMMV.

def checkwin(map_):
    directions = [Vector(x, y) for (x, y) in [(1, 0), (-1, 1), (0, 1), (1, 1)]]
    # directions = E, SW, S, SE
    for y, row in enumerate(map_):
        for x, ch in enumerate(row):
            value = ch
            if value == ' ': continue # blank squares can't win
            for vector in directions:
                result = checkfour(map_, x, y, vector)
                if result:
                    return result
            return False

def checkfour(map_, x, y, vector):
    """Checks map_ for four squares from the given x and y in vector direction"""
    value = map_[y][x]
    try:
        lst = [map_[y + k*vector.y][x + k*vector.x]==value for k in range(1,4)]
        # 2 2 2 1 would return [True, True, False]
        return all(lst) and (x,y)
    except IndexError:
        return False
        # we know we'll run off the edge of the map. It's cheaper (in programmer
        # time) to simply return False here rather than check each square to make
        # sure there ARE 3 more squares in vector-direction.

map_ = Map("12 ", 8, 8)
print(checkwin(map_))
# if your randomly generated map would win in connect four, it should print
# the first (x,y) coordinate that begins a win going E, SW, S, or SE
print(map_)

撰写回答