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