简体   繁体   English

如何使用二维数组检查“连续 4 个”? 请注意,我没有使用“numpy”,因为我对编码非常陌生

[英]How do I check for a "4 in a row" with a 2d array? Note that I'm not using "numpy" as I am extremely new to coding

I've got a connect 4 game using turtles.我有一个使用海龟的 connect 4 游戏。 I've got a 2d array with 6 rows of 7. I don't know how to make a list check for 4 in a row.我有一个 6 行 7 的二维数组。我不知道如何连续检查 4 个列表。 It's connect four so it needs to check for diagonally, horizontally, and vertically.它连接四个,因此需要检查对角线、水平和垂直方向。 This is my list:这是我的清单:

c4board = [[0]*7 for _ in range(6)]

I have a turtle over each column that when clicked will insert an item into the list via this:我在每一列上都有一个乌龟,单击它时将通过以下方式将一个项目插入列表中:

def x2click(x,y):
  global currentturn
  global x2rowcor
  checker = trtl.Turtle()
  checker.ht()
  checker.shape("circle")
  checker.turtlesize(2)
  checker.color(currentturn)
  checker.penup()
  checker.goto(-80, x2rowcor)
  checker.st()
  x2rowcor += 40
  listxcor2 = ((x2rowcor+80)/40)-1
  print(listxcor2)
  checkerplaced()
  if c4board[5][1] == 0:
    c4board[5][1] = onetwo
    print(c4board)
  elif c4board[4][1] == 0:
    c4board[4][1] = onetwo
    print(c4board)
  elif c4board[3][1] == 0:
    c4board[3][1] = onetwo
    print(c4board)
  elif c4board[2][1] == 0:
    c4board[2][1] = onetwo
    print(c4board)
  elif c4board[1][1] == 0:
    c4board[1][1] = onetwo
    print(c4board)
  elif c4board[0][1] == 0:
    c4board[0][1] = onetwo
    print(c4board)
  if x2rowcor > 120:
    c2.ht()
    x2.ht()

I have tried to check for the turtle colors instead but found that to be a dead end.我曾尝试检查乌龟 colors,但发现这是一个死胡同。

I have tried to use Numpy but as I said I'm somewhat new to coding (I've only been doing python for a few months) Numpy was quite confusing to me, and I couldnt figure out how to get it to work.我曾尝试使用 Numpy,但正如我所说,我对编码有些陌生(我只做了几个月的 python)Numpy 让我很困惑,我不知道如何让它工作。

If there isn't a way to do it without Numpy, please explain it to me like you would a 10 year old.如果没有 Numpy 就没有办法做到这一点,请像 10 岁的孩子一样向我解释。

If you want my full 500+ lines of code, you can ask but i didnt want to put all of that in my question.如果你想要我完整的 500 多行代码,你可以问,但我不想把所有这些都放在我的问题中。

You shouldn't fear numpy it is a very handy tool.你不应该害怕numpy它是一个非常方便的工具。 To install it simply use pip install numpy from the command line in the same invironment you are using python.要安装它,只需在与 python 相同的环境中从命令行使用pip install numpy numpy。


Having numpy at hand the conditions I use are 1 for player 1 and 2 for player 2 .手头有 numpy,我使用的条件是1代表player 1 2代表player 2 Now we can navigate through every 4x4 subfield of the game board to check for "four in a row of 1 or 2 "现在我们可以浏览游戏板的每个4x4子字段以检查“四个连续12

# Import numpy to your script via this statement at the top of the file.
import numpy as np


def check_victory(board: np.array) -> int:
    """
    Navigating through all 4x4 subfields and check for victory condition
    of either player. 
    :returns: 1 or 2 of player 1 or 2 has won, 0 otherwise.
    """
    for row in range(7 - 4):
        for col in range(8 - 4):
            v = check_subfield(board[row:row + 4, col:col + 4])
            if v > 0:
                return v
    return 0


def check_subfield(field: np.array) -> int:
    # check diagonal.
    v = same_number(np.diagonal(field))
    if v > 0:
        return v
    for i in range(4):
        # check column
        v = same_number(field[i, :])
        if v > 0:
            return v
        # check row
        v = same_number(field[:, i])
        if v > 0:
            return v
    return 0

def same_number(values: list) -> int:
    return int((values == values[0]).all() * values[0])

All methods will return as soon as a victory condition is met to avoid superflous checks.一旦满足胜利条件,所有方法都会返回,以避免多余的检查。 There are more sophisticated ways to check this (see rolling windows , etc.), but this version should be somewhat beginner friendly with a not too high level of abstraction and library use.有更复杂的方法来检查这个(参见rolling windows等),但这个版本应该对初学者有点友好,抽象和库使用的级别不太高。 I hope this gives you a readable and understandable example.我希望这能为您提供一个可读且易于理解的示例。


Now, with this set of methods at hand, we can easily test this:现在,有了这组方法,我们可以很容易地测试它:

# We can create an empty 6x7 game board (zeros everywhere) 
# by using the `numpy.zeros` method with the desired shape:
c4board = np.zeros((6, 7))
print(check_victory(c4board))
# Out[0] = 0

c4board[2, 1] = 1
c4board[2, 2] = 1
c4board[2, 3] = 1
c4board[2, 4] = 1
print(check_victory(c4board))
# Out[1] = 1

c4board = np.zeros((6, 7))
c4board[2, 1] = 1
c4board[2, 2] = 1
c4board[2, 4] = 1
c4board[5, 3] = 2
c4board[5, 4] = 2
c4board[5, 5] = 2
c4board[5, 6] = 2
print(check_victory(c4board))
# Out[2] = 2

c4board = np.zeros((6, 7))
c4board[2, 2] = 1
c4board[3, 3] = 1
c4board[4, 4] = 1
c4board[5, 5] = 1
c4board[5, 4] = 2
print(check_victory(c4board))
# Out[3] = 1

Ok, and if you insist to do it without numpy : here you go: (I really recommend getting used to numpy, though)好吧,如果你坚持不使用numpy的话:给你 go:(不过我真的建议你习惯 numpy)

def check_victory(board: list) -> int:
    for row in range(7 - 4):
        for col in range(8 - 4):
            # This part is now much more effort
            sub_field = [[board[i][j] for i in range(row, row+4)] for j in range(col, col+4)]
            v = check_subfield(sub_field)
            if v > 0:
                return v
    return 0


def check_subfield(field: list) -> int:
    # Note the change in syntax and list construction.
    # check diag.
    v = same_number([field[i][i] for i in range(4)])
    if v > 0:
        return v
    for i in range(4):
        # check row
        v = same_number(field[i])
        if v > 0:
            return v
        # check column
        v = same_number([field[j][i] for j in range(4)])
        if v > 0:
            return v
    return 0


def same_number(values: list) -> int:
    if all(v == 1 for v in values):
        return 1
    if all(v == 2 for v in values):
        return 2
    return 0

This cann be as easily checked as above这可以像上面一样容易检查

c4board = [[0 for _ in range(7)] for _ in range(6)]
c4board[2][2] = 1
c4board[3][3] = 1
c4board[4][4] = 1
c4board[5][5] = 1
c4board[5][4] = 2
print(check_victory(c4board))
# Out[4] = 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM