Created
March 19, 2016 07:09
-
-
Save adam-phillipps/fc823b33edab971b0838 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Windows.Media; | |
namespace Connect4 | |
{ | |
class PanelBackend | |
{ | |
public SolidColorBrush[,] panel; | |
public PanelBackend() | |
{ | |
panel = new SolidColorBrush[6, 7]; | |
} | |
public int DropDisk(int? currentMove, SolidColorBrush diskColor) | |
{ | |
int slot = currentMove ?? default(int); | |
int height = GetHeight(slot); | |
panel[height, slot] = diskColor; | |
return height; | |
} | |
public bool CheckForWin(int height, int slot) | |
{ | |
return (CheckDiagonal(height, slot) | |
|| CheckHorizontal(height, slot) | |
|| CheckVertical(height, slot)); | |
} | |
private bool CheckDiagonal(int height, int slot) | |
{ | |
int count = 0; | |
int reverseCount = 0; | |
int tempHeight = height; | |
// count from all four lines going diagonally away from the current move | |
// counts up and to the right | |
for (int tempSlot = slot; (tempSlot < panel.GetLength(1) && tempHeight < panel.GetLength(0)); tempSlot++) | |
{ | |
if (panel[tempHeight, tempSlot] == panel[height, slot]) | |
{ | |
count += 1; | |
} | |
else | |
{ break; } | |
tempHeight += 1; | |
} | |
tempHeight = height; | |
if (count == 4) | |
return true; | |
// counts down and to the left to join the first partial line with this one | |
for (int tempSlot = slot; (tempSlot > 0 && tempHeight > 0); tempSlot++) | |
{ | |
if (panel[tempHeight, tempSlot] == panel[height, slot]) | |
{ // don't count the origin again | |
if (tempSlot != slot && tempHeight != height) | |
count += 1; | |
} | |
else { break; } | |
tempHeight -= 1; | |
} | |
if (count == 4) | |
return true; | |
tempHeight = height; | |
// counts up and to the left | |
for (int tempSlot = slot; (tempSlot > 0 && tempHeight < panel.GetLength(0)); tempSlot--) | |
{ | |
if (panel[tempHeight, tempSlot] == panel[height, slot]) | |
{ | |
reverseCount += 1; | |
} | |
else { break; } | |
tempHeight += 1; | |
} | |
tempHeight = height; | |
// counts down and to the right to finish the up and to the left line | |
for (int tempSlot = slot; (tempSlot < panel.GetLength(1) && tempHeight > 0); tempSlot++) | |
{ | |
if (panel[tempHeight, tempSlot] == panel[height, slot]) | |
{ // don't count the origin again | |
if (tempSlot != slot && tempHeight != height) | |
reverseCount += 1; | |
} | |
else { break; } | |
tempHeight -= 1; | |
} | |
if (reverseCount == 4) | |
return true; | |
return (count >= 4 || reverseCount >= 4); | |
} | |
private bool CheckHorizontal(int height, int slot) | |
{ | |
int count = 0; | |
for (int col = 0; col < panel.GetLength(1); col++) | |
{ | |
if (panel[height, col] == panel[height, slot]) | |
{ | |
if ((count += 1) == 4) | |
break; | |
} | |
else | |
count = 0; | |
} | |
return count == 4; | |
} | |
private bool CheckVertical(int height, int slot) | |
{ | |
int count = 0; | |
for (int row = 0; row < panel.GetLength(0); row++) | |
{ | |
if (panel[row, slot] == panel[height, slot]) | |
{ | |
if ((count += 1) == 4) | |
break; | |
} | |
else | |
count = 0; | |
} | |
return count == 4; | |
} | |
public int GetHeight(int slot) | |
{ | |
int number = 6; | |
for (int lastFilledRow = 0; lastFilledRow < 5; ++lastFilledRow) | |
{ | |
if (panel[lastFilledRow, slot] == null) | |
{ | |
number = lastFilledRow; | |
} | |
else | |
break; | |
} | |
return number; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Window x:Class="Connect4.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:Connect4" | |
mc:Ignorable="d" | |
Title="Connect 4" Height="350" Width="525"> | |
<!-- contains and organizes the game area and reset button --> | |
<Grid x:Name="BaseOrganizer" Background="Black"> | |
<!-- | |
top grid row = top row that placeholder disk moves in | |
middle six grid rows = game area | |
bottom grid row = reset button | |
--> | |
<Grid.RowDefinitions> | |
<RowDefinition Height="*"/> | |
<RowDefinition Height="6*"/> | |
<RowDefinition Height="*" /> | |
</Grid.RowDefinitions> | |
<!-- where the action happens --> | |
<Grid x:Name="gamePanel" | |
Grid.Row="1" | |
Grid.Column="0" | |
Grid.ColumnSpan="7" | |
Background="Blue" | |
ShowGridLines="True"> | |
<Canvas x:Name="animationBoard" /> | |
</Grid> | |
<!-- user controls --> | |
<DockPanel x:Name="UserControlls" Grid.Row="2" > | |
<Button x:Name="resetButton" | |
Content="Reset the game" | |
Click="resetButton_Click"> | |
<Button.Background> | |
<LinearGradientBrush> | |
<LinearGradientBrush.GradientStops> | |
<GradientStop Offset="0.0" Color="Red" /> | |
<GradientStop Offset="1.0" Color="Blue" /> | |
</LinearGradientBrush.GradientStops> | |
</LinearGradientBrush> | |
</Button.Background> | |
</Button> | |
</DockPanel> | |
</Grid> | |
</Window> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.Navigation; | |
using System.Windows.Shapes; | |
using System.Windows.Threading; | |
namespace Connect4 | |
{ | |
/// <summary> | |
/// Interaction logic for MainWindow.xaml | |
/// </summary> | |
public partial class MainWindow : Window | |
{ | |
private DispatcherTimer timer = new DispatcherTimer(); | |
private int startTop = 80; | |
private int currentTop; | |
private int bottom = 330; | |
private SolidColorBrush yellow = Brushes.Yellow; | |
private SolidColorBrush red = Brushes.Red; | |
private SolidColorBrush turn; | |
private PanelBackend panel; | |
private int[] XY = new int[2]; | |
private int animationStopRow; | |
private Ellipse currentEllipse; | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
SetUpGamePanel(); | |
Play(); | |
} | |
public void Play() | |
{ | |
int turnCounter = 0; | |
do | |
{ | |
turn = ((turnCounter += 1) % 2 == 0) | |
? red | |
: yellow; | |
Ellipse disk = Disk(turn); | |
currentEllipse = disk; | |
Keyboard.Focus(disk); | |
} | |
while (!IsWinningMove() && turnCounter < 42); | |
if (turnCounter < 42) | |
FlashingHappyFunTime(); | |
else | |
Reset(); | |
panel = new PanelBackend(); | |
} | |
private int[] GetMove(Ellipse currentDisk) | |
{ | |
int lastCol = XY[1]; | |
int currentCol = lastCol; | |
while (currentCol == lastCol) | |
{ | |
currentCol = lastCol + 1; | |
} | |
return XY; | |
} | |
private bool IsWinningMove() | |
{ | |
SolidColorBrush b = Brushes.Yellow; | |
animationStopRow = panel.DropDisk(XY[1], ((SolidColorBrush)currentEllipse.Fill)); | |
return panel.CheckForWin(animationStopRow, XY[1]); | |
} | |
private void InitTimer() | |
{ | |
timer.Interval = new TimeSpan(0, 0, 0, 0, 25); | |
timer.Tick += AnimateDiskDrop; | |
} | |
private void AnimateDiskDrop(object sender, EventArgs e) | |
{ | |
const int updateDistance = 10; | |
if (currentTop + updateDistance <= bottom) | |
{ | |
currentTop += updateDistance; | |
Canvas.SetTop(Disk(Brushes.Yellow), currentTop); | |
} | |
else | |
{ | |
timer.Stop(); | |
} | |
} | |
private void FlashingHappyFunTime() | |
{ | |
//throw new NotImplementedException(); | |
} | |
private Grid SetUpGamePanel() | |
{ | |
panel = new PanelBackend(); | |
gamePanel.ColumnDefinitions.Add(Col()); | |
for (int row = 0; row < 6; row++) | |
{ | |
gamePanel.RowDefinitions.Add(Row()); | |
gamePanel.ColumnDefinitions.Add(Col()); | |
} | |
return gamePanel; | |
} | |
private Ellipse Disk(SolidColorBrush turn) | |
{ | |
const int size = 30; | |
Ellipse disk = new Ellipse(); | |
disk.Fill = turn; | |
disk.Width = disk.Height = size; | |
disk.KeyDown += Disk_KeyDown; | |
return disk; | |
} | |
private void Disk_KeyDown(object sender, KeyEventArgs e) | |
{ | |
while (e.Key != Key.Enter) | |
{ | |
if (e.Key == Key.Right) | |
{ | |
// cd.location -= UpdateDistance; | |
} | |
else if (e.Key == Key.Left) | |
{ | |
// cd.location += updateDistance; | |
} | |
} | |
// XY[0] = cd.location; | |
int current = XY[1]; | |
//var currentPosition = sender.TranslatePoint(new Point(0, 0), gamePanel); | |
} | |
private RowDefinition Row() | |
{ | |
return new RowDefinition(); | |
} | |
private ColumnDefinition Col() | |
{ | |
return new ColumnDefinition(); | |
} | |
private void resetButton_Click(object sender, RoutedEventArgs e) | |
{ | |
Reset(); | |
} | |
private void Reset() | |
{ | |
//SetUpGamePanel(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment