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

#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

von daniel59 (4260 Punkte)
- 07.06.2016 um 13:47 Uhr

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

<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
Seite 1 von 0
1