connect4

Connect 4 Board Game
Log | Files | Refs

commit 4527dd1499f5e38288558417a817418cdd5dad94
parent f0be7b5d1b4c30b1bc24a93be29a722af1334617
Author: sej <sej@sejdt.localhost>
Date:   Thu, 17 Oct 2024 14:17:21 +0200

Restructured determining the win condition

Diffstat:
MBoard.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; } }