阵列扫描治疗

时间:2019-05-06 12:57:52

标签: c# arrays

我的战舰有问题,更确切地说是进入治疗问题。如果我在阵列中选择要拍摄的坐标(X =第一个坐标,Y =第二个坐标),那么我可以在阵列中选择相同的坐标更多次,我想修复它。 我的意思是我想只选择一次而不是多次选择特定的坐标(数组索引)。

谢谢您的帮助。

有一个代码: 抱歉,如果我在论坛上输入错误代码。

namespace Battleship

{
    class Program 
    {
        static void Main(string[] args) 
        {
            string continue = "yes";  
            while (continue == "yes")
            {
                Console.WriteLine(); 
                Console.WriteLine("----Battleship-----"); 
                Console.WriteLine();
                Console.WriteLine("Your name"); 
                string jmeno = Console.ReadLine(); 
                Console.WriteLine();
                Console.WriteLine("Hit left 7x");
                Console.WriteLine();
                Hodnoty h = new Hodnoty(); 
                while (h.Trefa < 7) 
                {
                    h.Zadej();                 
                }
                Console.Clear(); 
                Console.WriteLine(name + " won!!!"); 
                Console.WriteLine();
                Console.WriteLine(name + " se trefil/a " + h.Trefa + "x"); 
                Console.WriteLine(name + " miss " + h.Vedle + "x");
                Console.WriteLine("Do you wanna play again? [yes/no]"); 
                pokracovat = Console.ReadLine(); 
            }
            Console.Clear();
            Console.WriteLine("Click on Enter"); 
            Console.ReadLine();

        }



        class Hodnoty 
        {

            public int Hit = 0; 
            public int left = 0; 
            int left = 0; 
            int x = 0; 
            int y = 0; 
            string cislo; 
            int hodnota; 

//MAIN PROBLEM (I Guess)
//------------------------------------------------------------------------------
public void Zadej() /
{
    var mapa = new char[5, 5]; 


    using (var reader = new StreamReader("Lode.txt")) 
    {
        Console.WriteLine("  ¦ 01234"); 
        Console.WriteLine("  ¦----------");
        for (var i = 0; i < 5; i++) 
        {
            Console.Write((i).ToString() + " ¦ "); 
            var pole = reader.ReadLine(); 
            for (var j = 0; j < 5; j++) 
            {
                mapa[i, j] = char.Parse(pole[j].ToString()); 

            }
            Console.WriteLine();
        }
    }

    Console.WriteLine();
    Console.Write("Enter coordinates X = "); 
    cislo = Console.ReadLine(); 
    if (int.TryParse(cislo, out hodnota)) 
    {
        x = hodnota;

    }

    else
    {
        Console.WriteLine("Enter number");
    }

    Console.Write("Enter bumber Y = "); 
    cislo = Console.ReadLine(); 
    if (int.TryParse(cislo, out hodnota)) 
    {
        y = hodnota; 
    }

    else
    {
        Console.WriteLine("Enter number");

    }

    if (mapa[x, y].Equals('X')) 
    {
        Console.Clear();
        Console.WriteLine("-----Battleship-----");
        Console.WriteLine();
        Trefa += 1; 
        Zbyva = 7 - Trefa; 
        Console.WriteLine("Hit " + Hit + "x "); 
        Console.WriteLine();
        Console.WriteLine("hits left " + left + "x"); 
        Console.WriteLine();
    }
    else 
    {
        Console.Clear();
        Console.WriteLine("-----Battleship-----");
        Console.WriteLine();
        Vedle += 1; 
        Console.WriteLine("Miss " + Miss + "x "); 
        Console.WriteLine();
        Console.WriteLine("hits left " + left + "x");
        Console.WriteLine();
      }

   }     
        }
    }
}

问题:

enter image description here

我的意思是。我可以一次输入相同的坐标,而不能多次输入。

2 个答案:

答案 0 :(得分:1)

如果您不想在同一地图平铺上拍摄两次,则必须记住那里发生了什么。您正在使用char状态标记。我建议使用一个枚举:

public enum MapStatus
{
    Empty = 0,
    Ship = 1,
    HitShip = 2,
    HitWater = 3
}

您的地图将如下所示:

MapStatus[,] mapTiles;

但是我们已经将int值设置为enum值。因此,我们可以将其转换:

map[0,0] = (MapStatus)1; // This will set a ship to 1/1

现在,您每次拍摄时都要检查是否有水等。

此外,您应该将逻辑移至类“ map”之类。

嗯..这很快就升级了:这是一个完整的例子:

public enum MapStatus
{
    Empty = 0,
    Ship = 1,
    HitShip = 2,
    HitWater = 3
}
public class Map
{
    MapStatus[,] mapTiles;

    public Map(int[,] mapInt = null)
    {
        if (mapInt == null) // if there's no map in parameters we'll set a default map..
        {
            mapInt = new int[,]
            {
                { 0, 0, 0, 0, 0 },
                { 0, 1, 1, 1, 1 },  // in this row there's a ship
                { 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0 },
            };
        }
        // Initialize empty map
        mapTiles = new MapStatus[mapInt.GetLength(0), mapInt.GetLength(1)];

        // copy numbers into our map
        for (int i = 0; i < mapTiles.GetLength(0); i++)
        {
            for (int j = 0; j < mapTiles.GetLength(1); j++)
            {
                mapTiles[i, j] = (MapStatus)mapInt[i, j];
            }
        }
    }

    /// <summary>
    /// "Graphics-Engine" which enables us to print our map.
    /// </summary>
    public void PrintMap()
    {
        Console.Clear();
        Console.Write("        ");
        for (int j = 0; j < mapTiles.GetLength(1); j++)
        {
            Console.Write(j.ToString().PadLeft(8));
        }
        Console.WriteLine();

        for (int i = 0; i < mapTiles.GetLength(0); i++)
        {
            Console.Write(i.ToString().PadLeft(8));
            for (int j = 0; j < mapTiles.GetLength(1); j++)
            {
                Console.Write(mapTiles[i, j].ToString().PadLeft(8) + " ");
            }
            Console.WriteLine();
        }
    }

    /// <summary>
    /// Check if there are ships left. Have a look at Linq ;)
    /// </summary>
    public bool StillAlive()
    {
        return mapTiles.Cast<MapStatus>().Any(a => a == MapStatus.Ship);
    }
    public bool Shoot(int x, int y)
    {
        // Error-Checking if the values are valid..
        if (x < 0 || x >= mapTiles.GetLength(0))
            throw new ArgumentOutOfRangeException(string.Format("X-coordinate ({0}) is wrong (min: {1}, max: {2})!", x, 0, mapTiles.GetLength(0)));

        if (y < 0 || y >= mapTiles.GetLength(1))
            throw new ArgumentOutOfRangeException(string.Format("Y-coordinate ({0}) is wrong (min: {1}, max: {2})!", y, 0, mapTiles.GetLength(1)));

        // Check if we shot here before..
        if (mapTiles[x, y] == MapStatus.HitShip || mapTiles[x, y] == MapStatus.HitWater)
            throw new ArgumentException(string.Format("You did already shoot the coordinates {0}/{1}", x, y));

        // Shoot
        if (mapTiles[x, y] == MapStatus.Empty)
        {
            mapTiles[x, y] = MapStatus.HitWater; // Change value
            return false; // return the info that we didn't hit anything
        }
        else
        {
            mapTiles[x, y] = MapStatus.HitShip;
            return true;
        }
    }
}

public static void Main(string[] args)
{
    Map m = new Map(); // Initialize without map.

    int x;
    int y;
    while (m.StillAlive()) // Loop untill all ships are sunk
    {
        m.PrintMap();
        Console.Write("Enter X: ");
        x = Convert.ToInt32(Console.ReadLine());

        Console.Write("Enter Y: ");
        y = Convert.ToInt32(Console.ReadLine());

        try
        {
            bool hit = m.Shoot(x, y);
            m.PrintMap();
            if (hit)
                Console.WriteLine("We hit a ship!");
            else
                Console.WriteLine("We hit only water!");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception: " + ex.Message);
        }
        Console.WriteLine("(Press Enter to continue)");
        Console.ReadLine();
    }

    Console.WriteLine("We won!");
    Console.ReadLine();
}

答案 1 :(得分:1)

您正在询问如何防止用户两次玩相同的坐标,或者您正在询问如何使用一个def resolve_items(root, info, ids): items = [] queryset1 = FirstModel.objects.filter(id__in=pks) items.extend(queryset1) queryset2 = SecondModel.objects.filter(id__in=pks) items.extend(queryset2) return items 语句而不是两个语句来输入坐标。

我将首先回答第二个问题:

这是一个简单的循环,用户输入两个值,系统将字符串解析为两个整数ReadLine()x。这一直持续到用户按下Enter键为止。技巧是在逗号y处分割输入,以生成字符串数组。 ,

"5,3" => ["5","3"]

如果您跟踪先前的输入坐标并将当前输入与先前的坐标进行比较,则第一个问题将更容易处理。一种方法是将do { int x, y; Console.WriteLine("Enter Hit Coordinates (x,y):"); var input = Console.ReadLine(); var parts = input.Split(','); if (parts.Length!=2) { Console.WriteLine("Please enter two values separated by a comma."); break; } if (int.TryParse(parts[0].Trim(), out x) && int.TryParse(parts[1].Trim(), out y)) { // use the x, y values below Console.WriteLine($"User input was: ({x},{y})"); } else { Console.WriteLine("Please enter numeric values."); } } while (true); 值的列表保留为(x,y)

Tuple

,并使用var history = new List<(int x,int y)>();

检查现有值后,针对每个输入填充它
.Contains()