N queen C# algorithm Unity3D

using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using UnityEngine;

namespace Assets.NetSyncDemo.Test
{
    // N皇后C#算法
    public class TestNQueen : MonoBehaviour
    {
        private void Start()
        {
            int n = 8;
            var result = SolveQueue(n);
            UnityEngine.Debug.Log($"皇后 行数={n}, 排列方法={result.Count}");
            int index = 0;
            foreach (var solve in result)
            {
                UnityEngine.Debug.Log("方法" + index +": \n" + PrintQueue(solve));
                index++;
            }
        }

        private readonly int[] dirX = new int[] { -1, -1, -1,  0,  0,  1,  1,  1 };
        private readonly int[] dirY = new int[] { -1,  0,  1, -1,  1, -1,  0,  1 };
        private List<List<List<bool>>> SolveQueue(int count)
        {
            List<List<List<bool>>> result = new List<List<List<bool>>>();
            var attack = new List<List<bool>>();
            var queen = new List<List<bool>>();
            for(int i = 0; i < count; i++)
            {
                var attackI = new List<bool>();
                var queenI = new List<bool>();
                for (int j = 0; j < count; j++)
                {
                    attackI.Add(false);
                    queenI.Add(false);
                }
                attack.Add(attackI);
                queen.Add(queenI);
            }
            BackTrace(0, count, ref attack, ref queen, ref result);
            return result;
        }


        private void BackTrace(int lineIndex, int count, ref List<List<bool>> attack, 
            ref List<List<bool>> queen, ref List<List<List<bool>>> result)
        {
            if (lineIndex == count)
            {
                result.Add(Clone<List<bool>>(queen));
            }
            else
            {
                for(int i = 0; i < count; i++)
                {
                    if(attack[lineIndex][i] == false)
                    {
                        List<List<bool>> tmpAttack = Clone<List<bool>>(attack);
                        queen[lineIndex][i] = true;
                        InsertQueen(lineIndex, i, count, ref attack);
                        BackTrace(lineIndex + 1, count, ref attack, ref queen, ref result);
                        attack = tmpAttack;
                        queen[lineIndex][i] = false;
                    }
                }
            }
        }

       

        private void InsertQueen( int x, int y, int count, ref List<List<bool>> attack)
        {
            attack[x][y] = true;
            int dx, dy;
            for(int i = 0; i < count; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    dx = x + i * dirX[j];
                    dy = y + i * dirY[j];
                    if(dx >= 0 && dx < count && dy >= 0 && dy < count)
                    {
                        attack[dx][dy] = true;
                    }
                }
            }
        }

        private static List<T> Clone<T>(object list)
        {
            using (Stream objectStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, list);
                objectStream.Seek(0, SeekOrigin.Begin);
                return formatter.Deserialize(objectStream) as List<T>;
            }
        }

        private static string PrintQueue(List<List<bool>> list)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var row in list)
            {
                foreach (var col in row)
                {
                    sb.Append(col ? 1 : 0);
                }
                sb.AppendLine();
            }
            return sb.ToString();
        }
    }
}

 

Guess you like

Origin blog.csdn.net/PangNanGua/article/details/118088929