commit 4527dd1499f5e38288558417a817418cdd5dad94
parent f0be7b5d1b4c30b1bc24a93be29a722af1334617
Author: sej <sej@sejdt.localhost>
Date: Thu, 17 Oct 2024 14:17:21 +0200
Restructured determining the win condition
Diffstat:
| M | Board.cs | | | 113 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
1 file changed, 66 insertions(+), 47 deletions(-)
diff --git a/Board.cs b/Board.cs
@@ -14,6 +14,7 @@ public class Board {
Free = 0, // make sure free is the default value
PlayerX,
PlayerO,
+ None,
}
public enum Status {
@@ -74,11 +75,18 @@ public class Board {
/*
* returns whos turn it is
*/
- public Cell getNext() {
+ public Cell GetNext() {
return _next;
}
/*
+ * returns who just played
+ */
+ public Cell GetPrevious() {
+ return _next == Cell.PlayerX ? Cell.PlayerO : Cell.PlayerX;
+ }
+
+ /*
* Pretty prints the board
*/
public void PrettyPrint() {
@@ -107,61 +115,72 @@ public class Board {
return legalMoves;
}
+ public Status GetStatus() {
+ return _status;
+ }
+
+ public int GetHeight() {
+ return _m;
+ }
+
+ public int GetWidth() {
+ return _n;
+ }
+
+ /*
+ * Indexer to grant read-only access to the board
+ */
+ public Cell this[ int j, int i ] {
+ get {
+ if ( 0 <= j && j < _m && 0 <= i && i < _n ) {
+ return _board[ j, i ];
+ } else {
+ return Cell.None;
+ }
+ }
+ }
+
+
/*
* Computes the status of this board, ie. has someone won by obtaining four in a row.
*/
public Status ComputeStatus() {
- foreach ( Cell player in new Cell[] { Cell.PlayerX, Cell.PlayerO } ) {
- // Check for vertical four in a row
- ComputeStatus(
- ( j, i, k ) => _board[ j + k, i ],
- j => j < _m - 3,
- _ => true,
- player
- );
- // Check for horizontal four in a row
- ComputeStatus(
- ( j, i, k ) => _board[ j, i + k ],
- _ => true,
- i => i < _n - 3,
- player
- );
- // Check for diagonal four in a row
- ComputeStatus(
- ( j, i, k ) => _board[ j + k, i + k ],
- j => j < _m - 3,
- i => i < _n - 3,
- player
- );
- // Check for alternate diagonal four in a row
- ComputeStatus(
- ( j, i, k ) => _board[ j - k, i + k ],
- j => j > 3,
- i => i < _n - 3,
- player
- );
+ int FourInARow = NumberQInRow( 4, GetPrevious() );
+
+ if ( FourInARow > 0 ) {
+ _status = _next == Cell.PlayerO ? Status.PlayerXWon : Status.PlayerOWon;
}
return _status;
}
/*
- * Helper method
+ * Returns the number of q in a row for player.
+ * Note: this also counts instance of more than q in a row.
*/
- private void ComputeStatus( Func< int, int, int, Cell > f, Predicate< int > YOkay, Predicate< int > XOkay, Cell player ) {
- int j = 0;
- while ( _status == Status.InProgress && j < _m ) {
- int i = 0;
- while ( _status == Status.InProgress && i < _n ) {
- int k = 0;
- while ( XOkay( i ) && YOkay( j ) && k < 4 && f( j, i, k ) == player ) {
- k ++;
- }
- if ( k == 4 ) {
- _status = player == Cell.PlayerX ? Status.PlayerXWon : Status.PlayerOWon;
- }
- i ++;
- }
- j ++;
- }
+ public int NumberQInRow( int q, Cell player ) {
+ var rows = Enumerable.Range( 0, _m );
+ var columns = Enumerable.Range( 0, _n );
+
+ var indices = new Func< int, int, int, ( int, int ) >[] {
+ ( j, i, k ) => ( j + k, i ),
+ ( j, i, k ) => ( j, i + k ),
+ ( j, i, k ) => ( j + k, i + k ),
+ ( j, i, k ) => ( j - k, i + k ),
+ };
+
+ int count =
+ ( from index in indices
+ from j in rows
+ from i in columns
+ select Enumerable.All(
+ Enumerable.Range( 0, q ),
+ k => {
+ var ( jj, ii ) = index( j, i, k );
+ return this[ jj, ii ] == player;
+ }
+ )
+ ).Where( b => b )
+ .Count();
+ return count;
}
}