diff --git a/CoopSweeper/ArrayHelpers.cs b/CoopSweeper/ArrayHelpers.cs new file mode 100644 index 0000000..caf436b --- /dev/null +++ b/CoopSweeper/ArrayHelpers.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CoopSweeper +{ + public static class ArrayHelpers + { + public static T[,] Clone2D(T[,] data) where T : ICloneable + { + if (data == null) + return null; + var newArray = new T[data.GetLength(0), data.GetLength(1)]; + for (var x = 0; x< data.GetLength(0); x++) + for (var y = 0; y < data.GetLength(1); y++) + newArray[x,y] = data[x,y].Clone(); + return newArray; + } + } +} diff --git a/CoopSweeper/GameTypes/Field.cs b/CoopSweeper/GameTypes/Field.cs index 1e83a60..8ef0468 100644 --- a/CoopSweeper/GameTypes/Field.cs +++ b/CoopSweeper/GameTypes/Field.cs @@ -21,20 +21,34 @@ namespace CoopSweeper.GameTypes public int CheckID { get; set; } - public DisplayState GetDisplayState() + public DisplayState DisplayState { - switch(State) + get { - case FieldState.QUESTIONMARK: - case FieldState.NONE: - case FieldState.FLAG: + switch (State) + { + case FieldState.QUESTIONMARK: + case FieldState.NONE: + case FieldState.FLAG: return (DisplayState)State; - case FieldState.REVEALED: - if(ContainsBomb) - return DisplayState.BOMB; - return (DisplayState)SurroundingBombs; + case FieldState.REVEALED: + if (ContainsBomb) + return DisplayState.BOMB; + return (DisplayState)SurroundingBombs; + } + return DisplayState.ERROR; } - return DisplayState.ERROR; + } + + public IField Clone() + { + return new Field() + { + State = State, + ContainsBomb = ContainsBomb, + SurroundingBombs = SurroundingBombs, + CheckID = CheckID + }; } } } diff --git a/CoopSweeper/GameTypes/IField.cs b/CoopSweeper/GameTypes/IField.cs index ece31e0..3048d47 100644 --- a/CoopSweeper/GameTypes/IField.cs +++ b/CoopSweeper/GameTypes/IField.cs @@ -30,7 +30,7 @@ namespace CoopSweeper.GameTypes FLAG = DisplayState.FLAG } - public interface IField + public interface IField : ICloneable { bool ContainsBomb { get; set; } @@ -41,6 +41,6 @@ namespace CoopSweeper.GameTypes FieldState State { get; set; } - DisplayState GetDisplayState(); + DisplayState DisplayState { get; } } } diff --git a/CoopSweeper/ICloneable.cs b/CoopSweeper/ICloneable.cs new file mode 100644 index 0000000..fbce50c --- /dev/null +++ b/CoopSweeper/ICloneable.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CoopSweeper +{ + public interface ICloneable where T : ICloneable + { + T Clone(); + } +} diff --git a/CoopSweeper/Program.cs b/CoopSweeper/Program.cs index 41b07f0..981f771 100644 --- a/CoopSweeper/Program.cs +++ b/CoopSweeper/Program.cs @@ -7,6 +7,7 @@ namespace CoopSweeper { class Program { + static IField[,] currentMap = null; const int MAP_POS_X = 3; const int MAP_POS_Y = 3; @@ -27,7 +28,7 @@ namespace CoopSweeper Console.Write("You won!"); else Console.Write("You lost!"); - DrawMap(MAP_POS_X, MAP_POS_Y, game.Map, cursorPosX, cursorPosY); + DrawMap(MAP_POS_X, MAP_POS_Y, game.Map, cursorPosX, cursorPosY, true); Console.ReadKey(); StartNewGame(game, cursorPosX, cursorPosY); }; @@ -59,7 +60,7 @@ namespace CoopSweeper if (cursorPosX >= game.Map.GetLength(0)) cursorPosX = game.Map.GetLength(0) - 1; if (cursorPosY >= game.Map.GetLength(1)) cursorPosY = game.Map.GetLength(1) - 1; if (fullRedraw) - DrawMap(3, 3, game.Map, cursorPosX, cursorPosY); + DrawMap(3, 3, game.Map, cursorPosX, cursorPosY, true); else if(oldCursorPosX != cursorPosX || oldCursorPosY != cursorPosY) { Console.SetCursorPosition(oldCursorPosX + 3, oldCursorPosY + 3); @@ -79,7 +80,7 @@ namespace CoopSweeper bool fgChanged = false; bool bgChanged = false; var c = 'E'; - var state = f.GetDisplayState(); + var state = f.DisplayState; switch (state) { case DisplayState.EMPTY: c = ' '; @@ -93,8 +94,10 @@ namespace CoopSweeper c = ' '; break; case DisplayState.QUESTIONMARK: + fgChanged = true; bgChanged = true; Console.BackgroundColor = ConsoleColor.Gray; + Console.ForegroundColor = ConsoleColor.DarkBlue; c = '?'; break; case DisplayState.BOMB: @@ -163,20 +166,33 @@ namespace CoopSweeper Console.Clear(); Console.SetCursorPosition(0, 0); DrawBorder(MAP_POS_X - 1, MAP_POS_X - 1, game.Map.GetLength(0) + 2, game.Map.GetLength(1) + 2); - DrawMap(MAP_POS_X, MAP_POS_Y, game.Map, cursorPosX, cursorPosY); + DrawMap(MAP_POS_X, MAP_POS_Y, game.Map, cursorPosX, cursorPosY, false); } - private static void DrawMap(int posX, int posY, IField[,] map, int cursorX, int cursorY) + private static void DrawMap(int posX, int posY, IField[,] map, int cursorX, int cursorY, bool doChangeDetection) { - var res = new string[map.GetLength(1)]; for (var y = 0; y < map.GetLength(1); y++) { - Console.SetCursorPosition(posX, posY + y); + if(currentMap == null || !doChangeDetection) Console.SetCursorPosition(posX, posY + y); for (var x = 0; x < map.GetLength(0); x++) { - DrawChar(map[x, y], x == cursorX && y == cursorY); + if (currentMap != null && doChangeDetection) + { + var currentField = currentMap[x, y]; + var newField = map[x, y]; + if (currentField == null || currentField.DisplayState != newField.DisplayState) + { + Console.SetCursorPosition(posX + x, posY + y); + DrawChar(map[x, y], x == cursorX && y == cursorY); + } + } + else + { + DrawChar(map[x, y], x == cursorX && y == cursorY); + } } } + currentMap = ArrayHelpers.Clone2D(map); } private static void DrawBorder(int posX, int posY, int width, int height)