3D黑白棋 StarReversi
组对编程---3D黑白棋 发布
这是一个用silverlight编写的3D程序,可以360°变化视角,展开/收缩棋盘,实现了标准黑白棋股则及扩展股则(棋盘左右两边连通)
游戏有AI功能,有回放功能,回放过程中可以进入下棋模式
游戏链接:
http://home.ustc.edu.cn/~sqren/(墙内可用)
http://dl.dropbox.com/u/15667321/Reversi3D.html (墙外可用)
下载链接:
https://sites.google.com/site/starreversi/StarReversi.zip (墙外可用)
http://dl.dropbox.com/u/15667321/StarReversi.zip (墙外可用)
http://home.ustc.edu.cn/~sqren/StarReversi.zip (墙内可用)
code:
xmal:
代码
<UserControl x:Class="Reversi3D.MainPage"
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:Execution="clr-namespace:Balder.Execution;assembly=Balder"
xmlns:Flat="clr-namespace:Balder.Objects.Flat;assembly=Balder"
xmlns:View="clr-namespace:Balder.View;assembly=Balder"
xmlns:Geometries="clr-namespace:Balder.Objects.Geometries;assembly=Balder"
xmlns:Lighting="clr-namespace:Balder.Lighting;assembly=Balder"
xmlns:Materials="clr-namespace:Balder.Materials;assembly=Balder"
xmlns:Animation="clr-namespace:Balder.Animation.Silverlight;assembly=Balder"
xmlns:Objects="clr-namespace:Balder.Objects;assembly=Balder"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800">
<Grid x:Name="LayoutRoot" Background="Silver" MouseWheel="Grid_MouseWheel" KeyDown="LayoutRoot_KeyDown" KeyUp="LayoutRoot_KeyUp">
<Grid.Resources>
<Materials:Material x:Name="WhiteMaterial" x:Key="WhiteMaterial" ReflectionMap="/Reversi3D;component/image/laughstar.jpg"/>
<Materials:Material x:Name="BlackMaterial" x:Key="BlackMaterial" ReflectionMap="/Reversi3D;component/image/bluestar.png"/>
<Materials:Material x:Name="StarReversiMaterial" x:Key="StarReversiMaterial" DiffuseMap="/Reversi3D;component/image/starreversi.jpg"/>
<Materials:Material x:Name="YouWinMaterial" x:Key="YouWinMaterial" DiffuseMap="/Reversi3D;component/image/youwin.jpg"/>
<Materials:Material x:Name="YouLoseMaterial" x:Key="YouLoseMaterial" DiffuseMap="/Reversi3D;component/image/youlose.jpg"/>
<Materials:Material x:Name="GameOverMaterial" x:Key="GameOverMaterial" DiffuseMap="/Reversi3D;component/image/gameover.jpg"/>
<!-- <EventTrigger x:Key ="event" RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard x:Name="boxopacity" RepeatBehavior="Forever">
<Animation:StoryboardExtensions.CoordinateAnimation>
<Animation:CoordinateAnimation To="100,100,100" Duration="00:00:05" TargetName="bb" TargetProperty="(Node.Position)"/>
</Animation:StoryboardExtensions.CoordinateAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>-->
<!--<Storyboard x:Name="leftrotation" RepeatBehavior="Forever">
<Animation:StoryboardExtensions.CoordinateAnimation>
<Animation:CoordinateAnimation From="0,0,359" To="0,0,0" Duration="00:00:05" TargetName="group" TargetProperty="(Node.Rotation)"/>
</Animation:StoryboardExtensions.CoordinateAnimation>-->
</Grid.Resources>
<Execution:Game Width ="800" Height="600">
<Execution:Game.Skybox>
<Objects:Skybox IsEnabled ="True"
Front="/Reversi3D;component/image/star/3.jpg"
Back="/Reversi3D;component/image/star/1.jpg"
Left="/Reversi3D;component/image/star/2.jpg"
Right="/Reversi3D;component/image/star/5.jpg"
Top="/Reversi3D;component/image/star/6.jpg"
Bottom="/Reversi3D;component/image/star/4.jpg"
/>
</Execution:Game.Skybox>
<Execution:Game.Camera>
<View:Camera x:Name="cCamera" Position="0, 0, -190" Target="0, 0, 0"/>
</Execution:Game.Camera>
<Lighting:OmniLight Position="300, 400, 400" Ambient="Black" Diffuse="White" Specular= "boxopacity" Strength="0.3"/>
<Lighting:OmniLight Position="300, 400, -400" Ambient="Black" Diffuse="White" Specular= "boxopacity" Strength="0.3"/>
<Lighting:OmniLight Position="300, -400, 400" Ambient="Black" Diffuse="White" Specular= "boxopacity" Strength="0.3"/>
<Lighting:OmniLight Position="300, -400, -400" Ambient="Black" Diffuse="White" Specular= "boxopacity" Strength="0.3"/>
<Lighting:OmniLight Position="-300, 400, 400" Ambient="Black" Diffuse="White" Specular= "boxopacity" Strength="0.3"/>
<Lighting:OmniLight Position="-300, 400, -400" Ambient="Black" Diffuse="White" Specular= "boxopacity" Strength="0.3"/>
<Lighting:OmniLight Position="-300, -400, 400" Ambient="Black" Diffuse="White" Specular= "boxopacity" Strength="0.3"/>
<Lighting:OmniLight Position="-300, -400, -400" Ambient="Black" Diffuse="White" Specular= "boxopacity" Strength="0.3"/>
<Geometries:Geometry x:Name="group" Height="600" Width="800" InteractionEnabled ="True" MouseLeftButtonDown="group_MouseLeftButtonDown" MouseLeftButtonUp="group_MouseLeftButtonUp">
</Geometries:Geometry>
</Execution:Game>
<Grid HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="80"/>
<RowDefinition Height="20"/>
<RowDefinition Height="280"/>
</Grid.RowDefinitions>
<TextBlock Text="Reversi Mode" Grid.Column="0" Grid.Row="1"/>
<ComboBox x:Name="ModeComboBox" Grid.Column="0" Grid.Row="2" SelectedIndex="1">
<ComboBoxItem Content="Normal"/>
<ComboBoxItem Content="Extended"/>
</ComboBox>
<TextBlock Text="Player Number" Grid.Column="0" Grid.Row="3"/>
<ComboBox x:Name="PlayerNumberComboBox" Grid.Column="0" Grid.Row="4" SelectedIndex="0">
<ComboBoxItem Content="Single"/>
<ComboBoxItem Content="Double"/>
</ComboBox>
<Button x:Name="StartButton" Content="Start" Grid.Column="0" Grid.Row="6" Click="StartButton_Click">
</Button>
<Button x:Name="EndThisGame" Content="End" Grid.Column="0" Grid.Row="8" IsEnabled="False" Click="EndThisGame_Click">
</Button>
<Grid x:Name="_infoBox" Grid.Column="0" Grid.Row="10">
<Grid.RenderTransform>
<TranslateTransform x:Name="_infoBoxTranslation"/>
</Grid.RenderTransform>
<Grid.Background>
<SolidColorBrush Opacity="0.5" Color="Gray"/>
</Grid.Background>
<Border BorderBrush="White" BorderThickness="1">
<TextBlock Foreground="White">
<Run x:Name="_player1name"/><Run>:</Run>
<Run x:Name="_player1sorce"/><LineBreak/>
<Run x:Name="_player2name"/><Run>:</Run>
<Run x:Name="_player2sorce"/><LineBreak/>
<Run>Result:</Run>
<Run x:Name="_result"/><LineBreak/>
</TextBlock>
</Border>
</Grid>
<Grid x:Name="_ruleBox" Grid.Column="0" Grid.Row="12">
<Grid.RenderTransform>
<TranslateTransform x:Name="_ruleBoxTranslation"/>
</Grid.RenderTransform>
<Grid.Background>
<SolidColorBrush Opacity="0.5" Color="Gray"/>
</Grid.Background>
<Border BorderBrush="White" BorderThickness="1">
<TextBlock TextWrapping="Wrap" Grid.Column="0" Grid.Row="12">
模式说明:<LineBreak/>
Normal--标准黑白棋棋规则<LineBreak/>
Extended--棋盘左右两边连通<LineBreak/>
操作说明:<LineBreak/>
‘W’,’A’,’S’,’D’--调整视角<LineBreak/>
‘Z’--展开/收缩棋盘<LineBreak/>
鼠标滚轮—改变视距远近<LineBreak/>
鼠标拖动棋盘改变视角<LineBreak/>
PS:利用Replay中的Playnow功能,您可以换下AI的棋:)
</TextBlock>
</Border>
</Grid>
</Grid>
<Grid HorizontalAlignment="Right" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="10"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap" Grid.Column="0" Grid.Row="2">Replay Control</TextBlock>
<Button x:Name="ReplayButton" Content="Replay" Grid.Column="0" Grid.Row="4" IsEnabled="False" Click="ReplayButton_Click">
</Button>
<Button x:Name="PlayNowButton" Content="PlayNow" Grid.Column="0" Grid.Row="6" IsEnabled="False" Click="PlayNowButton_Click" >
</Button>
<Button x:Name="NextButton" Content="Next" Grid.Column="0" Grid.Row="8" IsEnabled="False" Click="NextButton_Click">
</Button>
<Button x:Name="PreviousButton" Content="Previous" Grid.Column="0" Grid.Row="10" IsEnabled="False" Click="PreviousButton_Click">
</Button>
</Grid>
</Grid>
</UserControl>
xmal.cs:
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Balder.Silverlight.Content;
using Balder.Math;
using Balder.Objects.Geometries;
using Balder.Execution;
using Balder.Lighting;
using Balder.View;
using Balder.Materials;
using Balder.Objects;
using Balder.Assets;
using Balder.Animation.Silverlight;
using System.Threading;
using System.ComponentModel;
using System.Windows.Interop;
namespace Reversi3D
{
public partial class MainPage : UserControl
{
public AIChess chess = new AIChess();
public MainPage()
{
InitializeComponent();
The_Game();
}
private void The_Game()
{
Create_Tube();
Create_First_Page();
}
private void Create_First_Page()
{
m_bPictureShowBox = new Box()
{
Name = "PictureShowBox",
Dimension = new Coordinate(160, 120, 1),
Position = new Coordinate(0, 0, -30),
Rotation = new Coordinate(0, 0, 0)
};
m_bPictureShowBox.SetMaterialOnSide(0, StarReversiMaterial);
group.Children.Add(m_bPictureShowBox);
}
private void Game_Init()
{
for (char cXName = 'a'; cXName <= 'h'; cXName++)
for (char cYName = '1'; cYName <= '8'; cYName++)
{
((Cylinder)((Geometry)group.FindName(new string(new char[] { 'g', cXName, cYName }))).Children[1]).IsVisible = false;
}
int x, y;
for (x = 1; x < 9; x++)
{
for (y = 1; y < 9; y++)
{
if (chess.board[f(x, y)] == 0) ;
if (chess.board[f(x, y)] == 2)//WHITE
{
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).Material = WhiteMaterial;
}
if (chess.board[f(x, y)] == 1)//BLACK
{
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).Material = BlackMaterial ;
}
}
}
}
private void Create_Tube()
{
Coordinate cooBoxSize = new Coordinate(iBoxLength, iBoxWidth, iBoxHeight);
Coordinate cooBoxPosition = new Coordinate(0, 0, 0);
double iPositionX = (-3.5) * iBoxWidth;
for (char cXName = 'a'; cXName <= 'h'; iPositionX += iBoxWidth, cXName++)
{
double iPositionY = (3.5) * iBoxLength;
for (char cYName = '1'; cYName <= '8'; iPositionY -= iBoxLength, cYName++)
{
Box bBox = new Box()
{
Dimension = new Coordinate(iBoxWidth, iBoxLength, iBoxHeight),
Position = new Coordinate(0, 0, 0),
Rotation = new Coordinate(0, 0, 0),
Name = new System.String(new char[] { cXName, cYName })
};
bBox.Color = ((cXName - 'a' + cYName) % 2 == 0) ? Balder.Color.FromArgb(255, 79, 0, 3) : Balder.Color.FromArgb(255, 254, 254, 228);
Cylinder cyChessman = new Cylinder
{
TopRadius = 5,
BottomRadius = 5,
Segments = 20,
Size = 3,
Position = new Coordinate(0, 0, -2.5),
Name = new System.String(new char[] { 'c', cXName, cYName }),
IsVisible = false
};
// cyChessman.Material = ((cXName - 'a' + cYName) % 2 == 0) ? BlackMaterial : WhiteMaterial;
cyChessman.Rotation = new Coordinate(90, 0, 0);
Geometry minGroup = new Geometry()
{
Name = new System.String(new char[] {'g', cXName, cYName }),
Position = new Coordinate(iPositionX, iPositionY, -iBoxWidth / 2 / Math.Sin(double_to_angle(22.5))),
Rotation = new Coordinate(0, 0, 0)
};
minGroup.Children.Add(bBox);
minGroup.Children.Add(cyChessman);
group.Children.Add(minGroup);
}
}
Cylinder cyInner = new Cylinder()
{
BottomRadius = iBoxWidth / 2 / Math.Sin(double_to_angle(22.5)),
TopRadius = iBoxWidth / 2 / Math.Sin(double_to_angle(22.5)),
Segments = 8,
Position = new Coordinate(0, 0, 0),
Size = 8 * iBoxLength + 4,
Name = "inner"
};
cyInner.Color = Balder.Color.FromArgb(255, 48, 4, 121);
group.Children.Add(cyInner);
}
private void Board_Retract()
{
if (!bRetractInit)
{
bRetractInit = true;
Init_Board_Retract_Anmition();
}
if(bSpeared == true)
{
if (bRetractFinish == true)
{
bRetractFinish = false;
LayoutRoot.Resources.Add("retract", sbBoard_Retract);
sbBoard_Retract.Begin();
}
}
}
private void sbBoard_Retract_Completed(object sender, EventArgs e)
{
bRetractFinish = true;
LayoutRoot.Resources.Remove("retract");
bSpeared = false;
}
private void Init_Board_Retract_Anmition()
{
sbBoard_Retract = new Storyboard();
sbBoard_Retract.Completed += new EventHandler(sbBoard_Retract_Completed);
Duration duration = new System.TimeSpan(0, 0, 5);
sbBoard_Retract.Duration = duration;
Coordinate cooPosition;
Coordinate cooRotation;
double iPositionX = (-3.5) * iBoxWidth;
for (char cXName = 'a'; cXName <= 'h'; iPositionX += iBoxWidth, cXName++)
{
double iPositionY = (3.5) * iBoxLength;
for (char cYName = '1'; cYName <= '8'; iPositionY -= iBoxLength, cYName++)
{
cooPosition = ((Geometry)group.FindName(new System.String((new char[] { 'g', cXName, cYName })))).Position;
cooRotation = ((Geometry)group.FindName(new System.String((new char[] { 'g', cXName, cYName })))).Rotation;
DoubleAnimation dAnimationPX = new DoubleAnimation()
{
From = cooPosition.X,
To = dLengthX[cXName - 'a'],
Duration = duration
};
sbBoard_Retract.Children.Add(dAnimationPX);
Storyboard.SetTargetName(dAnimationPX, new System.String((new char[] { 'g', cXName, cYName })));
Storyboard.SetTargetProperty(dAnimationPX, new PropertyPath("(Node.Position).(X)"));
DoubleAnimation dAnimationPY = new DoubleAnimation()
{
From = cooPosition.Y,
To = iPositionY,
Duration = duration
};
sbBoard_Retract.Children.Add(dAnimationPY);
Storyboard.SetTargetName(dAnimationPY, new System.String((new char[] { 'g', cXName, cYName })));
Storyboard.SetTargetProperty(dAnimationPY, new PropertyPath("(Node.Position).(Y)"));
DoubleAnimation dAnimationPZ = new DoubleAnimation()
{
From = cooPosition.Z,
To = dLengthZ[cXName - 'a'],
Duration = duration
};
sbBoard_Retract.Children.Add(dAnimationPZ);
Storyboard.SetTargetName(dAnimationPZ, new System.String((new char[] { 'g', cXName, cYName })));
Storyboard.SetTargetProperty(dAnimationPZ, new PropertyPath("(Node.Position).(Z)"));
DoubleAnimation dRoationPY = new DoubleAnimation()
{
From = cooRotation.Y,
To = dRotationY[cXName - 'a'],
Duration = duration
};
sbBoard_Retract.Children.Add(dRoationPY);
Storyboard.SetTargetName(dRoationPY, new System.String((new char[] { 'g', cXName, cYName })));
Storyboard.SetTargetProperty(dRoationPY, new PropertyPath("(Node.Rotation).(Y)"));
}
}
}
private void Board_Spread()
{
if (!bSpeareInit)
{
bSpeareInit = true;
Init_Board_Spread_Anmition();
}
if(bSpeared == false)
{
if (bSpeareFinish == true)
{
bSpeareFinish = false;
LayoutRoot.Resources.Add("spread", sbBoard_Spread);
sbBoard_Spread.Begin();
}
}
}
private void sbBoard_Spread_Completed(object sender, EventArgs e)
{
// sbBoard_Spread.Stop();
LayoutRoot.Resources.Remove("spread");
bSpeareFinish = true;
bSpeared = true;
}
private void Init_Board_Spread_Anmition()
{
sbBoard_Spread = new Storyboard();
sbBoard_Spread.Completed += new EventHandler(sbBoard_Spread_Completed);
Duration duration = new System.TimeSpan(0, 0, 5);
sbBoard_Spread.Duration = duration;
Coordinate cooPosition;
Coordinate cooRotation;
double iPositionX = (-3.5) * iBoxWidth;
for (char cXName = 'a'; cXName <= 'h'; iPositionX += iBoxWidth, cXName++)
{
double iPositionY = (3.5) * iBoxLength;
for (char cYName = '1'; cYName <= '8'; iPositionY -= iBoxLength, cYName++)
{
cooPosition = ((Geometry)group.FindName(new System.String((new char[] { 'g', cXName, cYName })))).Position;
cooRotation = ((Geometry)group.FindName(new System.String((new char[] { 'g', cXName, cYName })))).Rotation;
DoubleAnimation dAnimationPX = new DoubleAnimation()
{
From = cooPosition.X,
To = iPositionX,
Duration = duration
};
sbBoard_Spread.Children.Add(dAnimationPX);
Storyboard.SetTargetName(dAnimationPX, new System.String((new char[] { 'g', cXName, cYName })));
Storyboard.SetTargetProperty(dAnimationPX, new PropertyPath("(Node.Position).(X)"));
DoubleAnimation dAnimationPY = new DoubleAnimation()
{
From = cooPosition.Y,
To = iPositionY,
Duration = duration
};
sbBoard_Spread.Children.Add(dAnimationPY);
Storyboard.SetTargetName(dAnimationPY, new System.String((new char[] { 'g', cXName, cYName })));
Storyboard.SetTargetProperty(dAnimationPY, new PropertyPath("(Node.Position).(Y)"));
DoubleAnimation dAnimationPZ = new DoubleAnimation()
{
From = cooPosition.Z,
To = -iBoxWidth / 2 / Math.Sin(double_to_angle(22.5)),
Duration = duration
};
sbBoard_Spread.Children.Add(dAnimationPZ);
Storyboard.SetTargetName(dAnimationPZ, new System.String((new char[] { 'g', cXName, cYName })));
Storyboard.SetTargetProperty(dAnimationPZ, new PropertyPath("(Node.Position).(Z)"));
DoubleAnimation dRoationPY = new DoubleAnimation()
{
From = cooRotation.Y,
To = 0,
Duration = duration
};
sbBoard_Spread.Children.Add(dRoationPY);
Storyboard.SetTargetName(dRoationPY, new System.String((new char[] { 'g', cXName, cYName })));
Storyboard.SetTargetProperty(dRoationPY, new PropertyPath("(Node.Rotation).(Y)"));
}
}
}
private double double_to_angle(double input)
{
return input * Math.PI / 180;
}
private void sbChessman_Anmition1_Completed(object sender, EventArgs e)
{
sbChessman_Anmition.Stop();
LayoutRoot.Resources.Remove("chessman_anmition1");
sbChessman_Anmition.Children.Clear();
sbChessman_Anmition = null;
foreach (string chessman in m_sTargetChessmen)
{
((Cylinder)((Geometry)group.FindName("g" + chessman)).Children[1]).Material
= chess.colour == 1 ? WhiteMaterial : BlackMaterial;
}
Chessman_Anmition2();
}
private void sbChessman_Anmition2_Completed(object sender, EventArgs e)
{
sbChessman_Anmition.Stop();
LayoutRoot.Resources.Remove("chessman_anmition2");
sbChessman_Anmition.Children.Clear();
sbChessman_Anmition = null;
if (bEnded == true)
{
bChessTrunarounded = true;
return;
}
if(chess.CanGoOrNot() == false)
{
chess.colour = 3 - chess.colour;
if (m_mode == MODEDEFINE.SING2D || m_mode == MODEDEFINE.SING3D)
bAIturn = bAIturn ? false : true;
if (bAIturn)
Lock = 1;
else Lock = 0;
}
if (m_mode == MODEDEFINE.DOUBLE2D || m_mode==MODEDEFINE.DOUBLE3D)
{
bAIturn = false;
Lock = 0;
}
if (bAIturn)
{
Thread tAIthread = new Thread(ComputerChessTurn);
tAIthread.Start();
bAIturn = false;
}
bChessTrunarounded = true;
}
private void Chessman_Anmition1()
{
sbChessman_Anmition = new Storyboard();
sbChessman_Anmition.Completed += new EventHandler(sbChessman_Anmition1_Completed);
LayoutRoot.Resources.Add("chessman_anmition1", sbChessman_Anmition);
Duration duration = new System.TimeSpan(0, 0, 0, 0, 400);
foreach (string chessman in m_sTargetChessmen)
{
DoubleAnimation dAnimationPZ = new DoubleAnimation
{
From = -2.5,
To = -18,
Duration = duration
};
sbChessman_Anmition.Children.Add(dAnimationPZ);
Storyboard.SetTargetName(dAnimationPZ, 'c' + chessman);
Storyboard.SetTargetProperty(dAnimationPZ, new PropertyPath("(Node.Position).(Z)"));
DoubleAnimation dAnimationRY = new DoubleAnimation
{
From = ((Cylinder)((Geometry)group.FindName('g' + chessman)).Children[1]).Rotation.Y,
To = ((Cylinder)((Geometry)group.FindName('g' + chessman)).Children[1]).Rotation.Y + 90,
Duration = duration,
SpeedRatio = 1
};
sbChessman_Anmition.Children.Add(dAnimationRY);
Storyboard.SetTargetName(dAnimationRY, 'c' + chessman);
Storyboard.SetTargetProperty(dAnimationRY, new PropertyPath("(Node.Rotation).(Y)"));
}
sbChessman_Anmition.Begin();
}
private void Chessman_Anmition2()
{
sbChessman_Anmition = new Storyboard();
sbChessman_Anmition.Completed += new EventHandler(sbChessman_Anmition2_Completed);
LayoutRoot.Resources.Add("chessman_anmition2", sbChessman_Anmition);
Duration duration = new System.TimeSpan(0, 0, 0, 0, 400);
foreach (string chessman in m_sTargetChessmen)
{
DoubleAnimation dAnimationPZ = new DoubleAnimation
{
From = -18,
To = -2.5,
Duration = duration
};
sbChessman_Anmition.Children.Add(dAnimationPZ);
Storyboard.SetTargetName(dAnimationPZ, 'c' + chessman);
Storyboard.SetTargetProperty(dAnimationPZ, new PropertyPath("(Node.Position).(Z)"));
DoubleAnimation dAnimationRY = new DoubleAnimation
{
From = ((Cylinder)((Geometry)group.FindName('g' + chessman)).Children[1]).Rotation.Y + 90,
To = ((Cylinder)((Geometry)group.FindName('g' + chessman)).Children[1]).Rotation.Y + 180,
Duration = duration,
SpeedRatio = 1
};
sbChessman_Anmition.Children.Add(dAnimationRY);
Storyboard.SetTargetName(dAnimationRY, 'c' + chessman);
Storyboard.SetTargetProperty(dAnimationRY, new PropertyPath("(Node.Rotation).(Y)"));
}
sbChessman_Anmition.Begin();
}
private void Chessman_TurnAround()
{
if (!bChessTrunarounded)
return;
bChessTrunarounded = false;
Chessman_Anmition1();
}
private void set_Camera_Position()
{
if(m_viewAngleYZ == 90 || m_viewAngleYZ == 270)
cCamera.Up = -cCamera.Up;
cCamera.Position.Z = -iViewLength * Math.Cos(double_to_angle(m_viewAngleXZ)) * Math.Cos(double_to_angle(m_viewAngleYZ));
cCamera.Position.X = iViewLength * Math.Sin(double_to_angle(m_viewAngleXZ)) * Math.Cos(double_to_angle(m_viewAngleYZ));
cCamera.Position.Y = iViewLength * Math.Sin(double_to_angle(m_viewAngleYZ));
}
private void Grid_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta > 0)
{
iViewLength -= iViewLength / 15;
set_Camera_Position();
}
if (e.Delta < 0)
{
iViewLength += iViewLength / 15;
set_Camera_Position();
}
}
private void LayoutRoot_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.W)
{
m_viewAngleYZ = (++m_viewAngleYZ) % 360;
set_Camera_Position();
}
if (e.Key == Key.S)
{
m_viewAngleYZ = (--m_viewAngleYZ) % 360;
set_Camera_Position();
}
if (e.Key == Key.A)
{
m_viewAngleXZ = (--m_viewAngleXZ) % 360;
set_Camera_Position();
}
if (e.Key == Key.D)
{
m_viewAngleXZ = (++m_viewAngleXZ) % 360;
set_Camera_Position();
}
if (e.Key == Key.Z)
{
if (bSpeared)
Board_Retract();
else
Board_Spread();
}
if(e.Key == Key.T)
{
Content contentObject = Application.Current.Host.Content;
contentObject.IsFullScreen = !contentObject.IsFullScreen;
}
}
private void LayoutRoot_KeyUp(object sender, KeyEventArgs e)
{
}
private void group_MouseLeftButtonDown(object sender, Balder.Input.MouseButtonEventArgs args)
{
sClickedBox = (args.OriginalSource.Name);
//attention!!! is box???
// ((Box)args.OriginalSource).Color = Colors.Red;
}
private void group_MouseLeftButtonUp(object sender, Balder.Input.MouseButtonEventArgs args)
{
if (bReplay == true)
return;
if (Lock == 0 && bChessTrunarounded == true)
{
if (sClickedBox == (args.OriginalSource.Name) &&
args.OriginalSource.Name != "inner" &&
(args.OriginalSource.GetType().ToString() == "Balder.Objects.Geometries.Box" ||
args.OriginalSource.GetType().ToString() == "Balder.Objects.Geometries.Cylinder"))
{
string sBoxName = args.OriginalSource.Name.Length == 2 ?
args.OriginalSource.Name : args.OriginalSource.Name.Remove(0, 1);
if (chess.ChangeBoard(sBoxName) != -1)
{
draw();
Lock = 1;
if (chess.NewGameOrNot())
{
bEnded = true;
Game_Over_Show_Picture(chess.WinSignal);
}
//BackgroundWorker bw = new BackgroundWorker();
//bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
//bw.DoWork += new DoWorkEventHandler(ComputerChessTurn);
//bw.RunWorkerAsync();
bAIturn = true;
}
}
else
sClickedBox = null;
}
}
//public void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
//{
// if (e.Result.ToString() != "-1")
// draw();
// Lock = 0; //IN IF OR NOT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//}
//public void ComputerChessTurn(object sender, DoWorkEventArgs e)
//{
// e.Result = chess.ComputerTurn();
//}
public void ComputerChessTurn()
{
if (chess.ComputerTurn() != -1)
{
this.Dispatcher.BeginInvoke(() => {
draw();
Lock = 0;
if (chess.NewGameOrNot())
{
bEnded = true;
Game_Over_Show_Picture(chess.WinSignal);
}
});
}
}
public void draw()
{
((Cylinder)((Geometry)group.FindName("g" + chess.TurnGridArray[chess.TurnGridArray.Count - 1])).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName("g" + chess.TurnGridArray[chess.TurnGridArray.Count - 1])).Children[1]).Material =
(chess.colour == 1 ? WhiteMaterial : BlackMaterial);
if(bReplay == false)
{
m_sPositionRecord.Add(chess.TurnGridArray[chess.TurnGridArray.Count - 1]);
}
chess.TurnGridArray.RemoveAt(chess.TurnGridArray.Count - 1);
m_sTargetChessmen = chess.TurnGridArray;
Chessman_TurnAround();
_player1sorce.Text = chess.black.ToString();
_player2sorce.Text = chess.white.ToString();
return;
}
private void Mode_Choice()
{
switch (ModeComboBox.SelectedIndex)
{
case 0:
chess.ChangeMode(2);
switch (PlayerNumberComboBox.SelectedIndex)
{
case 0:
m_mode = MODEDEFINE.SING2D;
break;
case 1:
m_mode = MODEDEFINE.DOUBLE2D;
break;
default:
break;
}
break;
case 1:
chess.ChangeMode(3);
switch (PlayerNumberComboBox.SelectedIndex)
{
case 0:
m_mode = MODEDEFINE.SING3D;
break;
case 1:
m_mode = MODEDEFINE.DOUBLE3D;
break;
default:
break;
}
break;
default:
m_mode = MODEDEFINE.SING3D;
break;
}
m_SelectedMode = m_mode;
}
private void Game_Over_Show_Picture(WhoWin whowin)
{
if (bExchangeSide == true && ((m_SelectedMode == MODEDEFINE.SING2D || m_SelectedMode == MODEDEFINE.SING3D)))
{
switch (whowin)
{
case WhoWin.WhiteWin:
whowin = WhoWin.BlackWin;
break;
case WhoWin.BlackWin:
whowin = WhoWin.WhiteWin;
break;
case WhoWin.Draw:
break;
default:
break;
}
}
if (m_mode == MODEDEFINE.DOUBLE2D || m_mode == MODEDEFINE.DOUBLE3D)
{
m_bPictureShowBox.Material = GameOverMaterial;
switch (whowin)
{
case WhoWin.WhiteWin:
_result.Text = "Player2 win!";
break;
case WhoWin.BlackWin:
_result.Text = "Player1 win!";
break;
case WhoWin.Draw:
_result.Text = "Draw!";
break;
default:
break;
}
}
else
switch (whowin)
{
case WhoWin.WhiteWin:
_result.Text = "You lose!";
m_bPictureShowBox.Material = YouLoseMaterial;
break;
case WhoWin.BlackWin:
_result.Text = "You win!";
m_bPictureShowBox.Material = YouWinMaterial;
break;
case WhoWin.Draw:
_result.Text = "Draw!";
m_bPictureShowBox.Material = GameOverMaterial;
break;
default:
break;
}
group.World.M11 = 1;
group.World.M12 = 0;
group.World.M13 = 0;
group.World.M14 = 0;
group.World.M21 = 0;
group.World.M22 = 1;
group.World.M23 = 0;
group.World.M24 = 0;
group.World.M31 = 0;
group.World.M32 = 0;
group.World.M33 = 1;
group.World.M34 = 0;
group.World.M41 = 0;
group.World.M42 = 0;
group.World.M43 = 0;
group.World.M44 = 1;
LayoutRoot.UpdateLayout();
if (group.Children.Contains(m_bPictureShowBox) == true)
group.Children.Remove(m_bPictureShowBox);
if(group.Children.Contains(m_bPictureShowBox) == false)
group.Children.Add(m_bPictureShowBox);
}
private void Game_Start()
{
group.Children.Remove(m_bPictureShowBox);
if(m_mode == MODEDEFINE.SING2D || m_mode == MODEDEFINE.SING3D)
{
_player1name.Text = "You";
_player2name.Text = "AI";
}
else
{
_player1name.Text = "Player1";
_player2name.Text = "Player2";
}
_player1sorce.Text = "2";
_player2sorce.Text = "2";
if (m_mode == MODEDEFINE.DOUBLE3D || m_mode == MODEDEFINE.SING3D)
Board_Retract();
else
Board_Spread();
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
m_sPositionRecord = new List<string>();
StartButton.IsEnabled = false;
ReplayButton.IsEnabled = false;
ModeComboBox.IsEnabled = false;
PlayerNumberComboBox.IsEnabled = false;
PlayNowButton.IsEnabled = false;
EndThisGame.IsEnabled = true;
NextButton.IsEnabled = false;
PreviousButton.IsEnabled = false;
bAIturn = false;
bExchangeSide = false;
Lock = 0;
bChessTrunarounded = true;
bEnded = false;
bReplay = false;
_result.Text = "";
chess.NEW(3);
Game_Init();
Mode_Choice();
Game_Start();
if (group.Children.Contains(m_bPictureShowBox) == true)
group.Children.Remove(m_bPictureShowBox);
}
private void ReplayButton_Click(object sender, RoutedEventArgs e)
{
if (m_sPositionRecord.Count == 0)
return;
if (m_sTargetChessmen.Count == 0)
{
NextButton.IsEnabled = false;
}
else
NextButton.IsEnabled = true;
StartButton.IsEnabled = false;
PreviousButton.IsEnabled = false;
PlayNowButton.IsEnabled = true;
EndThisGame.IsEnabled = true;
bExchangeSide = false;
bAIturn = false;
Lock = 0;
bChessTrunarounded = true;
bEnded = false;
bReplay = true;
bAIturnInReplay = false;
m_iReplayIndex = 0;
bPreviousDraw = false;
m_boardRecord = new List<int[]>();
m_blackRecord = new List<int>();
m_whiteRecord = new List<int>();
m_colourRecord = new List<int>();
_result.Text = "";
if (m_SelectedMode == MODEDEFINE.DOUBLE2D || m_SelectedMode == MODEDEFINE.SING2D)
chess.NEW(2);
else
chess.NEW(3);
Game_Init();
Game_Start();
if (m_mode == MODEDEFINE.DOUBLE2D || m_mode == MODEDEFINE.SING2D)
m_mode = MODEDEFINE.DOUBLE2D;
else
m_mode = MODEDEFINE.DOUBLE3D;
if (group.Children.Contains(m_bPictureShowBox) == true)
group.Children.Remove(m_bPictureShowBox);
}
private void PlayNowButton_Click(object sender, RoutedEventArgs e)
{
int x, y;
for (x = 1; x < 9; x++)
{
for (y = 1; y < 9; y++)
{
if (chess.board[f(x, y)] == 0)
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = false;
if (chess.board[f(x, y)] == 2)//WHITE
{
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).Material = WhiteMaterial;
}
if (chess.board[f(x, y)] == 1)//BLACK
{
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).Material = BlackMaterial;
}
}
}
bReplay = false;
m_sPositionRecord.RemoveRange(m_iReplayIndex, m_sPositionRecord.Count - m_iReplayIndex);
m_mode = m_SelectedMode;
StartButton.IsEnabled = false;
ReplayButton.IsEnabled = false;
ModeComboBox.IsEnabled = false;
PlayerNumberComboBox.IsEnabled = false;
PlayNowButton.IsEnabled = false;
EndThisGame.IsEnabled = true;
NextButton.IsEnabled = false;
PreviousButton.IsEnabled = false;
// bAIturn = bAIturnInReplay; //是否可换下AI的棋
if( bAIturnInReplay == true
&& (m_SelectedMode == MODEDEFINE.SING2D || m_SelectedMode == MODEDEFINE.SING3D) )
{
bExchangeSide = true;
_player1name.Text = "AI";
_player2name.Text = "You";
}
if (bEnded == true)
{
bChessTrunarounded = true;
return;
}
if (chess.CanGoOrNot() == false)
{
chess.colour = 3 - chess.colour;
if (m_mode == MODEDEFINE.SING2D || m_mode == MODEDEFINE.SING3D)
bAIturn = bAIturn ? false : true;
if (bAIturn)
Lock = 1;
else Lock = 0;
}
if (m_mode == MODEDEFINE.DOUBLE2D || m_mode == MODEDEFINE.DOUBLE3D)
{
bAIturn = false;
Lock = 0;
}
if (bAIturn)
{
Thread tAIthread = new Thread(ComputerChessTurn);
tAIthread.Start();
bAIturn = false;
}
}
private void NextButton_Click(object sender, RoutedEventArgs e)
{
int x, y;
for (x = 1; x < 9; x++)
{
for (y = 1; y < 9; y++)
{
if (chess.board[f(x, y)] == 0)
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = false;
if (chess.board[f(x, y)] == 2)//WHITE
{
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).Material = WhiteMaterial;
}
if (chess.board[f(x, y)] == 1)//BLACK
{
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).Material = BlackMaterial;
}
}
}
int[] tempBoard = new int[91];
for (int i = 0; i < 91; i++)
tempBoard[i] = chess.board[i];
m_boardRecord.Add(tempBoard);
m_blackRecord.Add(chess.black);
m_whiteRecord.Add(chess.white);
m_colourRecord.Add(chess.colour);
PreviousButton.IsEnabled = true;
bAIturnInReplay = (chess.colour == 1 ? true : false); //是否可换下AI的棋
if (chess.ChangeBoard(m_sPositionRecord[m_iReplayIndex]) != -1)
{
m_iReplayIndex++;
if (m_iReplayIndex == m_sPositionRecord.Count)
{
NextButton.IsEnabled = false;
}
draw();
Lock = 1;
if (chess.NewGameOrNot())
{
bEnded = true;
Game_Over_Show_Picture(chess.WinSignal);
}
//BackgroundWorker bw = new BackgroundWorker();
//bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
//bw.DoWork += new DoWorkEventHandler(ComputerChessTurn);
//bw.RunWorkerAsync();
bAIturn = true;
//Thread tAIthread = new Thread(ComputerChessTurn);
//tAIthread.Start();
}
}
private void PreviousButton_Click(object sender, RoutedEventArgs e)
{
chess.board = m_boardRecord[m_boardRecord.Count - 1];
chess.black = m_blackRecord[m_blackRecord.Count - 1];
chess.white = m_whiteRecord[m_whiteRecord.Count - 1];
chess.colour = m_colourRecord[m_colourRecord.Count - 1];
m_boardRecord.RemoveAt(m_boardRecord.Count - 1);
m_blackRecord.RemoveAt(m_blackRecord.Count - 1);
m_whiteRecord.RemoveAt(m_whiteRecord.Count - 1);
m_colourRecord.RemoveAt(m_colourRecord.Count - 1);
m_iReplayIndex--;
NextButton.IsEnabled = true;
if (m_iReplayIndex == 0)
PreviousButton.IsEnabled = false;
int x, y;
for (x = 1; x < 9; x++)
{
for (y = 1; y < 9; y++)
{
if (chess.board[f(x, y)] == 0)
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = false;
if (chess.board[f(x, y)] == 2)//WHITE
{
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).Material = WhiteMaterial;
}
if (chess.board[f(x, y)] == 1)//BLACK
{
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).IsVisible = true;
((Cylinder)((Geometry)group.FindName(new System.String(new char[] { 'g', (char)(x - 1 + 'a'), (char)(y - 1 + '1') }))).Children[1]).Material = BlackMaterial;
}
}
}
}
private void EndThisGame_Click(object sender, RoutedEventArgs e)
{
StartButton.IsEnabled = true;
ReplayButton.IsEnabled = true;
ModeComboBox.IsEnabled = true;
PlayerNumberComboBox.IsEnabled = true;
EndThisGame.IsEnabled = false;
WhoWin Winsignal = new WhoWin();
if (chess.white > chess.black) Winsignal = WhoWin.WhiteWin;
if (chess.white < chess.black) Winsignal = WhoWin.BlackWin;
if (chess.white == chess.black) Winsignal = WhoWin.Draw;
Game_Over_Show_Picture(Winsignal);
}
private int f(int x, int y) { return (x * 9 + y); }
const int iBoxHeight = 1;
const int iBoxWidth = 20;
const int iBoxLength = 15;
private int Lock = 0;
private bool bEnded = false;
private int m_viewAngleXZ = 0;
private int m_viewAngleYZ = 0;
private Storyboard sbBoard_Spread;
private Storyboard sbBoard_Retract;
private Storyboard sbChessman_Anmition;
int iViewLength = 190;
static double dSin225 = Math.Sin(22.5 * Math.PI / 180);
static double dCos225 = Math.Cos(22.5 * Math.PI / 180);
static double dTan225 = Math.Tan(22.5 * Math.PI / 180);
static double dConstdl1 = iBoxWidth / 2 * dCos225;
static double dConstdl2 = iBoxWidth / 2 / dTan225 * dCos225;
double[] dLengthX = { -dConstdl1, -dConstdl2, -dConstdl2, -dConstdl1, dConstdl1, dConstdl2, dConstdl2, dConstdl1 };
double[] dLengthZ = { dConstdl2, dConstdl1, -dConstdl1, -dConstdl2, -dConstdl2, -dConstdl1, dConstdl1, dConstdl2 };
double[] dRotationY = { 157.5, 112.5, 67.5, 22.5, -22.5, -67.5, -112.5, -157.5 };
private bool bSpeareInit = false;
private bool bRetractInit = false;
private bool bSpeareFinish = true;
private bool bRetractFinish = true;
private bool bExchangeSide = false;
private string sClickedBox;
private bool bSpeared = true;
private bool bChessTrunarounded = true;
private bool bAIturn = false;
private MODEDEFINE m_mode = new MODEDEFINE();
private Box m_bPictureShowBox;
private List<string> m_sTargetChessmen;
private List<string> m_sPositionRecord;
private List<int[]> m_boardRecord;
private List<int> m_blackRecord;
private List<int> m_whiteRecord;
private List<int> m_colourRecord;
private bool bReplay = false;
private int m_iReplayIndex = 0;
private bool bAIturnInReplay = false;
private bool bPreviousDraw = false;
private MODEDEFINE m_SelectedMode = new MODEDEFINE();
enum MODEDEFINE:int
{
SING2D = 1,
DOUBLE2D,
SING3D,
DOUBLE3D
};
}
}