Implement Change Detection Drawing
This commit is contained in:
20
CoopSweeper/ArrayHelpers.cs
Normal file
20
CoopSweeper/ArrayHelpers.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CoopSweeper
|
||||||
|
{
|
||||||
|
public static class ArrayHelpers
|
||||||
|
{
|
||||||
|
public static T[,] Clone2D<T>(T[,] data) where T : ICloneable<T>
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,20 +21,34 @@ namespace CoopSweeper.GameTypes
|
|||||||
|
|
||||||
public int CheckID { get; set; }
|
public int CheckID { get; set; }
|
||||||
|
|
||||||
public DisplayState GetDisplayState()
|
public DisplayState DisplayState
|
||||||
{
|
{
|
||||||
switch(State)
|
get
|
||||||
{
|
{
|
||||||
case FieldState.QUESTIONMARK:
|
switch (State)
|
||||||
case FieldState.NONE:
|
{
|
||||||
case FieldState.FLAG:
|
case FieldState.QUESTIONMARK:
|
||||||
|
case FieldState.NONE:
|
||||||
|
case FieldState.FLAG:
|
||||||
return (DisplayState)State;
|
return (DisplayState)State;
|
||||||
case FieldState.REVEALED:
|
case FieldState.REVEALED:
|
||||||
if(ContainsBomb)
|
if (ContainsBomb)
|
||||||
return DisplayState.BOMB;
|
return DisplayState.BOMB;
|
||||||
return (DisplayState)SurroundingBombs;
|
return (DisplayState)SurroundingBombs;
|
||||||
|
}
|
||||||
|
return DisplayState.ERROR;
|
||||||
}
|
}
|
||||||
return DisplayState.ERROR;
|
}
|
||||||
|
|
||||||
|
public IField Clone()
|
||||||
|
{
|
||||||
|
return new Field()
|
||||||
|
{
|
||||||
|
State = State,
|
||||||
|
ContainsBomb = ContainsBomb,
|
||||||
|
SurroundingBombs = SurroundingBombs,
|
||||||
|
CheckID = CheckID
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace CoopSweeper.GameTypes
|
|||||||
FLAG = DisplayState.FLAG
|
FLAG = DisplayState.FLAG
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IField
|
public interface IField : ICloneable<IField>
|
||||||
{
|
{
|
||||||
|
|
||||||
bool ContainsBomb { get; set; }
|
bool ContainsBomb { get; set; }
|
||||||
@@ -41,6 +41,6 @@ namespace CoopSweeper.GameTypes
|
|||||||
|
|
||||||
FieldState State { get; set; }
|
FieldState State { get; set; }
|
||||||
|
|
||||||
DisplayState GetDisplayState();
|
DisplayState DisplayState { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
CoopSweeper/ICloneable.cs
Normal file
11
CoopSweeper/ICloneable.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CoopSweeper
|
||||||
|
{
|
||||||
|
public interface ICloneable<T> where T : ICloneable<T>
|
||||||
|
{
|
||||||
|
T Clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ namespace CoopSweeper
|
|||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
|
static IField[,] currentMap = null;
|
||||||
const int MAP_POS_X = 3;
|
const int MAP_POS_X = 3;
|
||||||
const int MAP_POS_Y = 3;
|
const int MAP_POS_Y = 3;
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ namespace CoopSweeper
|
|||||||
Console.Write("You won!");
|
Console.Write("You won!");
|
||||||
else
|
else
|
||||||
Console.Write("You lost!");
|
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();
|
Console.ReadKey();
|
||||||
StartNewGame(game, cursorPosX, cursorPosY);
|
StartNewGame(game, cursorPosX, cursorPosY);
|
||||||
};
|
};
|
||||||
@@ -59,7 +60,7 @@ namespace CoopSweeper
|
|||||||
if (cursorPosX >= game.Map.GetLength(0)) cursorPosX = game.Map.GetLength(0) - 1;
|
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 (cursorPosY >= game.Map.GetLength(1)) cursorPosY = game.Map.GetLength(1) - 1;
|
||||||
if (fullRedraw)
|
if (fullRedraw)
|
||||||
DrawMap(3, 3, game.Map, cursorPosX, cursorPosY);
|
DrawMap(3, 3, game.Map, cursorPosX, cursorPosY, true);
|
||||||
else if(oldCursorPosX != cursorPosX || oldCursorPosY != cursorPosY)
|
else if(oldCursorPosX != cursorPosX || oldCursorPosY != cursorPosY)
|
||||||
{
|
{
|
||||||
Console.SetCursorPosition(oldCursorPosX + 3, oldCursorPosY + 3);
|
Console.SetCursorPosition(oldCursorPosX + 3, oldCursorPosY + 3);
|
||||||
@@ -79,7 +80,7 @@ namespace CoopSweeper
|
|||||||
bool fgChanged = false;
|
bool fgChanged = false;
|
||||||
bool bgChanged = false;
|
bool bgChanged = false;
|
||||||
var c = 'E';
|
var c = 'E';
|
||||||
var state = f.GetDisplayState();
|
var state = f.DisplayState;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case DisplayState.EMPTY:
|
case DisplayState.EMPTY:
|
||||||
c = ' ';
|
c = ' ';
|
||||||
@@ -93,8 +94,10 @@ namespace CoopSweeper
|
|||||||
c = ' ';
|
c = ' ';
|
||||||
break;
|
break;
|
||||||
case DisplayState.QUESTIONMARK:
|
case DisplayState.QUESTIONMARK:
|
||||||
|
fgChanged = true;
|
||||||
bgChanged = true;
|
bgChanged = true;
|
||||||
Console.BackgroundColor = ConsoleColor.Gray;
|
Console.BackgroundColor = ConsoleColor.Gray;
|
||||||
|
Console.ForegroundColor = ConsoleColor.DarkBlue;
|
||||||
c = '?';
|
c = '?';
|
||||||
break;
|
break;
|
||||||
case DisplayState.BOMB:
|
case DisplayState.BOMB:
|
||||||
@@ -163,20 +166,33 @@ namespace CoopSweeper
|
|||||||
Console.Clear();
|
Console.Clear();
|
||||||
Console.SetCursorPosition(0, 0);
|
Console.SetCursorPosition(0, 0);
|
||||||
DrawBorder(MAP_POS_X - 1, MAP_POS_X - 1, game.Map.GetLength(0) + 2, game.Map.GetLength(1) + 2);
|
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++)
|
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++)
|
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)
|
private static void DrawBorder(int posX, int posY, int width, int height)
|
||||||
|
|||||||
Reference in New Issue
Block a user