C# :: Aufgabe #47 :: Lösung #2

2 Lösungen Lösungen öffentlich
#47

Spiel: Schiffe versenken

Fortgeschrittener - C# von david_k - 06.01.2013 um 17:24 Uhr
Es soll ein Schiffe-Versenken Spiel (Konsole oder Gui) erstellt werden. Man solll gegen den Computer oder gegen einen Menschen spielen können.
#2
vote_ok
von daniel59 (4260 Punkte) - 07.06.2016 um 13:47 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WpfSchiffeVersenken
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private static Random rnd = new Random();

        List<Ship> allShips;
        List<Button> coordinates;
        int shots = 0;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void DrawField(int width, int height, double size)
        {
            coordinates = new List<Button>();
            canvas.Children.Clear();
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    Button button = new Button() { Width = size, Height = size, Background = Brushes.DarkSeaGreen, Name = "btn_" + x.ToString() + "_" + y.ToString() };
                    button.Click += Button_Click;
                    Canvas.SetLeft(button, x * size);
                    Canvas.SetTop(button, y * size);
                    canvas.Children.Add(button);
                    coordinates.Add(button);
                }
            }
        }

        private void SetShips(int width, int height, int schlachtschiffe, int kreuzer, int zerstoerer, int uboote)
        {
            allShips = new List<Ship>();
            int ships = schlachtschiffe + kreuzer + zerstoerer + uboote;
            for (int i = 0; i < ships; i++)
            {
                ShipPart startPart = new ShipPart(-1, -1);
                do
                {
                    int startX = rnd.Next(0, width);
                    int startY = rnd.Next(0, height);
                    startPart = new ShipPart(startX, startY);
                }
                while (allShips.Any(a => a.Contains(startPart)));

                int size;
                List<int> movedDirections = new List<int>();

                if (i < schlachtschiffe)//Schlachtschiff
                {
                    size = 5;
                }
                else if (i < kreuzer + schlachtschiffe)//Kreuzer
                {
                    size = 4;
                }
                else if (i < zerstoerer + schlachtschiffe + kreuzer)//Zerstörer
                {
                    size = 3;
                }
                else//U-Boot
                {
                    size = 2;
                }

                Ship ship = new Ship();
                ship.Add(startPart);
                int dir;
                do
                {
                    dir = rnd.Next(0, 4);
                }
                while (movedDirections.Contains(dir) && movedDirections.Count < 4);

                movedDirections.Add(dir);
                int x = 0;
                int y = 0;
                ShipPart part;
                for (int j = 1; j < size; j++)
                {
                    switch (dir)
                    {
                        case 0://left
                            part = new ShipPart(startPart.X - j, startPart.Y);
                            break;

                        case 1://right
                            part = new ShipPart(startPart.X + j, startPart.Y);
                            break;

                        case 2://up
                            part = new ShipPart(startPart.X, startPart.Y - j);
                            break;

                        case 3://down
                            part = new ShipPart(startPart.X, startPart.Y + j);
                            break;

                        default:
                            part = new ShipPart(-1, -1);
                            break;
                    }
                    if (part.X < 0 || part.X > width - 1 || part.Y < 0 || part.Y > height - 1)
                    { break; }
                    if (!allShips.Any(a => a.Contains(part, ShipPartComparer.Comparer)))
                    { ship.Add(part); }
                    else
                    { break; }
                }
                if (ship.Count != size)
                { i--; }
                else
                { allShips.Add(ship); }
            }
        }

        private void Init()
        {
            int width, height, size, schlacht, kreuz, zerstoer, uboot;
            if (int.TryParse(textBoxHeight.Text, out height) && int.TryParse(textBoxWidth.Text, out width) && int.TryParse(textBoxSize.Text, out size) && int.TryParse(textBoxSchlacht.Text, out schlacht) && int.TryParse(textBoxKreuzer.Text, out kreuz) && int.TryParse(textBoxZerstoerer.Text, out zerstoer) && int.TryParse(textBoxUboote.Text, out uboot))
            {
                canvas.Children.Clear();
                DrawField(width, height, size);
                SetShips(width, height, schlacht, kreuz, zerstoer, uboot);
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Button btnXY = ((Button)sender);

            string[] split = btnXY.Name.Split('_');
            int x = Convert.ToInt32(split[1]);
            int y = Convert.ToInt32(split[2]);

            ShipPart part = new ShipPart(x, y);
            int indexShip = allShips.FindIndex(a => a.Contains(part, ShipPartComparer.Comparer));
            shots++;
            if (indexShip > -1)
            {
                int indexPart = allShips[indexShip].IndexOf(part);
                if (!allShips[indexShip][indexPart].Destroyed)
                {
                    btnXY.Background = Brushes.Red;
                    allShips[indexShip][indexPart].Destroyed = true;
                    if (allShips[indexShip].Destroyed)
                    { MessageBox.Show("Schiff zerstört"); }
                }
                if (allShips.TrueForAll(a => a.Destroyed))
                { MessageBox.Show("Alle Schiffe zerstört!\nBenötigte Züge: " + shots.ToString()); }
            }
            else
            {
                btnXY.Background = Brushes.Blue;
            }
        }

        private void button_Click_1(object sender, RoutedEventArgs e)
        {
            Init();
        }
    }

    public class Ship : List<ShipPart>
    {
        public bool Destroyed { get { return this.TrueForAll(x => x.Destroyed); } }
        public bool Valid { get { return this.TrueForAll(x => x.X == this.FirstOrDefault().X) ^ this.TrueForAll(x => x.Y == this.FirstOrDefault().Y); } }
    }

        public class ShipPart
    {
        public int X { get; set; }
        public int Y { get; set; }
        public bool Destroyed { get; set; }

        public ShipPart(int x, int y)
        {
            X = x;
            Y = y;
            Destroyed = false;
        }

        public bool IsNeighbour(ShipPart part)
        {
            return (Math.Abs(this.X - part.X) == 1 && Math.Abs(this.Y - part.Y) == 0) || (Math.Abs(this.Y - part.Y) == 1 && Math.Abs(this.X - part.X) == 0);
        }

        public override bool Equals(object obj)
        {
            ShipPart part = (ShipPart)obj;
            return this.X == part.X && this.Y == part.Y;
        }

        public override int GetHashCode()
        {
            int hash = 13;
            hash = (hash * 7) + X.GetHashCode();
            hash = (hash * 7) + Y.GetHashCode();
            return hash;
        }
    }

        public class ShipPartComparer : IEqualityComparer<ShipPart>
    {
        public static readonly ShipPartComparer Comparer = new ShipPartComparer();
        public bool Equals(ShipPart a, ShipPart b)
        {
            return a.Equals(b);
        }

        public int GetHashCode(ShipPart part)
        {
            return part.GetHashCode();
        }
    }
}


MainWindow.xaml
Quellcode ausblenden XML-Code
<Window x:Class="WpfSchiffeVersenken.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfSchiffeVersenken"
        mc:Ignorable="d"
        Title="MainWindow" Height="500" Width="525">
    <Grid>
        <Canvas x:Name="canvas">
            <TextBlock x:Name="textBlock" Canvas.Left="10" TextWrapping="Wrap" Text="Höhe" Canvas.Top="10"/>
            <TextBox x:Name="textBoxHeight" Height="23" Canvas.Left="93" TextWrapping="Wrap" Text="10" Canvas.Top="7" Width="120" TextAlignment="Center"/>
            <TextBox x:Name="textBoxWidth" Height="23" Canvas.Left="93" TextWrapping="Wrap" Text="10" Canvas.Top="35" Width="120" TextAlignment="Center"/>
            <TextBlock x:Name="textBlock1" Canvas.Left="10" TextWrapping="Wrap" Text="Breite" Canvas.Top="38"/>
            <TextBox x:Name="textBoxSize" Height="23" Canvas.Left="93" TextWrapping="Wrap" Text="30" Canvas.Top="63" Width="120" TextAlignment="Center"/>
            <TextBlock x:Name="textBlock2" Canvas.Left="10" TextWrapping="Wrap" Text="Feldgröße" Canvas.Top="66"/>
            <TextBlock x:Name="textBlock3" Canvas.Left="10" TextWrapping="Wrap" Text="Schlachtschiffe" Canvas.Top="94"/>
            <TextBox x:Name="textBoxSchlacht" Height="23" Canvas.Left="93" TextWrapping="Wrap" Text="1" Canvas.Top="91" Width="120" TextAlignment="Center"/>
            <TextBox x:Name="textBoxKreuzer" Height="23" Canvas.Left="93" TextWrapping="Wrap" Text="2" Canvas.Top="119" Width="120" TextAlignment="Center"/>
            <TextBlock x:Name="textBlock3_Copy" Canvas.Left="10" TextWrapping="Wrap" Text="Kreuzer" Canvas.Top="122"/>
            <TextBox x:Name="textBoxZerstoerer" Height="23" Canvas.Left="93" TextWrapping="Wrap" Text="3" Canvas.Top="147" Width="120" TextAlignment="Center"/>
            <TextBlock x:Name="textBlock4" Canvas.Left="10" TextWrapping="Wrap" Text="Zerstörer" Canvas.Top="150"/>
            <TextBlock x:Name="textBlock5" Canvas.Left="10" TextWrapping="Wrap" Text="U-Boote" Canvas.Top="178"/>
            <TextBox x:Name="textBoxUboote" Height="23" Canvas.Left="93" TextWrapping="Wrap" Text="4" Canvas.Top="175" Width="120" TextAlignment="Center"/>
            <Button x:Name="button" Content="OK" Canvas.Left="10" Canvas.Top="203" Width="203" Click="button_Click_1"/>
        </Canvas>
    </Grid>
</Window>

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben
2092598

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.