I am completely new to object oriented programing (OOP). I have also never worked with C#
before. The exercise from my book had some requirements that should be followed to complete the exercise.
Use of at least two classes (not counting the main class), one of which should be a Tile class, representing the tiles
No public fields with the exception of the field representing the value of Tiles.
The value field of Tiles must be readonly
This are the problems I am currently facing.
- I dont know what the tile class should do or how it should be implemented.
- I am almost 100% sure I am not following the guidelines (tried my best)
- I think my shuffle method and detection if the puzzle is solvable is wrong
Program.cs
class Program
{
static void Main(string[] args)
{
Board board = new Board();
board.StartGame();
}
}
Tile.cs
class Tile
{
readonly public int Value;
}
Board.cs
class Board
{
private int[,] Arr2d { get; set; }
private int Size { get; set; }
public void StartGame()
{
Size = 3;
Arr2d = new int[Size, Size];
FillTiles();
ShuffleTiles();
if (IsSolvable() == true)
{
PrintArr();
}
else
{
StartGame();
}
SwapTiles();
Console.WriteLine("Finished the game");
}
private void FillTiles()
{
int k = 0;
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
Arr2d[i, j] = k++;
}
}
}
private void ShuffleTiles()
{
Random random = new Random();
int n = Arr2d.GetLength(1);
for (int i = Arr2d.Length - 1; i > 0; i--)
{
int i0 = i / n;
int i1 = i % n;
int j = random.Next(i + 1);
int j0 = j / n;
int j1 = j % n;
int temp = Arr2d[i0, i1];
Arr2d[i0, i1] = Arr2d[j0, j1];
Arr2d[j0, j1] = temp;
}
}
private int GetInvCount()
{
//List<int> flattedList = new List<int> { 1, 20, 6, 4, 5 };
var flattedList = Arr2d.OfType<int>().ToList();
int inv_count = 0;
for (int i = 0; i < flattedList.Count - 1; i++) {
for (int j = i + 1; j < flattedList.Count; j++)
{
if (flattedList[i] > flattedList[j])
{
inv_count++;
}
}
}
return inv_count+1;
}
private int GetRowNumberFromBelow(int emptyTilePosition)
{
var row = emptyTilePosition / Size;
return Size - row;
}
private bool IsSolvable()
{
int numberOfInversions = GetInvCount();
if (Size % 2 != 0)
{
return (numberOfInversions % 2 == 0);
}
int pos = GetRowNumberFromBelow(IndexZeroPos());
if (pos % 2 != 0)
{
return (numberOfInversions % 2 == 0);
}
else
{
return (numberOfInversions % 2 != 0);
}
}
private void PrintArr()
{
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
Console.Write(Arr2d[i, j] + " ");
}
Console.WriteLine();
}
}
private bool ArrSorted()
{
var flattedList = Arr2d.OfType<int>().ToList();
var result = flattedList.OrderByDescending(x => x !=0).ThenBy(x => x).SequenceEqual(flattedList);
return result;
}
private int IndexZeroPos()
{
var flattedList = Arr2d.OfType<int>().ToList();
int i = flattedList.IndexOf(0);
return i;
}
private void SwapTiles()
{
int y = IndexZeroPos() % Size;
int x = IndexZeroPos() / Size;
var isSorted = ArrSorted();
while (isSorted != true)
{
ConsoleKeyInfo info = Console.ReadKey();
Console.WriteLine();
if (info.Key == ConsoleKey.RightArrow)
{
if (y >= (Size - 1))
{
continue;
}
int temp = Arr2d[x, y];
Arr2d[x, y] = Arr2d[x, (y + 1)];
Arr2d[x, (y + 1)] = temp;
if (isSorted != ArrSorted())
{
break;
}
else
{
y = IndexZeroPos() % Size;
x = IndexZeroPos() / Size;
PrintArr();
}
}
if (info.Key == ConsoleKey.LeftArrow)
{
if (y <= 0)
{
continue;
}
int temp = Arr2d[x, y];
Arr2d[x, y] = Arr2d[x, (y - 1)];
Arr2d[x, (y - 1)] = temp;
if (isSorted != ArrSorted())
{
break;
}
else
{
y = IndexZeroPos() % Size;
x = IndexZeroPos() / Size;
PrintArr();
}
}
if (info.Key == ConsoleKey.UpArrow)
{
if (x <= 0)
{
continue;
}
int temp = Arr2d[x, y];
Arr2d[x, y] = Arr2d[(x - 1), y];
Arr2d[(x - 1), y] = temp;
if (isSorted != ArrSorted())
{
break;
}
else
{
y = IndexZeroPos() % Size;
x = IndexZeroPos() / Size;
PrintArr();
}
}
if (info.Key == ConsoleKey.DownArrow)
{
if (x >= (Size - 1))
{
continue;
}
int temp = Arr2d[x, y];
Arr2d[x, y] = Arr2d[(x + 1), y];
Arr2d[(x + 1), y] = temp;
if (isSorted != ArrSorted())
{
break;
}
else
{
y = IndexZeroPos() % Size;
x = IndexZeroPos() / Size;
PrintArr();
}
}
}
}
}
As this is my first small project I feel like any feedback will do me good and I would really appreciate any feedback of any sort to become better.
The code above works, as in the user can move and it will complete when the puzzle is in this state 1 2 3 4 5 6 7 8 0
. I have tested some puzzles that where generated with Puzzle solver From the testing it seems a lot of the puzzle states are not solvable which shouldn't be the case. My method IsSolvable
seem flawed.