This file contains 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.Linq; | |
namespace SlidingPuzzle | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.Clear(); | |
Console.CursorVisible = false; | |
var game = new SlidingPuzzle(); | |
PrintBoard(game.Board); | |
while (true) | |
{ | |
if (Console.KeyAvailable) | |
{ | |
var key = Console.ReadKey(true); | |
Move? direction = null; | |
switch (key.Key) | |
{ | |
case ConsoleKey.UpArrow: | |
direction = Move.Up; | |
break; | |
case ConsoleKey.DownArrow: | |
direction = Move.Down; | |
break; | |
case ConsoleKey.LeftArrow: | |
direction = Move.Left; | |
break; | |
case ConsoleKey.RightArrow: | |
direction = Move.Right; | |
break; | |
case ConsoleKey.Escape: | |
return; | |
} | |
if (direction != null) | |
{ | |
var fieldsToRefresh = game.TryMove(direction.Value); | |
if (fieldsToRefresh.Any()) | |
{ | |
RefreshBoard(game.Board, fieldsToRefresh); | |
if (game.Won()) | |
break; | |
} | |
} | |
} | |
} | |
Console.SetCursorPosition(4, 6); | |
Console.WriteLine("Victory!"); | |
Console.ReadLine(); | |
} | |
static void PrintBoard(int[][] board) | |
{ | |
for (var row = 0; row < board.Length; row++) | |
{ | |
for (var column = 0; column < board[row].Length; column++) | |
{ | |
RefreshField(board[row][column], new FieldLocation(column, row)); | |
} | |
} | |
} | |
static void RefreshBoard(int[][] board, FieldLocation[] fieldsToRefresh) | |
{ | |
foreach(var field in fieldsToRefresh) | |
RefreshField(board[field.Row][field.Column], field); | |
} | |
static void RefreshField(int value, FieldLocation fieldPosition) | |
{ | |
if (value == -1) | |
{ | |
Console.BackgroundColor = ConsoleColor.Black; | |
WriteEmptyFieldLine(fieldPosition.Column * 4, fieldPosition.Row * 3); | |
WriteEmptyFieldLine(fieldPosition.Column * 4, fieldPosition.Row * 3 + 1); | |
WriteEmptyFieldLine(fieldPosition.Column * 4, fieldPosition.Row * 3 + 2); | |
} | |
else | |
{ | |
Console.BackgroundColor = ConsoleColor.DarkGreen; | |
WriteEmptyFieldLine(fieldPosition.Column * 4, fieldPosition.Row * 3); | |
Console.SetCursorPosition(fieldPosition.Column * 4, fieldPosition.Row * 3 + 1); | |
Console.Write(" "); | |
if (value < 10) | |
Console.Write("0"); | |
Console.Write(value); | |
Console.Write(" "); | |
WriteEmptyFieldLine(fieldPosition.Column * 4, fieldPosition.Row * 3 + 2); | |
} | |
Console.ResetColor(); | |
} | |
static void WriteEmptyFieldLine(int left, int top) | |
{ | |
Console.SetCursorPosition(left, top); | |
Console.Write(" "); | |
} | |
} | |
public class SlidingPuzzle | |
{ | |
public int[][] Board { get; } | |
private FieldLocation emptyField; | |
public SlidingPuzzle() | |
{ | |
Board = new int[][] | |
{ | |
new int[]{ -1, 1, 2, 3 }, | |
new int[]{ 4, 5, 6, 7 }, | |
new int[]{ 8, 9, 10, 11 }, | |
new int[]{ 12, 13, 14, 15 } | |
}; | |
emptyField = new FieldLocation(0, 0); | |
var rnd = new Random(); | |
for (var i = 0; i < 100; i++) | |
TryMove((Move)rnd.Next(4)); | |
} | |
public FieldLocation[] TryMove(Move move) | |
{ | |
switch (move) | |
{ | |
case Move.Up: | |
return Swap(new FieldLocation(emptyField.Column, emptyField.Row + 1)); | |
case Move.Down: | |
return Swap(new FieldLocation(emptyField.Column, emptyField.Row - 1)); | |
case Move.Left: | |
return Swap(new FieldLocation(emptyField.Column + 1, emptyField.Row)); | |
case Move.Right: | |
return Swap(new FieldLocation(emptyField.Column - 1, emptyField.Row)); | |
} | |
return new FieldLocation[0]; | |
} | |
private FieldLocation[] Swap(FieldLocation from) | |
{ | |
if (from.Column > 3 || from.Column < 0 || from.Row > 3 || from.Row < 0) | |
return new FieldLocation[0]; | |
var affectedFields = new FieldLocation[] { emptyField, from }; | |
var temp = Board[emptyField.Row][emptyField.Column]; | |
Board[emptyField.Row][emptyField.Column] = Board[from.Row][from.Column]; | |
Board[from.Row][from.Column] = temp; | |
emptyField = from; | |
return affectedFields; | |
} | |
public bool Won() | |
{ | |
if (Board[0][0] != -1) | |
return false; | |
var expectedNumber = 1; | |
for (var row = 0; row < 4; row++) | |
{ | |
var firstFieldToTest = row == 0 ? 1 : 0; | |
for (var column = firstFieldToTest; column < 4; column++) | |
{ | |
if (Board[row][column] != expectedNumber) | |
return false; | |
expectedNumber++; | |
} | |
} | |
return true; | |
} | |
} | |
public struct FieldLocation | |
{ | |
public int Column { get; set; } | |
public int Row { get; set; } | |
public FieldLocation(int column, int row) | |
{ | |
Column = column; | |
Row = row; | |
} | |
} | |
public enum Move : byte | |
{ | |
Up, | |
Down, | |
Left, | |
Right | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment