深度复制一个数组C#不序列化 [英] Deep copying an array c# without serialization

查看:166
本文介绍了深度复制一个数组C#不序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上我有那些打算我的 MINMAX 算法不是真正的工作问题。

我需要的是,以使我的数组件被复制到 newPieces 时,不会改变 newPieces

下面是 MINMAX 算法的摘录:

 私人诠释MINMAX(
    INT深度,片[]块,布尔blacksTurn,
    清单<移动和​​GT;移动,游戏的游戏,INTα,移动的NextMove){    件[] = newPieces新的作品[24];
    移动= Game.possibleMoves(件,blacksTurn,FALSE);
    如果(深== 0 || Moves.Count == 0){
        返回评估(参考件);
    }    int值;    如果(blacksTurn ==真){
        的foreach(移动我移动){
            newPieces = DeepCopy.ObjectExtensions.Copy(件);
            game.MovePiece(newPieces,blacksTurn,i.Moving,i.Destination,真正的);
            game.DisplayBoard(件);
            值= MINMAX(深度-1,newPieces,blacksTurn,移动,游戏,阿尔法,的NextMove!);            如果(阿尔法>的值){
                阿尔法=价值;
                的NextMove = I;
            }    // ...

下面是件类。

  [StructLayout(LayoutKind.Sequential)]
公共类件
{    公共CellReference位置;
    公共BOOL isBlack {搞定;组; }
    公共BOOL isKing {搞定;组; }
    私人int值{搞定;组; }
    公共BOOL采取{搞定;组; }    公共件()
    {    }    公共件(INT I,布尔采取isBlack,布尔isKing,诠释CellsEast,诠释CellsNorth,布尔)
    {
        THIS.VALUE = I;
        Location.CellsEast = CellsEast;
        Location.CellsNorth = CellsNorth;
        this.isBlack = isBlack;
        this.isKing = isKing;
        this.taken =服用;
    }
}


解决方案

因为这添加属性类/结构

 使用System.Runtime.InteropServices;

  [StructLayout(LayoutKind.Sequential)]
公共类件{

而code是继

 命名空间deepcopy的{
    公共静态类ObjectExtensions {
        公共静态T []复制< T>(这件T []件){
            返回pieces.Select(X => {
                VAR手柄= Marshal.AllocHGlobal(Marshal.SizeOf(typeof运算(T)));                尝试{
                    Marshal.StructureToPtr(X,拉手,FALSE);
                    回报(T)Marshal.PtrToStructure(手柄的typeof(T));
                }
                最后{
                    Marshal.FreeHGlobal(手柄);
                }
            })ToArray的()。
        }
    }
}

我临时修改 Piece.Value 来的测试是公开的,并与一个测试类测试

 公共静态部分类识别TestClass {
    公共静态无效TestDeepCopy(件[]件){
        件[] = newPieces新的作品[24];        newPieces = DeepCopy.ObjectExtensions.Copy(件);        newPieces [0] .isKing = TRUE;
        newPieces [0]。价值= 3;        newPieces [1] .isKing =真;
        newPieces [1] .taken =真;
        newPieces [1]。价值= 4;        Console.WriteLine(=== newPieces ===);
        的foreach(在newPieces VAR X)
            Console.WriteLine(
                x.isKing = {0}; x.isBlack = {1}; x.Value = {2},
                x.isKing,x.isBlack,x.Value
                );        Console.WriteLine();
        Console.WriteLine(===件===);
        的foreach(在片变种X)
            Console.WriteLine(
                x.isKing = {0}; x.isBlack = {1}; x.Value = {2},
                x.isKing,x.isBlack,x.Value
                );
    }    公共静态无效StartTest(){
        VAR pieceA =新片(1,假的,假的,1,1,FALSE);
        VAR pieceB =新片(2,真,假,1,1,FALSE);
        VAR件=新[] {pieceA,pieceB};
        TestDeepCopy(件);
    }
}

和它的作品。为了进行测试,通话

  TestClass.StartTest();

Basically I have the problem that my MinMax algorithm isn't really working as intended.

What I need is to make my array pieces be copied to newPieces so that pieces isn't changed when newPieces is.

Here is an extract of the MinMax algorithm:

private int MinMax(
    int depth, Piece[] pieces, bool blacksTurn, 
    List<Move> Moves, Game game, int alpha, Move nextMove) {

    Piece[] newPieces=new Piece[24];
    Moves=Game.possibleMoves(pieces, blacksTurn, false);
    if(depth==0||Moves.Count==0) {
        return Evaluation(ref pieces);
    }

    int value;

    if(blacksTurn==true) {
        foreach(Move i in Moves) {
            newPieces=DeepCopy.ObjectExtensions.Copy(pieces);
            game.MovePiece(newPieces, blacksTurn, i.Moving, i.Destination, true);
            game.DisplayBoard(pieces);
            value=minMax(depth-1, newPieces, !blacksTurn, Moves, game, alpha, nextMove);

            if(alpha>value) {
                alpha=value;
                nextMove=i;
            }

    // ... 

Here is the Piece class.

[StructLayout(LayoutKind.Sequential)]
public class Piece
{

    public CellReference Location;
    public bool isBlack { get; set; }
    public bool isKing { get; set; }
    private int Value { get; set; }
    public bool taken { get; set; }

    public Piece()
    {

    }

    public Piece(int i, bool isBlack, bool isKing, int CellsEast, int CellsNorth, bool taken)
    {
        this.Value = i;
        Location.CellsEast = CellsEast;
        Location.CellsNorth = CellsNorth;
        this.isBlack = isBlack;
        this.isKing = isKing;
        this.taken = taken;
    }
}

解决方案

Add attribute as this to class/structure Piece:

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public class Piece {

And the code is following

namespace DeepCopy {
    public static class ObjectExtensions {
        public static T[] Copy<T>(this T[] pieces) {
            return pieces.Select(x => {
                var handle=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)));

                try {
                    Marshal.StructureToPtr(x, handle, false);
                    return (T)Marshal.PtrToStructure(handle, typeof(T));
                }
                finally {
                    Marshal.FreeHGlobal(handle);
                }
            }).ToArray();
        }
    }
}

I temporarily modify Piece.Value to be public for the test, and have tested with a test class

public static partial class TestClass {
    public static void TestDeepCopy(Piece[] pieces) {
        Piece[] newPieces=new Piece[24];

        newPieces=DeepCopy.ObjectExtensions.Copy(pieces);

        newPieces[0].isKing=true;
        newPieces[0].Value=3;

        newPieces[1].isKing=true;
        newPieces[1].taken=true;
        newPieces[1].Value=4;

        Console.WriteLine("=== newPieces ===");
        foreach(var x in newPieces)
            Console.WriteLine(
                "x.isKing={0}; x.isBlack={1}; x.Value={2}",
                x.isKing, x.isBlack, x.Value
                );

        Console.WriteLine();
        Console.WriteLine("=== pieces ===");
        foreach(var x in pieces)
            Console.WriteLine(
                "x.isKing={0}; x.isBlack={1}; x.Value={2}",
                x.isKing, x.isBlack, x.Value
                );
    }

    public static void StartTest() {
        var pieceA=new Piece(1, false, false, 1, 1, false);
        var pieceB=new Piece(2, true, false, 1, 1, false);
        var pieces=new[] { pieceA, pieceB };
        TestDeepCopy(pieces);
    }
}

and it works. To perform the test, call

TestClass.StartTest();

这篇关于深度复制一个数组C#不序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆