Example #1
0
def check_terminal(board: np.ndarray,
                   _last_action: Optional[PlayerAction] = None) -> bool:
    ''' check if the board is a "terminal" board: a win or a draw'''

    board1 = board.copy()
    board2 = board.copy()

    board1[board1 == PLAYER1] = NO_PLAYER
    board1[board1 == PLAYER2] = BoardPiece(1)

    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board1, kernel, 1, 0, 0, BoardPiece(0))
        if np.any(result == CONNECT_N):
            return True

    board2[board2 == PLAYER2] = NO_PLAYER
    board2[board2 == PLAYER1] = BoardPiece(1)

    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board2, kernel, 1, 0, 0, BoardPiece(0))
        if np.any(result == CONNECT_N):
            return True

    if np.count_nonzero(board) == board.shape[0] * board.shape[1]:
        return True

    return False
Example #2
0
def position_value(board: np.ndarray,
                   player: BoardPiece,
                   _last_action: Optional[PlayerAction] = None) -> bool:
    """
    Returns the heuristic value to the given plaer of a complete board
    """

    board1 = board.copy()
    board2 = board.copy()

    other_player = BoardPiece(player % 2 + 1)
    board1[board1 == other_player] = 5
    board1[board1 == player] = BoardPiece(1)

    board2[board2 == player] = BoardPiece(5)
    board2[board2 == other_player] = BoardPiece(1)

    value = 0

    # scoring central positions
    center = board[:, board.shape[1] // 2]
    value += (center == player).sum() * 10
    value += (center == other_player).sum() * -5

    # checking remainin positions
    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board1, kernel, 1, 0, 0, BoardPiece(0))
        for i in result:
            for sum in i:
                if sum == CONNECT_N:
                    value += 200

                if sum == CONNECT_N - 1:
                    value += 50

                if sum == CONNECT_N - 2:
                    value += 10

    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board2, kernel, 1, 0, 0, 0)
        for i in result:
            for sum in i:
                if sum == CONNECT_N:
                    value += -250

                if sum == CONNECT_N - 1:
                    value += -55

                if sum == CONNECT_N - 2:
                    value += -12

    return int(value)
Example #3
0
    def conv2d(self, img, kern, mode="valid"):
        """
        Basic slow python implementatation for DebugMode
        """

        if not imported_scipy_signal:
            raise NotImplementedError(
                "AbstractConv perform requires the python package"
                " for scipy.signal to be installed.")
        if not (mode in ('valid', 'full')):
            raise ValueError(
                'invalid mode {}, which must be either '
                '"valid" or "full"'.format(mode))

        out_shape = get_conv_output_shape(img.shape, kern.shape, mode, [1, 1])
        out = numpy.zeros(out_shape, dtype=img.dtype)
        val = _valfrommode(mode)
        bval = _bvalfromboundary('fill')

        with warnings.catch_warnings():
            warnings.simplefilter('ignore', numpy.ComplexWarning)
            for b in xrange(img.shape[0]):
                for n in xrange(kern.shape[0]):
                    for im0 in xrange(img.shape[1]):
                        # some cast generates a warning here
                        out[b, n, ...] += _convolve2d(img[b, im0, ...],
                                                      kern[n, im0, ...],
                                                      1, val, bval, 0)
        return out
Example #4
0
    def conv2d(self, img, kern, mode="valid"):
        """
        Basic slow python implementatation for DebugMode
        """

        if not imported_scipy_signal:
            raise NotImplementedError(
                "AbstractConv perform requires the python package"
                " for scipy.signal to be installed.")
        if not (mode in ('valid', 'full')):
            raise ValueError(
                'invalid mode {}, which must be either '
                '"valid" or "full"'.format(mode))

        out_shape = get_conv_output_shape(img.shape, kern.shape, mode, [1, 1])
        out = numpy.zeros(out_shape, dtype=img.dtype)
        val = _valfrommode(mode)
        bval = _bvalfromboundary('fill')

        with warnings.catch_warnings():
            warnings.simplefilter('ignore', numpy.ComplexWarning)
            for b in xrange(img.shape[0]):
                for n in xrange(kern.shape[0]):
                    for im0 in xrange(img.shape[1]):
                        # some cast generates a warning here
                        out[b, n, ...] += _convolve2d(img[b, im0, ...],
                                                      kern[n, im0, ...],
                                                      1, val, bval, 0)
        return out
Example #5
0
def check_result(board: np.ndarray,
                 player: BoardPiece,
                 _last_action: Optional[PlayerAction] = None) -> bool:
    ''' check if the board is a "terminal" board: a win or a draw
    and assigns a value to each option that can be used by an evaluation function'''

    board1 = board.copy()
    board2 = board.copy()

    MinPiece = 3 - player

    MaxPiece = player

    board1[board1 == MinPiece] = NO_PLAYER
    board1[board1 == MaxPiece] = BoardPiece(1)

    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board1, kernel, 1, 0, 0, BoardPiece(0))
        if np.any(result == CONNECT_N):
            # print(time)
            # print(MaxPiece)
            # print("won")
            return 1  #self wins

    board2[board2 == MaxPiece] = NO_PLAYER
    board2[board2 == MinPiece] = BoardPiece(1)

    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board2, kernel, 1, 0, 0, BoardPiece(0))
        if np.any(result == CONNECT_N):
            # print(time)
            # print(MinPiece)
            # print("lost")
            return -0.1  #opponent wins

    if np.count_nonzero(board) == board.shape[0] * board.shape[1]:
        # print(board)
        # print("draw")
        return 0  #draw

    return False
Example #6
0
def convolve2d(in1, in2, mode='full', boundary='fill', fillvalue=0):
    """
    Convolve two 2-dimensional arrays.
    Convolve `in1` and `in2` with output size determined by `mode`, and
    boundary conditions determined by `boundary` and `fillvalue`.
    Parameters
    ----------
    in1, in2 : array_like
        Two-dimensional input arrays to be convolved.
    mode : str {'full', 'valid', 'same'}, optional
        A string indicating the size of the output:
        ``full``
           The output is the full discrete linear convolution
           of the inputs. (Default)
        ``valid``
           The output consists only of those elements that do not
           rely on the zero-padding.
        ``same``
           The output is the same size as `in1`, centered
           with respect to the 'full' output.
    boundary : str {'fill', 'wrap', 'symm'}, optional
        A flag indicating how to handle boundaries:
        ``fill``
           pad input arrays with fillvalue. (default)
        ``wrap``
           circular boundary conditions.
        ``symm``
           symmetrical boundary conditions.
    fillvalue : scalar, optional
        Value to fill pad input arrays with. Default is 0.
    Returns
    -------
    out : ndarray
        A 2-dimensional array containing a subset of the discrete linear
        convolution of `in1` with `in2`.
    """
    in1 = asarray(in1)
    in2 = asarray(in2)

    if mode == 'valid':
        _check_valid_mode_shapes(in1.shape, in2.shape)

    val = _valfrommode(mode)
    bval = _bvalfromboundary(boundary)

    with warnings.catch_warnings():
        warnings.simplefilter('ignore', np.ComplexWarning)
        # FIXME: some cast generates a warning here
        out = sigtools._convolve2d(in1, in2, 1, val, bval, fillvalue)

    return out
Example #7
0
def connected_four(board: np.ndarray,
                   player: BoardPiece,
                   _last_action: Optional[PlayerAction] = None) -> bool:
    board = board.copy()

    other_player = BoardPiece(player % 2 + 1)
    board[board == other_player] = NO_PLAYER
    board[board == player] = BoardPiece(1)

    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board, kernel, 1, 0, 0, BoardPiece(0))
        if np.any(result == CONNECT_N):
            return True
    return False
Example #8
0
def _conv2d(img, kern, mode="valid", dilation=(1, 1), groups=1):
    """Basic slow Python 2D or 3D convolution for DebugMode

    Copied and simplified from Theano (2020/11/08):
    https://github.com/Theano/Theano/blob/master/theano/tensor/nnet/abstract_conv.py
    """
    convdim = 2
    assert mode in ("valid", "full")
    out_shape = _get_conv_output_shape(img.shape, kern.shape, mode,
                                       [1] * convdim, dilation)

    dil_kern_shp = kern.shape[:-convdim] + tuple(
        (kern.shape[-convdim + i] - 1) * dilation[i] + 1
        for i in range(convdim))
    dilated_kern = np.zeros(dil_kern_shp, dtype=kern.dtype)

    dilated_kern[(slice(None), ) * (dilated_kern.ndim - convdim) +
                 tuple(slice(None, None, dilation[i])
                       for i in range(convdim))] = kern
    out = np.zeros(out_shape, dtype=img.dtype)

    input_channel_offset = img.shape[1] // groups
    output_channel_offset = kern.shape[0] // groups

    val = _valfrommode(mode)
    bval = _bvalfromboundary("fill")

    with warnings.catch_warnings():
        warnings.simplefilter("ignore", np.ComplexWarning)
        for b in range(img.shape[0]):
            for g in range(groups):
                for n in range(output_channel_offset):
                    for im0 in range(input_channel_offset):
                        # some cast generates a warning here
                        out[b, g * output_channel_offset + n,
                            ...] += _convolve2d(
                                img[b, g * input_channel_offset + im0, ...],
                                dilated_kern[g * output_channel_offset + n,
                                             im0, ...],
                                1,
                                val,
                                bval,
                                0,
                            )

    return out
Example #9
0
def connected_four(board: np.ndarray,
                   player: BoardPiece,
                   _last_action: Optional[PlayerAction] = None) -> bool:
    """
   Returns True if there are four adjacent pieces equal to `player` arranged
   in either a horizontal, vertical, or diagonal line. Returns False otherwise.
   If desired, the last action taken (i.e. last column played) can be provided
   for potential speed optimisation.
    """
    board = board.copy()

    other_player = BoardPiece(player % 2 + 1)
    board[board == other_player] = NO_PLAYER
    board[board == player] = BoardPiece(1)

    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board, kernel, 1, 0, 0, BoardPiece(0))
        if np.any(result == 4):
            return True
    return False
Example #10
0
def negamax_heuristic(board: np.ndarray, player: BoardPiece) -> float:
    """
    A heuristic for negamax -- the weighted sum of n-in-a-row for the current board.

    :param board: current board
    :param player: the player to play
    :return: selected move
    """
    board = board.copy()

    other_player = BoardPiece(player % 2 + 1)
    board[board == other_player] = -1
    board[board == player] = 1
    score = 0

    # if a move results in blocking a loss, return it

    for n in range(2, CONNECT_N+1):
        weight = weights[n-1]
        for _, kernel in enumerate(kernels[n]):
            result = _convolve2d(board, kernel, 1, 0, 0, BoardPiece(0))
            score += weight * np.sum(result == (n - 1))
    return score
Example #11
0
    def _own_correlate(self,
                       Europa_map,
                       Sandbox_data,
                       mode='full',
                       boundary='fill',
                       fillvalue=0) -> Tuple[int, int]:
        in1 = np.asarray(Europa_map)
        in2 = np.asarray(Sandbox_data)

        if not in1.ndim == in2.ndim == 2:
            raise ValueError('_own_correlate inputs must both be 2D arrays')

        swapped_inputs = True  #np._inputs_swap_needed(mode, in1.shape, in2.shape)
        if swapped_inputs:
            in1, in2 = in2, in1

        #val = _valfrommode(mode)
        #bval = _bvalfromboundary(boundary)
        out = sigtools._convolve2d(in1, in2.conj(), 0)

        if swapped_inputs:
            out = out[::-1, ::-1]

        ascent = misc.ascent()
        fig, (ax_orig, ax_mag, ax_ang) = plt.subplots(3, 1, figsize=(6, 15))
        ax_orig.imshow(ascent, cmap='gray')
        ax_orig.set_title('Original')
        ax_orig.set_axis_off()
        ax_mag.imshow(np.absolute(out), cmap='gray')
        ax_mag.set_title('Gradient magnitude')
        ax_mag.set_axis_off()
        ax_ang.imshow(np.angle(out), cmap='hsv')  # hsv is cyclic, like angles
        ax_ang.set_title('Gradient orientation')
        ax_ang.set_axis_off()
        fig.show()

        return out
Example #12
0
def connected_four(
    board: np.ndarray,
    player: BoardPiece,
    last_action: Optional[PlayerAction] = None,
) -> bool:
    """
    Returns True if there are four adjacent pieces equal to `player` arranged
    in either a horizontal, vertical, or diagonal line. Returns False otherwise.
    If desired, the last action taken (i.e. last column played) can be provided
    for potential speed optimisation.
    """

    # from Owen Mackwood's connected_four_convolve
    board = board.copy()

    # other_player = BoardPiece(player % 2 + 1)
    # flat = board.flatten()  # to play nice with numba have to use 1d boolean indexing
    # flat[flat == other_player] = BoardPiece(0)
    # flat[flat == player] = BoardPiece(1)
    # board = flat.reshape(board.shape)

    other_player = BoardPiece(player % 2 + 1)
    board[board == other_player] = NO_PLAYER
    board[board == player] = BoardPiece(1)

    # TODO: add condition for if last_action provided
    # if last_action:
    #     result = _convolve2d(board, kernel, 1
    #     , 0, 0, BoardPiece(0))

    for kernel in (col_kernel, row_kernel, dia_l_kernel, dia_r_kernel):
        result = _convolve2d(board, kernel, 1, 0, 0, BoardPiece(0))
        # result = np.convolve(board, kernel)
        if np.any(result == CONNECT_N):
            return True
    return False
Example #13
0
def exec_multilayer_conv_nnet_old(conv_mode,
                                  ss,
                                  bsize,
                                  imshp,
                                  kshps,
                                  nkerns,
                                  unroll_batch=0,
                                  unroll_kern=0,
                                  img=T.dmatrix(),
                                  validate=True,
                                  conv_op_py=False,
                                  do_print=True,
                                  repeat=1,
                                  unroll_patch=False,
                                  unroll_patch_size=False,
                                  verbose=0):

    # build actual input images
    imgval = global_rng.rand(bsize, imshp[0], imshp[1], imshp[2])

    a = T.dmatrix()
    kerns = [a for i in nkerns]
    inputs4 = dmatrix4()
    kerns4 = dmatrix4()

    # for each layer
    ntot = 0
    tctot = 0
    tpytot = 0

    for kshp, kern, nkern, n_layer in zip(kshps, kerns, nkerns,
                                          range(len(nkerns))):
        if do_print:
            print '************* layer %i ***************' % n_layer

            print conv_mode, ss, n_layer, kshp, nkern

        # actual values
        w = global_rng.random_sample(N.r_[nkern, imshp[0], kshp])
        w_flip = flip(w, kshp).reshape(w.shape)

        ## manual implementation
        # check first stage
        padimg = imgval
        if conv_mode == 'full':
            padimg_shp = N.array(
                imshp[1:]) + 2 * (N.array(kshp) - N.array([1, 1]))
            padimg = N.zeros(N.r_[bsize, imshp[0], padimg_shp])
            padimg[:, :, kshp[0] - 1:-kshp[0] + 1,
                   kshp[1] - 1:-kshp[1] + 1] = imgval

        outshp = N.hstack(
            (nkern, ConvOp.getOutputShape(imshp[1:], kshp, ss, conv_mode)))

        time1 = time.time()
        outval = N.zeros(N.r_[bsize, outshp])
        if validate:
            # causes an atexit problem
            from scipy.signal.sigtools import _convolve2d
            from scipy.signal.signaltools import _valfrommode, _bvalfromboundary
            val = _valfrommode(conv_mode)
            bval = _bvalfromboundary('fill')
            for b in range(bsize):  # loop over batches
                for n in range(nkern):  # loop over filters
                    for i in range(imshp[0]):  # loop over input feature maps
                        outval[b,n,...] +=  _convolve2d(\
                            imgval[b,i,...], w_flip[n,i,...],1,val, bval, 0)[0::ss[0],0::ss[1]]
            ntot += time.time() - time1

        # ConvOp
        if unroll_patch and not unroll_patch_size:
            conv_op = ConvOp(dx=ss[0],
                             dy=ss[1],
                             output_mode=conv_mode,
                             unroll_patch=unroll_patch,
                             verbose=verbose)(inputs4, kerns4)
        else:
            conv_op = ConvOp(imshp,
                             kshp,
                             nkern,
                             bsize,
                             ss[0],
                             ss[1],
                             conv_mode,
                             unroll_batch=unroll_batch,
                             unroll_kern=unroll_kern,
                             unroll_patch=unroll_patch,
                             verbose=verbose)(inputs4, kerns4)
        l1shp = N.hstack(
            (nkern, ConvOp.getOutputShape(imshp[1:], kshp, ss, conv_mode)))
        propup2 = function([inputs4, kerns4], conv_op)
        propup3 = function([inputs4, kerns4], conv_op, mode=Mode(linker="py"))

        time1 = time.time()
        for i in range(repeat):
            hidval2_ = propup2(imgval, w_flip)
        hidval2 = hidval2_  #[:,:,0::ss[0],0::ss[1]]
        tctot += time.time() - time1

        if conv_op_py:
            time1 = time.time()
            for i in range(repeat):
                hidval3_ = propup3(imgval, w_flip)
            hidval3 = hidval3_  #[:,:,0::ss[0],0::ss[1]]
            tpytot += time.time() - time1
            assert (N.abs(hidval2 - hidval3) < 1e-5).all()
        else:
            tpytot += 0

        if validate:
            temp = N.abs(outval - hidval2)
            assert (temp < 1e-5).all()
        if validate and conv_op_py:
            temp = N.abs(outval - hidval3)
            assert (temp < 1e-5).all()

        imshp = tuple(outshp)
        imgval = outval.reshape(bsize, outshp[0], outshp[1], outshp[2])

    return tctot, tpytot, ntot
Example #14
0
def exec_multilayer_conv_nnet_old(
    conv_mode,
    ss,
    bsize,
    imshp,
    kshps,
    nkerns,
    unroll_batch=0,
    unroll_kern=0,
    img=T.dmatrix(),
    validate=True,
    conv_op_py=False,
    do_print=True,
    repeat=1,
    unroll_patch=False,
    unroll_patch_size=False,
    verbose=0,
):

    # build actual input images
    imgval = global_rng.rand(bsize, imshp[0], imshp[1], imshp[2])

    a = T.dmatrix()
    kerns = [a for i in nkerns]
    inputs4 = dmatrix4()
    kerns4 = dmatrix4()

    # for each layer
    ntot = 0
    tctot = 0
    tpytot = 0

    for kshp, kern, nkern, n_layer in zip(kshps, kerns, nkerns, xrange(len(nkerns))):
        if do_print:
            print("************* layer %i ***************" % n_layer)
            print(conv_mode, ss, n_layer, kshp, nkern)

        # actual values
        w = global_rng.random_sample(N.r_[nkern, imshp[0], kshp])
        w_flip = flip(w, kshp).reshape(w.shape)

        # manual implementation
        # check first stage
        padimg = imgval
        if conv_mode == "full":
            padimg_shp = N.array(imshp[1:]) + 2 * (N.array(kshp) - N.array([1, 1]))
            padimg = N.zeros(N.r_[bsize, imshp[0], padimg_shp])
            padimg[:, :, kshp[0] - 1 : -kshp[0] + 1, kshp[1] - 1 : -kshp[1] + 1] = imgval

        outshp = N.hstack((nkern, ConvOp.getOutputShape(imshp[1:], kshp, ss, conv_mode)))

        time1 = time.time()
        outval = N.zeros(N.r_[bsize, outshp])
        if validate:
            # causes an atexit problem
            from scipy.signal.sigtools import _convolve2d
            from scipy.signal.signaltools import _valfrommode, _bvalfromboundary

            val = _valfrommode(conv_mode)
            bval = _bvalfromboundary("fill")
            for b in xrange(bsize):  # loop over batches
                for n in xrange(nkern):  # loop over filters
                    for i in xrange(imshp[0]):  # loop over input feature maps
                        outval[b, n, ...] += _convolve2d(imgval[b, i, ...], w_flip[n, i, ...], 1, val, bval, 0)[
                            0 :: ss[0], 0 :: ss[1]
                        ]
            ntot += time.time() - time1

        # ConvOp
        if unroll_patch and not unroll_patch_size:
            conv_op = ConvOp(dx=ss[0], dy=ss[1], output_mode=conv_mode, unroll_patch=unroll_patch, verbose=verbose)(
                inputs4, kerns4
            )
        else:
            conv_op = ConvOp(
                imshp,
                kshp,
                nkern,
                bsize,
                ss[0],
                ss[1],
                conv_mode,
                unroll_batch=unroll_batch,
                unroll_kern=unroll_kern,
                unroll_patch=unroll_patch,
                verbose=verbose,
            )(inputs4, kerns4)
        # l1shp = N.hstack((nkern,
        #                ConvOp.getOutputShape(imshp[1:], kshp, ss, conv_mode)))
        propup2 = function([inputs4, kerns4], conv_op)
        propup3 = function([inputs4, kerns4], conv_op, mode=Mode(linker="py"))

        time1 = time.time()
        for i in xrange(repeat):
            hidval2_ = propup2(imgval, w_flip)
        hidval2 = hidval2_  # [:,:,0::ss[0],0::ss[1]]
        tctot += time.time() - time1

        if conv_op_py:
            time1 = time.time()
            for i in xrange(repeat):
                hidval3_ = propup3(imgval, w_flip)
            hidval3 = hidval3_  # [:,:,0::ss[0],0::ss[1]]
            tpytot += time.time() - time1
            assert (N.abs(hidval2 - hidval3) < 1e-5).all()
        else:
            tpytot += 0

        if validate:
            temp = N.abs(outval - hidval2)
            assert (temp < 1e-5).all()
        if validate and conv_op_py:
            temp = N.abs(outval - hidval3)
            assert (temp < 1e-5).all()

        imshp = tuple(outshp)
        imgval = outval.reshape(bsize, outshp[0], outshp[1], outshp[2])

    return tctot, tpytot, ntot