C# :: Aufgabe #200

2 Lösungen Lösungen öffentlich

Auslosung der Figurenaufstellung beim Chess960

Anfänger - C# von hollst - 12.02.2018 um 18:33 Uhr
Beim Chess960, auch Fischer-Random-Chess genannt, wird die
Ausgangsposition der acht weißen Offiziere ausgelost, wobei
zwei Regeln zu beachten sind:

1.) der König muss zwischen den zwei Türmen stehen (damit Rochaden möglich bleiben) und
2.) die zwei Läufer müssen ungleichfarbig sein.

Die schwarzen Offiziere werden spiegelsymmetrisch angeordnet (Bild 1, Beispielaufstellung),
alle anderen Schachspielregeln bleiben erhalten.

Man schreibe ein (vorzugsweise GUI-) Programm, das diesen Auslosungsregeln entspricht und eine
der möglichen 960 zufälligen Startpositionen rückgibt.

Lösungen:

vote_ok
von hollst (13980 Punkte) - 25.02.2018 um 15:28 Uhr
Hier wird der Zeichensatz CHESS BERLIN verwended: http://www.enpassant.dk/chess/downl/berlin.zip (CHESS ALPHA ist bei den Leerfeldern nicht proportional (glaub ich))
Quellcode ausblenden C#-Code
<Window x:Class="Chess960_WPF.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:Chess960_WPF"
        mc:Ignorable="d"
        Title="Chess969_WPF" Height="500" Width="500" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Margin="5" Orientation="Horizontal">
            <Button x:Name="bt_normal" Content=" startpos normal " Click="bt_normal_Click"/>
            <Button x:Name="bt_random960" Content=" random960 " Width="75" Click="bt_random960_Click" Margin="5,0,0,0"/>
        </StackPanel>
        <TextBox x:Name="textBox" Margin="5" Grid.Row="1" TextWrapping="Wrap" FontFamily="Chess Berlin" FontSize="48" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
    </Grid>
</Window>


Quellcode ausblenden C#-Code
using System;
using static System.Console;
using System.Collections.Generic;
using System.Text;
using System.Windows;

namespace Chess960_WPF
{
    public partial class MainWindow : Window
    {
        private Random random = new Random();
        private Chess960_Class.CHESS960 c960;
        public MainWindow()
        {
            InitializeComponent();

            c960 = new Chess960_Class.CHESS960(random);
            WriteLine(c960.string_position_CONSOLE);            
            this.textBox.Text = c960.string_position_CHESS_BERLIN_normalschach;
        }

        private void bt_random960_Click(object sender, RoutedEventArgs e)
        {
            c960 = new Chess960_Class.CHESS960(random);
            this.textBox.Text = c960.string_position_CHESS_BERLIN;
        }

        private void bt_normal_Click(object sender, RoutedEventArgs e)
        {
            this.textBox.Text = c960.string_position_CHESS_BERLIN_normalschach;
        }
    }
}

namespace Chess960_Class
{
    public class CHESS960
    {
        public int[] position_white_officers { get; private set; }
        public int[] position_white_officers_normalschach { get; private set; }

        public string string_position_CONSOLE;
        public string string_position_CHESS_BERLIN;
        public string string_position_CHESS_BERLIN_normalschach;

        public CHESS960(Random rand)    {
            position_white_officers = new int[8];
            position_white_officers_normalschach = new int[8];
            for (var i = 0; i < position_white_officers_normalschach.Length; i++)
                position_white_officers_normalschach[i] = i;
            List<int> list = null;

            bool pos_valid = false;            
            while (!pos_valid)  {
                list = new List<int>();
                for (var i = 0; i < position_white_officers.Length; i++)    {
                    bool bo_okay = false;
                    int next = -1;
                    while (!bo_okay)    {
                        next = rand.Next(8);
                        bo_okay = !list.Contains(next);                                                    
                    }
                    list.Add(next);
                }
                pos_valid = bo_valid(list);                
            }
            position_white_officers = list.ToArray();

            string_position_CONSOLE = position(position_white_officers);
            string_position_CHESS_BERLIN = position_CHESS_ALPHA(position_white_officers);
            string_position_CHESS_BERLIN_normalschach = position_CHESS_ALPHA(position_white_officers_normalschach);
        }

        private bool bo_valid(List<int> input)  {
            int king = 4, 
                pos_king = input.IndexOf(king);
            int rock1 = 0, rock2 = 7, 
                pos_rock1 = input.IndexOf(rock1), pos_rock2 = input.IndexOf(rock2);
            int bishop1 = 2, bishop2 = 5, 
                pos_bishop1 = input.IndexOf(bishop1), pos_bishop2 = input.IndexOf(bishop2);
            return 
                Math.Max(pos_rock1, pos_rock2) > pos_king && 
                Math.Min(pos_rock1, pos_rock2) < pos_king && 
                (pos_bishop1 + pos_bishop2) % 2 == 1;
        }

        private static string position(int[] L) {
            StringBuilder sb = new StringBuilder();
            string[][] officers = new string[][]
            {
                new string[] { "wT ", "wS ", "wL ", "wD ", "wK ", "wL ", "wS ", "wT " },
                new string[] { "bT ", "bS ", "bL ", "bD ", "bK ", "bL ", "bS ", "bT " }
            };
            string[] pawns_blank = new string[] { "wP ", "sP ", " . " };

            for (var j = 0; j < 8; j++)
                sb.Append(officers[1][L[j]]);
            sb.AppendLine();
            for (var j = 0; j < 8; j++)
                sb.Append(pawns_blank[1]);
            sb.AppendLine();
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 8; j++)
                    sb.Append(pawns_blank[2]);
                sb.AppendLine();
            }
            for (var j = 0; j < 8; j++)
                sb.Append(pawns_blank[0]);
            sb.AppendLine();
            for (var j = 0; j < 8; j++)
                sb.Append(officers[0][L[j]]);

            return sb.ToString();
        }

        //http://www.enpassant.dk/chess/downl/berlin.zip

        private static string position_CHESS_ALPHA(int[] L)
        {
            StringBuilder sb = new StringBuilder();

            string[][] officers = new string[][]
            {
                new string[] { "R", "H", "B", "Q", "K", "B", "H", "R", "r", "h", "b", "q", "k", "b", "h", "r",},
                new string[] { "t", "j", "n", "w", "l", "n", "j", "t", "T", "J", "N", "W", "L", "N", "J", "T" }
            };
            string[] pawns_blank = new string[] { "P", "o", " ", "p", "O", "+" };

            for (var j = 0; j < 8; j++)
            {
                int jj;
                jj = j % 2 == 0 ? 0 : 8;
                sb.Append(officers[1][L[j] + jj]);
            }
            sb.AppendLine();

            for (var j = 0; j < 8; j++)
            {
                int jj;
                jj = j % 2 == 1 ? 1 : 4;
                sb.Append(pawns_blank[jj]);
            }
            sb.AppendLine();

            for (var i = 0; i < 4; i++)
            {
                for (var j = 0; j < 8; j++)
                {
                    int jj;
                    jj = (j + i) % 2 == 0 ? 2 : 2 + 3;
                    sb.Append(pawns_blank[jj]);
                }
                sb.AppendLine();
            }

            for (var j = 0; j < 8; j++)
            {
                int jj;
                jj = j % 2 == 1 ? 0 : 0 + 3;
                sb.Append(pawns_blank[jj]);
            }
            sb.AppendLine();

            for (var j = 0; j < 8; j++)
            {
                int jj;
                jj = j % 2 == 0 ? 0 : 8;
                sb.Append(officers[0][L[j] + jj]);
            }

            return sb.ToString();
        }
    }
}
1 Kommentar
vote_ok
von daniel59 (4260 Punkte) - 28.02.2018 um 10:05 Uhr
MainWindow.xaml.cs
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 WpfChess960
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        static readonly Random rnd = new Random();
        static readonly SolidColorBrush blackBrush = new SolidColorBrush(Color.FromRgb(0x95, 0x6A, 0x45));
        static readonly SolidColorBrush whiteBrush = new SolidColorBrush(Color.FromRgb(0xE1, 0xE0, 0xDE));

        private List<ChessGrid> grids;
        public MainWindow()
        {
            InitializeComponent();
            grids = new List<ChessGrid>();
            InitChessBoard();
        }

        private void InitChessBoard()
        {
            gridChessBoard.Children.Clear();
            grids.Clear();
            const char A = 'A';
            for (int i = 0; i < 8; i++)
            {
                char c = (char)(A + i);
                int n = i + 1;

                TextBlock tbkC = new TextBlock() { Text = c.ToString(), Foreground = Brushes.White, TextAlignment = TextAlignment.Center, Width = 40, Height = 20 };
                TextBlock tbkN = new TextBlock() { Text = n.ToString(), Foreground = Brushes.White, TextAlignment = TextAlignment.Center, Width = 20, Margin = new Thickness(0, 11, 0, 0) };


                Grid.SetColumn(tbkC, n);
                Grid.SetRow(tbkC, 0);
                gridChessBoard.Children.Add(tbkC);

                Grid.SetColumn(tbkN, 0);
                Grid.SetRow(tbkN, n);
                gridChessBoard.Children.Add(tbkN);
            }

            bool white = true;
            for (int r = 1; r <= 8; r++)
            {
                for (int c = 1; c <= 8; c++)
                {
                    ChessGrid grid = new ChessGrid();
                    grid.Name = $"grid_{r}_{c}";
                    grid.White = white;
                    grid.Background = white ? whiteBrush : blackBrush;
                    white = !white;

                    Grid.SetRow(grid, r);
                    Grid.SetColumn(grid, c);
                    gridChessBoard.Children.Add(grid);
                    grids.Add(grid);
                }
                white = !white;
            }
        }

        private void GenerateRandom()//K = König, D = Dame, L = Läufer, S = Springer, T = Turm, B = Bauer
        {
            InitChessBoard();

            #region König
            int rowK = rnd.Next(1, 9);
            int columnK = rnd.Next(2, 8);
            int rowKMirror = 9 - rowK;

            ChessGrid gridK = grids.Single(a => a.Name == $"grid_{rowK}_{columnK}");
            TextBlock tbkK = new TextBlock() { Text = "K", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
            gridK.Children.Add(tbkK);

            ChessGrid gridKMirror = grids.Single(a => a.Name == $"grid_{rowKMirror}_{columnK}");
            TextBlock tbkKMirror = new TextBlock() { Text = "K", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
            gridKMirror.Children.Add(tbkKMirror);
            #endregion

            #region Türme
            int rowT = rowK;
            int columnTL = rnd.Next(1, columnK);
            int columnTR = rnd.Next(columnK + 1, 9);
            int rowTMirror = rowKMirror;

            //Linker Turm
            ChessGrid gridTL = grids.Single(a => a.Name == $"grid_{rowT}_{columnTL}");
            TextBlock tbkTL = new TextBlock() { Text = "T", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
            gridTL.Children.Add(tbkTL);

            ChessGrid gridTLMirror = grids.Single(a => a.Name == $"grid_{rowTMirror}_{columnTL}");
            TextBlock tbkTLMirror = new TextBlock() { Text = "T", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
            gridTLMirror.Children.Add(tbkTLMirror);

            //Rechter Turm
            ChessGrid gridTR = grids.Single(a => a.Name == $"grid_{rowT}_{columnTR}");
            TextBlock tbkTR = new TextBlock() { Text = "T", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
            gridTR.Children.Add(tbkTR);

            ChessGrid gridTRMirror = grids.Single(a => a.Name == $"grid_{rowTMirror}_{columnTR}");
            TextBlock tbkTRMirror = new TextBlock() { Text = "T", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
            gridTRMirror.Children.Add(tbkTRMirror);
            #endregion

            #region Dame
            ChessGrid gridD = null;
            do
            {
                int rowD = rnd.Next(1, 9);
                int columnD = rnd.Next(1, 9);
                int rowDMirror = 9 - rowD;

                gridD = grids.SingleOrDefault(a => a.Name == $"grid_{rowD}_{columnD}" && a.Children.Count == 0);
                if (gridD != null)
                {
                    TextBlock tbkD = new TextBlock() { Text = "D", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
                    gridD.Children.Add(tbkD);

                    ChessGrid gridDMirror = grids.Single(a => a.Name == $"grid_{rowDMirror}_{columnD}");
                    TextBlock tbkDMirror = new TextBlock() { Text = "D", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
                    gridDMirror.Children.Add(tbkDMirror);
                }
            } while (gridD == null);

            #endregion

            #region Läufer
            ChessGrid gridLL = null;
            ChessGrid gridLR = null;

            //Linker Läufer
            do
            {
                int rowLL = rnd.Next(1, 9);
                int columnLL = rnd.Next(1, 9);
                int rowLLMirror = 9 - rowLL;
                gridLL = grids.SingleOrDefault(a => a.Name == $"grid_{rowLL}_{columnLL}" && a.Children.Count == 0);
                if (gridLL != null)
                {
                    TextBlock tbkLL = new TextBlock() { Text = "L", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
                    gridLL.Children.Add(tbkLL);

                    ChessGrid gridLLMirror = grids.Single(a => a.Name == $"grid_{rowLLMirror}_{columnLL}");
                    TextBlock tbkLLMirror = new TextBlock() { Text = "L", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
                    gridLLMirror.Children.Add(tbkLLMirror);
                }
            } while (gridLL == null);

            //Rechter Läufer
            do
            {
                int rowLR = rnd.Next(1, 9);
                int columnLR = rnd.Next(1, 9);
                int rowLRMirror = 9 - rowLR;
                gridLR = grids.SingleOrDefault(a => a.Name == $"grid_{rowLR}_{columnLR}" && a.Children.Count == 0 && a.White != gridLL.White);
                if (gridLR != null)
                {
                    TextBlock tbkLR = new TextBlock() { Text = "L", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
                    gridLR.Children.Add(tbkLR);

                    ChessGrid gridLRMirror = grids.Single(a => a.Name == $"grid_{rowLRMirror}_{columnLR}");
                    TextBlock tbkLRMirror = new TextBlock() { Text = "L", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
                    gridLRMirror.Children.Add(tbkLRMirror);
                }
            } while (gridLR == null);

            #endregion

            #region Springer
            ChessGrid gridSL = null;
            ChessGrid gridSR = null;

            //Linker Springer
            do
            {
                int rowSL = rnd.Next(1, 9);
                int columnSL = rnd.Next(1, 9);
                int rowSLMirror = 9 - rowSL;
                gridSL = grids.SingleOrDefault(a => a.Name == $"grid_{rowSL}_{columnSL}" && a.Children.Count == 0);
                if (gridSL != null)
                {
                    TextBlock tbkSL = new TextBlock() { Text = "S", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
                    gridSL.Children.Add(tbkSL);

                    ChessGrid gridSLMirror = grids.Single(a => a.Name == $"grid_{rowSLMirror}_{columnSL}");
                    TextBlock tbkSLMirror = new TextBlock() { Text = "S", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
                    gridSLMirror.Children.Add(tbkSLMirror);
                }

            } while (gridSL == null);

            //Rechter Springer
            do
            {
                int rowSR = rnd.Next(1, 9);
                int columnSR = rnd.Next(1, 9);
                int rowSRMirror = 9 - rowSR;
                gridSR = grids.SingleOrDefault(a => a.Name == $"grid_{rowSR}_{columnSR}" && a.Children.Count == 0);
                if (gridSR != null)
                {
                    TextBlock tbkSR = new TextBlock() { Text = "S", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
                    gridSR.Children.Add(tbkSR);

                    ChessGrid gridSRMirror = grids.Single(a => a.Name == $"grid_{rowSRMirror}_{columnSR}");
                    TextBlock tbkSRMirror = new TextBlock() { Text = "S", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
                    gridSRMirror.Children.Add(tbkSRMirror);
                }

            } while (gridSR == null);
            #endregion

            #region Bauern
            for (int i = 0; i < 8; i++)
            {
                ChessGrid gridB = null;

                do
                {
                    int rowB = rnd.Next(1, 9);
                    int columnB = rnd.Next(1, 9);
                    int rowBMirror = 9 - rowB;
                    gridB = grids.SingleOrDefault(a => a.Name == $"grid_{rowB}_{columnB}" && a.Children.Count == 0);
                    if (gridB != null)
                    {
                        TextBlock tbkB = new TextBlock() { Text = "B", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.White };
                        gridB.Children.Add(tbkB);

                        ChessGrid gridBMirror = grids.Single(a => a.Name == $"grid_{rowBMirror}_{columnB}");
                        TextBlock tbkBMirror = new TextBlock() { Text = "B", TextAlignment = TextAlignment.Center, Width = 40, Margin = new Thickness(0, 4, 0, 0), FontWeight = FontWeights.Bold, FontSize = 24, Foreground = Brushes.Black };
                        gridBMirror.Children.Add(tbkBMirror);
                    }
                } while (gridB == null);
            }
            #endregion
        }

        private void buttonReset_Click(object sender, RoutedEventArgs e)
        {
            InitChessBoard();
        }

        private void buttonRandom_Click(object sender, RoutedEventArgs e)
        {
            GenerateRandom();
        }
    }

    class ChessGrid : Grid
    {
        public bool White { get; set; }
    }
}


MainWindow.xaml
Quellcode ausblenden XML-Code
<Window x:Class="WpfChess960.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:WpfChess960"
        mc:Ignorable="d"
        Title="Chess960" ResizeMode="CanMinimize" SizeToContent="WidthAndHeight">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10,10,0,0">
            <Button x:Name="buttonRandom" Content="Zufällige Aufstellung" Width="150" Click="buttonRandom_Click"/>
            <Button x:Name="buttonReset" Content="Zurücksetzten" Width="150" Margin="10,0,0,0" Click="buttonReset_Click"/>
        </StackPanel>
        <Grid x:Name="gridChessBoard" Grid.Row="1" Width="340" Height="340" Background="Black" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="20"/>
                <RowDefinition Height="40"/>
                <RowDefinition Height="40"/>
                <RowDefinition Height="40"/>
                <RowDefinition Height="40"/>
                <RowDefinition Height="40"/>
                <RowDefinition Height="40"/>
                <RowDefinition Height="40"/>
                <RowDefinition Height="40"/>
            </Grid.RowDefinitions>
        </Grid>
    </Grid>
</Window>