使用Unity Engine和C#在代码中进行排序和二进制搜索

问题描述 投票:-1回答:2

我正在为学校目的做一份工作,然后它需要进入我和朋友一起创建的游戏中,每当太空飞船摧毁一个目标并更新分数时,通过升级等级中的点来进行某种排序,并且在这种情况发生后,实现二进制搜索方法(递归)或者甚至是二进制搜索的新方法,并返回Rank中玩家实际点的确切位置。但我试图将方法插入更新,但每次返回的位置是-1。

除此之外,重要的是要说两件事:第一,按升序排序和二进制搜索需要手动完成,每个if,else,for等进行排序和搜索,这是我的一个重要要求已经被要求做了,没有任何array.sort()方法等于我测试代码所做的,或者只用一行命令就可以完成统一的方法。

第二个也是更重要的,我每天都在尝试寻找和学习解决方案来移动元素和数组以使用条件情况和二分搜索,但我想我(学习艺术并有一个基本的编程逻辑来理解如何代码工作),当然并且仍然很难理解代码如何以及为什么这样做起作用,我正在尽我所能去理解和了解它,我上面提到的所有这些原因都是主要的我请求帮助的原因,因为我觉得这两个实现对于比我和我的伙伴(艺术家也是如此)有更多知识的人来说很容易。现在,请遵循以下代码:

public class GameController : MonoBehaviour
{

    public GameObject Hazard;
    public Vector3 SpawnValues;
    public int HazardCount;
    public float SpawnWait;
    public float StartWait;
    public float WaveWait;
    public GUIText ScoreText;
    private int Score;
    public GUIText RestartText;
    public GUIText GameOverText;
    public bool GameOver;
    private bool Restart;
    public List<int> Lista_Array;
    public int[] arr = { 0, 1, 2, 3, 4, 5 };

    IEnumerator SpawnWaves()
    {

        yield return new WaitForSeconds(StartWait);
        while (true)
        {
            for (int i = 0; i < HazardCount; i++)
            {
                Vector3 SpawnPosition = new Vector3(UnityEngine.Random.Range(-SpawnValues.x, SpawnValues.x), SpawnValues.y, SpawnValues.z);
                Quaternion SpawnRotation = Quaternion.identity;
                Instantiate(Hazard, SpawnPosition, SpawnRotation);
                yield return new WaitForSeconds(SpawnWait);
            }
            yield return new WaitForSeconds(WaveWait);

            if (GameOver)
            {
                RestartText.text = "Press 'B' to return to main menu or 'R' to restart";
                Restart = true;
                break;
            }
        }

    }

    public void UpdateScore()
    {
        ScoreText.text = "Score: " + Score;
        for (int i = 0; i < 1; i++)
        {
            //Lista_Array = new List<int>(Score);
            Lista_Array.Insert(0, Score);
            Lista_Array.Insert(0, 0);
            Lista_Array.Insert(0, 999);
            Lista_Array.Insert(0, 1999);
            Lista_Array.Insert(0, 2999);
            Lista_Array.Insert(0, 3999);
            arr = Lista_Array.ToArray();
            Lista_Array = new List<int>(Score);
            Array.Sort(arr); // Need to implement here manually some kind of sort by Ascending the Points in the Rank (Rank = Array and Points = Elements and Position = Position of Elements in the Array)
        }
    }

    public int BuscaBinaria(int[] arr, int l, int r, int x) //This is the Method of a Recursive Binary Search, but always return the position of -1
    {
        if (r >= 1)
        {
            int mid = 1 + (r - l) / 2;
            if (arr[mid] == x)
            {
                return mid;
            }
            if (arr[mid] > x)
            {
                return BuscaBinaria(arr, 1, mid - 1, x);
            }
            return BuscaBinaria(arr, mid + 1, r, x);
        }
        return -1; //Aqui era -1
    }


    public void AddScore(int NewScoreValue)
    {
        Score += NewScoreValue;
        UpdateScore();
        int n = arr.Length;
        int x = 10;
        int result = BuscaBinaria(arr, 0, n - 1, x);
        if (result == -1)
        {
            Debug.Log("Posicao nao encontrada");
        }
        else
        {
            Debug.Log("Posicao encontrada no Ranking " + result);
        }
    }

    public void gameOver()
    {
        GameOverText.text = "Game Over";
        GameOver = true;
    }

    public void Start()
    {
        GameOver = false;
        Restart = false;
        RestartText.text = "";
        GameOverText.text = "";
        Score = 0;
        StartCoroutine(SpawnWaves());
        UpdateScore();
    }

    void Update()
    {
        if(Restart){
            if(Input.GetKeyDown (KeyCode.B)){
                SceneManager.LoadScene ("Menu");
            }
        }

        if(Restart){
            if(Input.GetKeyDown (KeyCode.R)){
                Application.LoadLevel (Application.loadedLevel);
            }
        }

    }

}
c# sorting binary-search-tree
2个回答
0
投票

二进制搜索方法的一些问题:

public int BuscaBinaria(int[] arr, int l, int r, int x) //This is the Method of a Recursive Binary Search, but always return the position of -1
{
    if (r >= 1) // You do a recursive algorithm, so the exit criteria should not be,
                // as long as the right border is larger than 1, but the exit should
                // be if there is still a range, like if (r-l>0) or similar.
                // Otherwise you could end in a endless loop
    {
        int mid = 1 + (r - l) / 2; // the middle of r and l is (r+l)/2 !!!! 
                                   // try with l = 3 and r = 5. middle should be 4.
                                   // 1 + (5-3) /2 = 2; (5+3)/2 = 4;
        if (arr[mid] == x)
        {
            return mid;
        }
        if (arr[mid] > x)
        {
            return BuscaBinaria(arr, 1, mid - 1, x); // Index, problem. Your array has
                                      // a 0-based index, so you should call (arr, 0, mid-1, x)
        }
        return BuscaBinaria(arr, mid + 1, r, x);
    }
    return -1; //Aqui era -1
}

考虑此更改,然后重试。使用几个输入参数调试代码(编写unittest方法!),然后您将看到二进制搜索是否符合您的要求。


0
投票

感谢@ gofal3的所有帮助,对不起延迟回复我和我的团队伙伴完成的代码的答案和最终版本。现在,请遵循以下代码:

using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameController : MonoBehaviour
{

    public GameObject [] Hazards;
    public Vector3 SpawnValues;
    public int HazardCount;
    public float SpawnWait;
    public float StartWait;
    public float WaveWait;
    public GUIText ScoreText;
    private int Score;
    public GUIText RestartText;
    public GUIText GameOverText;
    public bool GameOver;
    private bool Restart;
    public List<int> Lista_Array;
    public int[] arr = { 0, 1, 2, 3, 4, 5 };

    IEnumerator SpawnWaves()
    {

        yield return new WaitForSeconds(StartWait);
        while (true)
        {
            for (int i = 0; i < HazardCount; i++)
            {
                GameObject Hazard = Hazards[UnityEngine.Random.Range(0, Hazards.Length)];
                Vector3 SpawnPosition = new Vector3(UnityEngine.Random.Range(-SpawnValues.x, SpawnValues.x), SpawnValues.y, SpawnValues.z);
                Quaternion SpawnRotation = Quaternion.identity;
                Instantiate(Hazard, SpawnPosition, SpawnRotation);
                yield return new WaitForSeconds(SpawnWait);
            }
            yield return new WaitForSeconds(WaveWait);

            if (GameOver)
            {
                RestartText.text = "Press 'B' to return to main menu or 'R' to restart";
                Restart = true;
                break;
            }
        }

    }

    public void UpdateScore()
    {
        ScoreText.text = "Score: " + Score;
        for (int i = 0; i < 1; i++)
        {
            //Lista_Array = new List<int>(Score);
            Lista_Array.Insert(0, Score);
            Lista_Array.Insert(0, 0);
            Lista_Array.Insert(0, 999);
            Lista_Array.Insert(0, 1999);
            Lista_Array.Insert(0, 2999);
            Lista_Array.Insert(0, 3999);
            arr = Lista_Array.ToArray();
            Lista_Array = new List<int>(Score);
            BubbleSort(arr);
            //Array.Sort(arr);
            //Lista_Array = arr.ToList();
            //Array_Lista = Lista_Array.ToArray();
        }
    }

    public int BuscaBinaria(int[] arr, int l, int r, int x)
    {
        if (r >= 1)
        {
            int mid = (r + l) / 2;
            if (arr[mid] == x)
            {
                return mid;
            }
            if (arr[mid] < x)
            {
                return BuscaBinaria(arr, 0, mid - 1, x); //aqui tbm
            }
            return BuscaBinaria(arr, mid + 1, r, x); //aqui tbm
        }
        return -1; //Aqui era -1
    }

    public static int[] BubbleSort(int[] arr1)
    {
        int length = arr1.Length;

        int temp = arr1[1];

        for (int i = 0; i < length; i++)
        {
            for (int j = i + 1; j < length; j++)
            {
                if (arr1[i] < arr1[j]) //mudei aqui
                {

                        temp = arr1[i];

                        arr1[i] = arr1[j];

                        arr1[j] = temp;
                }
            }
        }

        return arr1;
    }

    public void AddScore(int NewScoreValue)
    {
        Score += NewScoreValue;
        UpdateScore();
    }

    public void gameOver()
    {
        int n = arr.Length;
        int x = Score;
        int result = BuscaBinaria(arr, 0, n - 1, x);
        if (result == -1)
        {
            Debug.Log("Posicao nao encontrada");
        }
        else
        {
            Debug.Log("Posicao encontrada no Ranking " + result);
        }
        GameOverText.text = "Game Over";
        GameOver = true;
    }

    public void Start()
    {
        GameOver = false;
        Restart = false;
        RestartText.text = "";
        GameOverText.text = "";
        Score = 0;
        StartCoroutine(SpawnWaves());
        UpdateScore();
    }

    void Update()
    {
        if(Restart){
            if(Input.GetKeyDown (KeyCode.B)){
                SceneManager.LoadScene ("Menu");
            }
        }

        if(Restart){
            if(Input.GetKeyDown (KeyCode.R)){
                //Application.LoadLevel (Application.loadedLevel);
                SceneManager.LoadScene("Main");
            }
        }

    }

}
© www.soinside.com 2019 - 2024. All rights reserved.