-
-
Save daleth90/03dafe3b943ed48f9ceca5e6fb2e33e9 to your computer and use it in GitHub Desktop.
almost final version
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using Zenject; | |
public class OthelloGame : IInitializable { | |
private static readonly Vector2Int[] checkDirections = new Vector2Int[] { | |
new Vector2Int( -1, 0 ), new Vector2Int( 1, 0 ), | |
new Vector2Int( 0, -1 ), new Vector2Int( 0, 1 ), | |
new Vector2Int( -1, -1 ), new Vector2Int( 1, 1 ), | |
new Vector2Int( -1, 1 ), new Vector2Int( 1, -1 ) | |
}; | |
public event Action<int, int> OnUpdateScore = delegate { }; | |
public event Action<Disk> OnGameEnd = delegate { }; | |
private readonly OthelloBoardModel othelloBoard; | |
private int numberOfDarkDisk; | |
private int numberOfLightDisk; | |
public OthelloGame( OthelloBoardModel othelloBoard ) { | |
this.othelloBoard = othelloBoard; | |
} | |
public void Initialize() { | |
StartNewGame(); | |
} | |
public void StartNewGame() { | |
othelloBoard.SetSide( Disk.DARK ); | |
othelloBoard.PlaceDisk( 4, 5 ); | |
othelloBoard.PlaceDisk( 5, 4 ); | |
othelloBoard.SetSide( Disk.LIGHT ); | |
othelloBoard.PlaceDisk( 4, 4 ); | |
othelloBoard.PlaceDisk( 5, 5 ); | |
othelloBoard.SetSide( Disk.DARK ); | |
UpdateScoreBoard(); | |
othelloBoard.OnRequestDisk += ValidatePlacement; | |
} | |
public bool IsValidPlace( int x, int y, Disk disk ) { | |
if ( othelloBoard.GetDisk( x, y ) != Disk.NONE ) { | |
return false; | |
} | |
Disk oppositeSide = GetOpponentSide( disk ); | |
for ( int d = 0; d < checkDirections.Length; d++ ) { | |
if ( othelloBoard.GetDisk( x + checkDirections[ d ].x, y + checkDirections[ d ].y ) != oppositeSide ) { | |
continue; | |
} | |
for ( int i = x + checkDirections[ d ].x * 2, j = y + checkDirections[ d ].y * 2; i >= 1 && j >= 1 && i <= 8 && j <= 8; | |
i += checkDirections[ d ].x, j += checkDirections[ d ].y ) { | |
if ( othelloBoard.GetDisk( i, j ) == disk ) { | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
private void ValidatePlacement( int x, int y, Disk disk ) { | |
Disk oppositeSide = GetOpponentSide( disk ); | |
List<Vector2Int> flipPositions = new List<Vector2Int>(); | |
for ( int d = 0; d < checkDirections.Length; d++ ) { | |
bool isValidDirection = false; | |
for ( int i = x + checkDirections[ d ].x, j = y + checkDirections[ d ].y; i >= 1 && j >= 1 && i <= 8 && j <= 8; | |
i += checkDirections[ d ].x, j += checkDirections[ d ].y ) { | |
if ( othelloBoard.GetDisk( i, j ) == disk ) { | |
isValidDirection = true; | |
} | |
} | |
if ( isValidDirection == false ) { | |
continue; | |
} | |
for ( int i = x + checkDirections[ d ].x, j = y + checkDirections[ d ].y; i >= 1 && j >= 1 && i <= 8 && j <= 8; | |
i += checkDirections[ d ].x, j += checkDirections[ d ].y ) { | |
if ( othelloBoard.GetDisk( i, j ) == oppositeSide ) { | |
flipPositions.Add( new Vector2Int( i, j ) ); | |
} | |
else { | |
break; | |
} | |
} | |
} | |
if ( flipPositions.Count > 0 ) { | |
othelloBoard.PlaceDisk( x, y ); | |
for ( int i = 0; i < flipPositions.Count; i++ ) { | |
othelloBoard.FlipDisk( flipPositions[ i ].x, flipPositions[ i ].y ); | |
} | |
UpdateScoreBoard(); | |
CheckEndOfGameOrSwitchSide( disk ); | |
} | |
} | |
private void UpdateScoreBoard() { | |
numberOfDarkDisk = GetNumberOfDisk( Disk.DARK ); | |
numberOfLightDisk = GetNumberOfDisk( Disk.LIGHT ); | |
OnUpdateScore.Invoke( numberOfDarkDisk, numberOfLightDisk ); | |
} | |
private int GetNumberOfDisk( Disk disk ) { | |
int number = 0; | |
for ( int i = 1; i <= 8; i++ ) { | |
for ( int j = 1; j <= 8; j++ ) { | |
if ( othelloBoard.GetDisk( i, j ) == disk ) { | |
++number; | |
} | |
} | |
} | |
return number; | |
} | |
private void CheckEndOfGameOrSwitchSide( Disk lastSide ) { | |
Disk oppositeSide = GetOpponentSide( lastSide ); | |
if ( IsAvailableToPlace( oppositeSide ) ) { | |
othelloBoard.SetSide( oppositeSide ); | |
} | |
else if ( IsAvailableToPlace( lastSide ) ) { | |
// The original side keeps going. Intentionally write this comment for readability | |
} | |
else { | |
if ( numberOfDarkDisk > numberOfLightDisk ) { | |
OnGameEnd.Invoke( Disk.DARK ); | |
} | |
else if ( numberOfLightDisk > numberOfDarkDisk ) { | |
OnGameEnd.Invoke( Disk.LIGHT ); | |
} | |
else { // Draw | |
OnGameEnd.Invoke( Disk.NONE ); | |
} | |
} | |
} | |
private bool IsAvailableToPlace( Disk disk ) { | |
for ( int i = 1; i <= 8; i++ ) { | |
for ( int j = 1; j <= 8; j++ ) { | |
if ( IsValidPlace( i, j, disk ) ) { | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
private Disk GetOpponentSide( Disk disk ) { | |
if ( disk == Disk.DARK ) { | |
return Disk.LIGHT; | |
} | |
else if ( disk == Disk.LIGHT ) { | |
return Disk.DARK; | |
} | |
else { | |
throw new ArgumentException( "\"None\" disk is impossible in the game" ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment