Сортировка и бинарный поиск в коде с Unity Engine и C # - PullRequest
0 голосов
/ 07 ноября 2018

Я делаю работу для школьных целей, а затем в Игре, которую я создаю с другом, требовалось использовать что-то вроде Поднятия очков в ранге каждый раз, когда космический корабль уничтожает цель и обновляет Подсчитайте, а после этого реализуйте метод бинарного поиска (рекурсивный) или даже новый метод бинарного поиска и верните точную позицию фактических очков игрока в ранге. Но я пытался вставить метод в обновление, но каждый раз возвращаемая позиция равна -1.

Кроме того, важно сказать две вещи: во-первых, сортировку по возрастанию и бинарный поиск нужно выполнять вручную с каждым, если, иначе, для и т. Д. Для выполнения сортировки и поиска это одна важная вещь. Требование, которое меня попросили сделать, - ни один из методов 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);
            }
        }

    }

}

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Спасибо @ 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");
            }
        }

    }

}
0 голосов
/ 12 ноября 2018

Некоторые проблемы с вашим методом двоичного поиска:

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!), И вы увидите, выполняет ли ваш двоичный поиск то, что вы хотите.

...