1
- using System . Text . RegularExpressions ;
2
- using static terminal_minesweeper . Program . Mine ;
1
+ using static terminal_minesweeper . Program . Mine ;
3
2
using static terminal_minesweeper . Program . MinesweeperGame . GridCell ;
4
3
5
4
namespace terminal_minesweeper {
@@ -8,7 +7,7 @@ static class Consts {
8
7
public const string CheatCode = "cheat" ;
9
8
}
10
9
const string Name = "terminal-minesweeper" ;
11
- const string Version = "v1.0.0 " ;
10
+ const string Version = "v1.0.1 " ;
12
11
static void Main ( string [ ] args ) {
13
12
Console . OutputEncoding = System . Text . Encoding . UTF8 ;
14
13
Console . Title = $ "{ Name } @{ Version } ";
@@ -49,10 +48,10 @@ public class MinesweeperGame {
49
48
private Coords CurPos {
50
49
get => _curPos ;
51
50
set {
52
- if ( value . Y >= GameGrid . GetLength ( 0 ) ) value . Y = 0 ;
53
- if ( value . Y < 0 ) value . Y = GameGrid . GetLength ( 0 ) - 1 ;
54
- if ( value . X >= GameGrid . GetLength ( 1 ) ) value . X = 0 ;
55
- if ( value . X < 0 ) value . X = GameGrid . GetLength ( 1 ) - 1 ;
51
+ if ( value . Y >= GridSize . Y ) value . Y = 0 ;
52
+ if ( value . Y < 0 ) value . Y = GridSize . Y - 1 ;
53
+ if ( value . X >= GridSize . X ) value . X = 0 ;
54
+ if ( value . X < 0 ) value . X = GridSize . X - 1 ;
56
55
_curPos = value ;
57
56
}
58
57
}
@@ -145,8 +144,8 @@ public bool Loop() {
145
144
}
146
145
147
146
private void RecalculateCellNumbers ( ) {
148
- for ( int y = 0 ; y < GameGrid . GetLength ( 0 ) ; y ++ ) {
149
- for ( int x = 0 ; x < GameGrid . GetLength ( 1 ) ; x ++ ) {
147
+ for ( int y = 0 ; y < GridSize . Y ; y ++ ) {
148
+ for ( int x = 0 ; x < GridSize . X ; x ++ ) {
150
149
if ( MineAt ( new ( x , y ) ) != null ) continue ;
151
150
var cellsAround = GetCellsAround ( new ( x , y ) ) ;
152
151
int mineCountAround = cellsAround . Where ( cell => MineAt ( cell ) != null ) . Count ( ) ;
@@ -160,19 +159,19 @@ private static bool EndScreenInput() {
160
159
const int enterPressCountToContinue = 3 ;
161
160
static void PrintKeyInfo ( int enterPressCount = enterPressCountToContinue ) {
162
161
PrintColoredStrings ( new ( ) {
163
- new ( "\n Press " ) ,
162
+ "\n Press " ,
164
163
new ( $ "{ ( enterPressCount == 0 ? "✓" : enterPressCount ) } ×ENTER", ConsoleColor . Blue ) ,
165
- new ( "/" ) ,
164
+ "/" ,
166
165
new ( "SPACE " , ConsoleColor . Blue ) ,
167
- new ( "to " ) ,
166
+ "to " ,
168
167
new ( "Play " , ConsoleColor . Blue ) ,
169
- new ( "again." ) ,
168
+ "again." ,
170
169
171
- new ( "\n Press " ) ,
170
+ "\n Press " ,
172
171
new ( "X " , ConsoleColor . Magenta ) ,
173
- new ( "to " ) ,
172
+ "to " ,
174
173
new ( "Exit" , ConsoleColor . Magenta ) ,
175
- new ( "." )
174
+ "."
176
175
} ) ;
177
176
}
178
177
int enterPressCount = 0 ;
@@ -322,10 +321,10 @@ private Coords GetRandomMineCoords() {
322
321
HashSet < Coords > allMineCoords = Mines . Select ( item => item . Coordinates ) . ToHashSet ( ) ;
323
322
int tries = 0 ;
324
323
Coords newMineCoords ;
325
- while ( tries < ( ( GameGrid . GetLength ( 0 ) + GameGrid . GetLength ( 1 ) ) * 3 ) ) {
324
+ while ( tries < ( ( GridSize . Y + GridSize . X ) * 3 ) ) {
326
325
newMineCoords = new (
327
- RandomGen . Next ( 0 , GameGrid . GetLength ( 1 ) ) ,
328
- RandomGen . Next ( 0 , GameGrid . GetLength ( 0 ) )
326
+ RandomGen . Next ( 0 , GridSize . X ) ,
327
+ RandomGen . Next ( 0 , GridSize . Y )
329
328
) ;
330
329
if ( ! allMineCoords . Contains ( newMineCoords ) ) return newMineCoords ;
331
330
tries ++ ;
@@ -408,12 +407,16 @@ private HashSet<Coords> GetCellsAround(Coords offset) {
408
407
409
408
private List < StringColorData > CreateGridString ( ) {
410
409
List < StringColorData > output = new ( ) ;
411
- for ( int y = 0 ; y < GameGrid . GetLength ( 0 ) ; y ++ ) {
412
- for ( int x = 0 ; x < GameGrid . GetLength ( 1 ) ; x ++ ) {
410
+ for ( int y = 0 ; y < GridSize . Y ; y ++ ) {
411
+ for ( int x = 0 ; x < GridSize . X ; x ++ ) {
413
412
GridCell gridItem = GameGrid [ y , x ] ;
414
- StringColorData stringColorData = new ( "" ) {
415
- Color = ConsoleColor . White
416
- } ;
413
+ StringColorData stringColorData = new ( "" , ConsoleColor . White ) ;
414
+
415
+ if ( y == 0 ) stringColorData . Data . CellTop = true ;
416
+ if ( x == 0 ) {
417
+ stringColorData . Data . CellLeft = true ;
418
+ stringColorData . Data . UniqueY = y ;
419
+ }
417
420
418
421
// show the mines if the game has ended
419
422
if ( ( MineAt ( new ( x , y ) ) != null ) && ( GameEnd || UncoveredCellsCoords . Contains ( new ( x , y ) ) || CheatMode ) ) {
@@ -458,56 +461,61 @@ private List<StringColorData> CreateGridString() {
458
461
459
462
const ConsoleColor currentPosColor = ConsoleColor . DarkCyan ;
460
463
461
- // add the horizontal border grid (A, B, C, ...)
464
+ // add the horizontal grid border (A, B, C, ...)
465
+ AddHorizontalBorder ( ref output , currentPosColor ) ;
466
+
467
+ // add the vertical grid border (1, 2, 3, ...)
468
+ AddVerticalBorder ( ref output , currentPosColor ) ;
469
+
470
+ if ( output . Last ( ) . String == "\n " ) output . RemoveAt ( output . Count - 1 ) ;
471
+ return output ;
472
+ }
473
+
474
+ private void AddHorizontalBorder ( ref List < StringColorData > output , ConsoleColor currentPosColor ) {
462
475
string loopingAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
463
476
int alphabetFullLoopCount = 0 ;
464
- int loopCount = GameGrid . GetLength ( 1 ) ;
465
- foreach ( int i in Enumerable . Range ( 0 , loopCount ) ) {
466
- output . Insert ( i ,
467
- new ( loopingAlphabet [ 0 ] . ToString ( ) + ( alphabetFullLoopCount == 0 ? " " : "'" ) ,
468
- i == CurPos . X ? currentPosColor : ConsoleColor . Gray )
469
- ) ;
470
- List < char > alphabetList = loopingAlphabet . ToList ( ) ;
471
- char temp = alphabetList [ 0 ] ;
472
- alphabetList . RemoveAt ( 0 ) ;
473
- alphabetList . Add ( temp ) ;
474
- loopingAlphabet = string . Join ( "" , alphabetList ) ;
475
- if ( i + 1 == loopCount ) {
476
- foreach ( int j in Enumerable . Range ( 0 , 2 ) ) {
477
- output . Insert ( i + 1 + j , new ( "\n " ) ) ;
478
- }
479
- }
477
+ List < StringColorData > topCells = output . Where ( item => item . Data . CellTop != null && ( bool ) item . Data . CellTop ) . ToList ( ) ;
478
+ int currentX = 0 ;
479
+ foreach ( var topCell in topCells ) {
480
+ StringColorData toAdd = new ( loopingAlphabet [ 0 ] + ( alphabetFullLoopCount == 0 ? " " : "'" ) ) {
481
+ Color = CurPos . X == currentX ? currentPosColor : ConsoleColor . Gray
482
+ } ;
480
483
484
+ output . Insert ( currentX , toAdd ) ;
485
+
486
+ loopingAlphabet = loopingAlphabet [ 1 ..] + loopingAlphabet [ 0 ] ;
481
487
if ( loopingAlphabet . StartsWith ( 'A' ) ) alphabetFullLoopCount ++ ;
488
+ currentX ++ ;
489
+ }
490
+ for ( int i = 0 ; i < 2 ; i ++ ) {
491
+ output . Insert ( topCells . Count + i , "\n " ) ;
482
492
}
493
+ }
483
494
484
- // add the vertical border grid (1, 2, 3, ...)
485
- int line = - 1 ;
495
+ private void AddVerticalBorder ( ref List < StringColorData > output , ConsoleColor currentPosColor ) {
496
+ int line = 0 ;
486
497
int numbersFullLoopCount = - 1 ;
487
- int realLineIndex = 0 ;
488
- for ( int i = 0 ; i < output . Count - 1 ; i ++ ) {
489
- int newLineCount = Regex . Matches ( output [ i ] . String , "\n " ) . Count ;
490
- realLineIndex += newLineCount ;
491
- if ( realLineIndex <= 1 || newLineCount == 0 ) { continue ; } else {
492
- line += newLineCount ;
493
- }
498
+ List < StringColorData > leftCells = output . Where ( item => item . Data . CellLeft != null && ( bool ) item . Data . CellLeft ) . ToList ( ) ;
499
+ foreach ( var leftCell in leftCells ) {
494
500
int displayNum = ( line % 9 ) + 1 ;
495
501
if ( displayNum == 1 ) numbersFullLoopCount ++ ;
496
- string spaceAfterNumber = " " ;
502
+ string spaceAfterNumber = "" ;
497
503
if ( numbersFullLoopCount == 1 ) spaceAfterNumber = "'" ;
498
504
if ( numbersFullLoopCount > 1 ) spaceAfterNumber = "\" " ;
499
505
if ( numbersFullLoopCount > 2 ) spaceAfterNumber = "\" '" ;
500
506
spaceAfterNumber += new string ( ' ' , 3 - spaceAfterNumber . Length ) ;
501
- output . Insert ( i + 1 ,
502
- new ( displayNum . ToString ( ) + spaceAfterNumber ,
503
- line == CurPos . Y ? currentPosColor : ConsoleColor . Gray )
504
- ) ;
505
- }
506
507
507
- output . Insert ( 0 , new ( " " ) ) ;
508
+ StringColorData toAdd = new ( displayNum + spaceAfterNumber ) {
509
+ Color = CurPos . Y == line ? currentPosColor : ConsoleColor . Gray
510
+ } ;
508
511
509
- if ( output . Last ( ) . String == "\n " ) output . RemoveAt ( output . Count - 1 ) ;
510
- return output ;
512
+ var leftCellIndex = output . IndexOf ( leftCell ) ;
513
+
514
+ output . Insert ( leftCellIndex , toAdd ) ;
515
+
516
+ line ++ ;
517
+ }
518
+ output . Insert ( 0 , " " ) ;
511
519
}
512
520
}
513
521
@@ -533,7 +541,6 @@ private static void PrintColoredStrings(List<StringColorData> colorStringData) {
533
541
Console . BackgroundColor = colorStringPair . BGColor ?? default ;
534
542
Console . Write ( colorStringPair . String ) ;
535
543
}
536
- //Console.ResetColor();
537
544
Console . ForegroundColor = ConsoleColor . White ;
538
545
Console . WriteLine ( ) ;
539
546
}
@@ -562,10 +569,23 @@ private class StringColorData {
562
569
public string String = "" ;
563
570
public ConsoleColor Color ;
564
571
public ConsoleColor ? BGColor = null ;
565
- public StringColorData ( string str , ConsoleColor color = ConsoleColor . White , ConsoleColor ? bgColor = null ) {
572
+ public AdditionalData Data = new ( ) ;
573
+
574
+ public StringColorData ( string str , ConsoleColor color = ConsoleColor . White , ConsoleColor ? bgColor = null , AdditionalData ? data = null ) {
566
575
String = str ;
567
576
Color = color ;
568
577
BGColor = bgColor ?? BGColor ;
578
+ Data = data ?? Data ;
579
+ }
580
+
581
+ public class AdditionalData {
582
+ public bool ? CellLeft ;
583
+ public bool ? CellTop ;
584
+ public int ? UniqueY ;
585
+ }
586
+
587
+ public static implicit operator StringColorData ( string str ) {
588
+ return new ( str ) ;
569
589
}
570
590
}
571
591
0 commit comments