mirror of
https://github.com/TwoFX/Morris.git
synced 2025-12-13 08:22:51 +00:00
Minor changes, add GUI (read only atm)
This commit is contained in:
@@ -26,6 +26,8 @@ namespace Morris
|
||||
|
||||
public void Notify(IReadOnlyGameState state)
|
||||
{
|
||||
Console.Clear();
|
||||
|
||||
// Ein mit Leerzeichen initialisiertes 13*13 Jagged Array
|
||||
char[][] field = Enumerable.Repeat(0, 13).Select(_ => Enumerable.Repeat(' ', 13).ToArray()).ToArray();
|
||||
|
||||
|
||||
12
Morris/GameWindow.xaml
Normal file
12
Morris/GameWindow.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<Window x:Class="Morris.GameWindow"
|
||||
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:Morris"
|
||||
mc:Ignorable="d"
|
||||
Title="Morris" Height="300" Width="300">
|
||||
<Grid x:Name="grid" Background="#FFD0D0D0">
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
187
Morris/GameWindow.xaml.cs
Normal file
187
Morris/GameWindow.xaml.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* GameWindow.xaml.cs
|
||||
* Copyright (c) 2016 Markus Himmel
|
||||
* This file is distributed under the terms of the MIT license
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Morris
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Eine WPF-gestütze Mühle-GUI
|
||||
/// </summary>
|
||||
public partial class GameWindow : Window, IGameStateObserver
|
||||
{
|
||||
|
||||
private const int BLOCK_SIZE = 100; // Sollte durch 2 teilbar sein
|
||||
private const int OFFSET_LEFT = 50;
|
||||
private const int OFFSET_TOP = 70;
|
||||
private const int OFFSET_BOTTOM = 90;
|
||||
private const int OFFSET_RIGHT = 10;
|
||||
private const int LINE_THICKNESS = 6; // Sollte durch 2 teilbar sein
|
||||
private const int PIECE_RADIUS = 30;
|
||||
private const int LEGEND_OFFSET = 30;
|
||||
private const int LABEL_BUFFER_SIZE = 40;
|
||||
|
||||
private Ellipse[] pieces;
|
||||
|
||||
private SolidColorBrush primaryColor = new SolidColorBrush(Color.FromRgb(0, 0, 0));
|
||||
|
||||
private Label status;
|
||||
|
||||
public GameWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Spielfield zeichnen
|
||||
for (int i = 0; i < GameState.FIELD_SIZE; i++)
|
||||
{
|
||||
var pointI = CoordinateTranslator.CoordinatesFromID(i);
|
||||
foreach (int j in GameState.GetConnected(i).Where(j => j < i))
|
||||
{
|
||||
var pointJ = CoordinateTranslator.CoordinatesFromID(j);
|
||||
|
||||
// "Fire and Forget": Sobald wir die Objekte zum Grid hinzugefügt haben,
|
||||
// brauchen wir keine Referenzen mehr zu speichern.
|
||||
var h = new Rectangle();
|
||||
h.Fill = primaryColor;
|
||||
h.Width = BLOCK_SIZE * Math.Abs(pointI[1] - pointJ[1]) + LINE_THICKNESS;
|
||||
h.Height = BLOCK_SIZE * Math.Abs(pointI[0] - pointJ[0]) + LINE_THICKNESS;
|
||||
h.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
h.VerticalAlignment = VerticalAlignment.Top;
|
||||
|
||||
h.Margin = new Thickness(
|
||||
BLOCK_SIZE * Math.Min(pointI[1], pointJ[1]) + BLOCK_SIZE / 2 - LINE_THICKNESS / 2 + OFFSET_LEFT,
|
||||
BLOCK_SIZE * Math.Min(pointI[0], pointJ[0]) + BLOCK_SIZE / 2 - LINE_THICKNESS / 2 + OFFSET_TOP,
|
||||
0, 0);
|
||||
|
||||
grid.Children.Add(h);
|
||||
}
|
||||
}
|
||||
|
||||
// Beschriftung links
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
Label l = new Label();
|
||||
l.VerticalContentAlignment = VerticalAlignment.Center;
|
||||
l.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
l.VerticalAlignment = VerticalAlignment.Top;
|
||||
l.Content = (7 - i).ToString();
|
||||
l.Height = LABEL_BUFFER_SIZE;
|
||||
|
||||
l.Margin = new Thickness(OFFSET_LEFT - LEGEND_OFFSET, OFFSET_TOP + i * BLOCK_SIZE + BLOCK_SIZE / 2 - LABEL_BUFFER_SIZE / 2, 0, 0);
|
||||
l.FontSize = 20;
|
||||
l.Foreground = primaryColor;
|
||||
grid.Children.Add(l);
|
||||
}
|
||||
|
||||
// Beschriftung unten
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
Label l = new Label();
|
||||
l.HorizontalContentAlignment = HorizontalAlignment.Center;
|
||||
l.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
l.VerticalAlignment = VerticalAlignment.Top;
|
||||
l.Content = (char)('a' + i);
|
||||
l.Width = LABEL_BUFFER_SIZE;
|
||||
l.Margin = new Thickness(OFFSET_LEFT + i * BLOCK_SIZE + BLOCK_SIZE / 2 - LABEL_BUFFER_SIZE / 2, OFFSET_TOP + 7 * BLOCK_SIZE, 0, 0);
|
||||
l.FontSize = 20;
|
||||
l.Foreground = primaryColor;
|
||||
grid.Children.Add(l);
|
||||
}
|
||||
|
||||
// Fenstergröße
|
||||
Height = OFFSET_TOP + 7 * BLOCK_SIZE + OFFSET_BOTTOM;
|
||||
Width = OFFSET_LEFT + 7 * BLOCK_SIZE + OFFSET_RIGHT;
|
||||
|
||||
|
||||
|
||||
// Es gibt nicht für jeden tatsächlichen Spielstein eine Ellipse, die sich bewegt. Stattdessen gibt es eine
|
||||
// Ellipse auf jedem der 24 Spielfeldpunkte, die je nach Belegung Schwarz, weiß oder transparent ist
|
||||
pieces = new Ellipse[GameState.FIELD_SIZE];
|
||||
for (int i = 0; i < GameState.FIELD_SIZE; i++)
|
||||
{
|
||||
var point = CoordinateTranslator.CoordinatesFromID(i);
|
||||
var e = new Ellipse();
|
||||
e.Fill = null;
|
||||
e.Width = e.Height = 2 * PIECE_RADIUS;
|
||||
e.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
e.VerticalAlignment = VerticalAlignment.Top;
|
||||
|
||||
e.Margin = new Thickness(
|
||||
OFFSET_LEFT + BLOCK_SIZE * point[1] + BLOCK_SIZE / 2 - PIECE_RADIUS,
|
||||
OFFSET_TOP + BLOCK_SIZE * point[0] + BLOCK_SIZE / 2 - PIECE_RADIUS,
|
||||
0, 0);
|
||||
|
||||
grid.Children.Add(e);
|
||||
|
||||
pieces[i] = e;
|
||||
}
|
||||
|
||||
// Statusanzeige
|
||||
status = new Label();
|
||||
status.HorizontalContentAlignment = HorizontalAlignment.Center;
|
||||
status.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
status.VerticalAlignment = VerticalAlignment.Top;
|
||||
status.Width = 7 * BLOCK_SIZE + LINE_THICKNESS;
|
||||
status.Margin = new Thickness(OFFSET_LEFT, 10, 0, 0);
|
||||
status.FontSize = 40;
|
||||
grid.Children.Add(status);
|
||||
}
|
||||
|
||||
public void Notify(IReadOnlyGameState state)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
// Ellipsen einfärben
|
||||
for (int i = 0; i < GameState.FIELD_SIZE; i++)
|
||||
{
|
||||
switch (state.Board[i])
|
||||
{
|
||||
case Occupation.Free:
|
||||
pieces[i].Fill = null;
|
||||
break;
|
||||
|
||||
case Occupation.Black:
|
||||
pieces[i].Fill = new SolidColorBrush(Colors.Black);
|
||||
break;
|
||||
|
||||
case Occupation.White:
|
||||
pieces[i].Fill = new SolidColorBrush(Colors.White);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Statusanzeige, falls das Spiel vorbei ist
|
||||
switch (state.Result)
|
||||
{
|
||||
case GameResult.BlackVictory:
|
||||
status.Content = "Schwarz hat gewonnen";
|
||||
break;
|
||||
|
||||
case GameResult.WhiteVictory:
|
||||
status.Content = "Weiß hat gewonnen";
|
||||
break;
|
||||
|
||||
case GameResult.Draw:
|
||||
status.Content = "Unentschieden";
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{E3CCB2E8-5840-4442-8A66-177F5DF4C4F5}</ProjectGuid>
|
||||
@@ -33,14 +34,18 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xaml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ConsoleInteraction.cs" />
|
||||
@@ -49,6 +54,9 @@
|
||||
<Compile Include="Game.cs" />
|
||||
<Compile Include="GameResult.cs" />
|
||||
<Compile Include="GameState.cs" />
|
||||
<Compile Include="GameWindow.xaml.cs">
|
||||
<DependentUpon>GameWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="RandomBot.cs" />
|
||||
<Compile Include="IGameStateObserver.cs" />
|
||||
<Compile Include="IMoveProvider.cs" />
|
||||
@@ -65,6 +73,12 @@
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="GameWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -8,14 +9,17 @@ namespace Morris
|
||||
{
|
||||
class Program
|
||||
{
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var a = new ConsoleInteraction();
|
||||
var b = new RandomBot();
|
||||
var w = new GameWindow();
|
||||
var g = new Game(b, b);
|
||||
g.AddObserver(a);
|
||||
g.Run();
|
||||
Console.ReadKey();
|
||||
g.AddObserver(w);
|
||||
Task.Run(() => g.Run());
|
||||
new Application().Run(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user