Проблема с numpy-логическими операциями

Я создаю игру. В игре у меня есть массив numpy (квадрат), который начинается с 0s. Игроки заполняют массив, добавляя их назначенное целое в определенное место. Игра выиграна игроком, который заполняет всю строку, столбец, диагональ или диагональ (?) С их номером. В настоящее время это моя функция, которая проверяет успех игры.

У меня есть две проблемы: 1. Я хочу, чтобы функция проверяла успех ALL игрока и возвращала кортеж (т. Е. (True, 2), если игрок выиграл 2), а не по одному за раз. Как работает игра, никогда не будет двух игроков, которые выиграли, так что это не проблема. У меня будет список всех игроков, играющих (т.е. [1,2,3,4] для 4 игроков), которые я могу передать функции. 2. Мне не нужен цикл «для», потому что я хочу сделать это для множества итераций.

Я борется с логическими операторами в numpy, но я не хочу менять это на список или что-то еще.

def check_success(gm,player): #gm is game array
            for i in range(len(gm)):
                if (not any(gm[i]-player)) or (not any(gm[:,i]-player)):
                    return True
            if (not any(np.diag(gm)-player)) or (not any(np.diag(np.fliplr(gm))-player)):
                return True
            return False

Примечание. Я подозреваю, что проблема № 1 не может быть решена без цикла for. Если это так, я предпочитаю, чтобы проблема №2 была решена. Я всегда могу запустить функцию несколько раз, потому что количество игроков, безусловно, будет намного меньше, чем размер gm.

python,list,numpy,integer,logic,

0

Ответов: 1


1 принят

Обновление: оптимизированный код и контрольные показатели:

Задержки

>>> stress_test(4, 1000, 2, 0, 0)
OP  : 0.322599 ms
pp0 : 0.451822 ms
pp1 : 0.140838 ms
>>> 
>>> stress_test(10, 1000, 4)
OP  : 1.051070 ms
pp0 : 0.425230 ms
pp1 : 0.166876 ms

Код

import numpy as np

def f_OP(board, p):
    for cp in range(1, p+1):
        if check_success(board, cp):
            return True, cp
    else:
        return False, 0

def check_success(gm,player): #gm is game array
            for i in range(len(gm)):
                if (not any(gm[i]-player)) or (not any(gm[:,i]-player)):
                    return True
            if (not any(np.diag(gm)-player)) or (not any(np.diag(np.fliplr(gm))-player)):
                return True
            return False

def f_pp0(board, dummy=None):
    for b in (board, board.T, np.einsum('ii->i', board)[:, None],
              np.einsum('ii->i', board[::-1])[:, None]):
        L = np.diff(b, axis=0).any(axis=0) | (b[0] == 0)
        ind = L.argmin()
        if not L[ind]:
            return True, b[0, ind]
    return False, 0

def f_pp1(board, dummy=None):
    D = np.einsum('ii->i', board)
    DP = D != 0
    if DP[0] and (D[0] == D).all():
        return True, D[0]
    L = DP & (D == board).all(0)
    I = L.argmax()
    if L[I]:
        return True, D[I]
    L = DP & (D == board.T).all(0)
    I = L.argmax()
    if L[I]:
        return True, D[I]
    D = np.einsum('ii->i', board[::-1])
    if D[0] and (D[0] == D).all():
        return True, D[0]
    return False, 0

def stress_test(n, k, p, wr=0.1, fr=0.4):
    from timeit import timeit
    data = np.random.randint(1, p+1, (k, n, n))
    data *= np.random.random((k, n, n)) < fr
    w = np.where(np.random.random((k,)) < wr)[0][:, None]
    pw = np.random.randint(1, p+1, w.shape)
    wp = np.random.randint(-2, 2*n, w.shape)
    i = np.where(wp < n, np.arange(n), wp-n)
    j = np.where((wp >= n) | (wp < 0), np.arange(n), wp)
    j[wp.ravel()==-1, :] == np.arange(n)[::-1]
    data[w, i, j] = pw
    glb = dict(data=data, p=p)
    kwds = dict(number=10, globals=glb)
    ref = None
    for f, glb['f'] in globals().items():
        if f.startswith('f_'):
            print('{:<4s}: {:8.6f} ms'.format(f[2:], timeit("for d in data: f(d, p)", **kwds) * 1000 / k))
            if ref is None:
                ref = np.array([glb['f'](d, p) for d in data])
                print(np.count_nonzero(ref))
            else:
                assert (ref == np.array([glb['f'](d, p) for d in data])).all()
питон, список, NumPy, целое число, логика,
Похожие вопросы