Skip to content

Instantly share code, notes, and snippets.

@tomaszbartoszewski
Last active March 3, 2020 20:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomaszbartoszewski/20eae51c6763cece407082ca87ae8c23 to your computer and use it in GitHub Desktop.
Save tomaszbartoszewski/20eae51c6763cece407082ca87ae8c23 to your computer and use it in GitHub Desktop.
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