public static bool CanMakeMove(OthelloPiece[,] bricks, Othello.PlayerColor currentPlayer) { int i = 0; foreach (OthelloPiece brick in bricks) { i++; if (brick.brickColor == BrickColor.Black || brick.brickColor == BrickColor.White) { continue; } foreach (Direction direction in Enum.GetValues(typeof(Direction))) { OthelloPiece nextBrick = NextBrickInDirection(brick.x, brick.y, direction, bricks); if (nextBrick != null) { if (ValidateLine(nextBrick.x, nextBrick.y, direction, 1, bricks, currentPlayer)) { return true; } } } } return false; }
//Highly value taking corner fields static List<OthelloPiece> GetValidCorners(OthelloPiece[,] bricks) { List<OthelloPiece> validCorners = new List<OthelloPiece>(); var validMoves = OthelloRules.GetAllValidMoves(bricks, Othello.CURRENT_PLAYER); if (validMoves.Count < 1) return null; foreach (OthelloPiece piece in validMoves) { if (piece.x == 0) { if (piece.y == 0 || piece.y == GameBoard.BoardWidth - 1) { validCorners.Add(piece); } } else if (piece.x == GameBoard.BoardWidth - 1) { if (piece.y == 0 || piece.y == GameBoard.BoardWidth - 1) { validCorners.Add(piece); } } } return validCorners; }
public OthelloPiece[,] SetupBoard(OthelloPiece[,] bricks) { CheckArrows(Othello.CURRENT_PLAYER); bricks = new OthelloPiece[8, 8]; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { GameObject piece = (GameObject)Instantiate(brick, new Vector3(x, y, -0.4f), Quaternion.identity); piece.transform.parent = transform; OthelloPiece othello = piece.GetComponentInChildren<OthelloPiece>(); othello.brickColor = BrickColor.Empty; othello.x = x; othello.y = y; bricks[x, y] = othello; } } bricks[3, 4].brickColor = BrickColor.White; bricks[4, 3].brickColor = BrickColor.White; bricks[3, 3].brickColor = BrickColor.Black; bricks[4, 4].brickColor = BrickColor.Black; UpdateBoard(bricks); return bricks; }
private static OthelloPiece GetRandomMove(OthelloPiece[,] bricks) { var validMoves = OthelloRules.GetAllValidMoves(bricks, Othello.CURRENT_PLAYER); if (validMoves.Count > 0) { int index = UnityEngine.Random.Range(0, validMoves.Count - 1); return validMoves[index] as OthelloPiece; } return null; }
public static OthelloPiece[,] ToOthelloPieceArray(this byte[] byteArray, OthelloPiece[,] bricks) { int length = (int)Mathf.Sqrt(byteArray.Length); var index = 0; for (int y = 0; y < length; y++) { for (int x = 0; x < length; x++) { bricks[x, y].brickColor = (BrickColor)byteArray[index]; index++; } } return bricks; }
public static void FlashRow(OthelloPiece brick, Direction direction, OthelloPiece[,] bricks, Othello.PlayerColor currentPlayer) { int X = brick.x; int Y = brick.y; if ((currentPlayer == Othello.PlayerColor.White && bricks[X, Y].brickColor == BrickColor.Black) || (currentPlayer == Othello.PlayerColor.Black && bricks[X, Y].brickColor == BrickColor.White)) { Flash(brick); brick = NextBrickInDirection(X, Y, direction, bricks); FlashRow(brick, direction, bricks, currentPlayer); } else { return; } }
public static ArrayList GetAllValidMoves(OthelloPiece[,] bricks, Othello.PlayerColor currentPlayer) { ArrayList validMoves = new ArrayList(); ArrayList validDirections; foreach (OthelloPiece brick in bricks) { if (brick.brickColor == BrickColor.Empty || brick.brickColor == BrickColor.Hint) { validDirections = GetValidDirections(bricks, brick, currentPlayer); if (validDirections.Count > 0) { validMoves.Add(brick); } } } return validMoves; }
// Start is called before the first frame update void Start() { for (int i = 0; i < Field_Size_X; i++) { for (int j = 0; j < Field_Size_Y; j++) { GameObject NewObject = GameObject.Instantiate <GameObject>(_PiecePrefab); OthelloPiece NewPiece = NewObject.GetComponent <OthelloPiece>(); NewObject.transform.localPosition = new Vector3(i - 3.5f, 0.0f, j - 3.5f); _FieldObject[i, j] = NewObject; _Piece[i, j] = NewPiece; _FieldPieceState[i, j] = ePieceState.None; } _FieldPieceState[3, 3] = ePieceState.Back; _FieldPieceState[4, 3] = ePieceState.Front; _FieldPieceState[3, 4] = ePieceState.Front; _FieldPieceState[4, 4] = ePieceState.Back; } _BoardObject = GameObject.Instantiate <GameObject>(_BoardPrefab); _CursorObject = GameObject.Instantiate <GameObject>(_CursorPrefab); _BackObject = GameObject.Instantiate <GameObject>(_BackPrefab); // ラインの生成 for (int i = 0; i <= 8; i++) { GameObject temp = GameObject.Instantiate <GameObject>(_XlinePrefab); LineRenderer XLine = temp.GetComponent <LineRenderer>(); XLine.SetPosition(0, new Vector3(-4.0f, 0.55f, i - 4.0f)); XLine.SetPosition(1, new Vector3(4.0f, 0.55f, i - 4.0f)); } for (int j = 0; j <= 8; j++) { GameObject temp = GameObject.Instantiate <GameObject>(_YlinePrefab); LineRenderer YLine = temp.GetComponent <LineRenderer>(); YLine.SetPosition(0, new Vector3(j - 4.0f, 0.51f, 4.0f)); YLine.SetPosition(1, new Vector3(j - 4.0f, 0.51f, -4.0f)); } _Turn.text = BlackTurn; }
public static OthelloPiece GetMove(OthelloPiece[,] bricks, OthelloManager.ComputerLevelEnum computerLevel) { ArrayList possibleMovesTemp = OthelloRules.GetAllValidMoves(bricks, Othello.CURRENT_PLAYER); var possibleMoves = new List<OthelloPiece>(); foreach (OthelloPiece temp in possibleMovesTemp) { possibleMoves.Add(temp); } if (possibleMoves.Count < 1) return null; switch (computerLevel) { case OthelloManager.ComputerLevelEnum.One: return LevelOneMove(bricks, possibleMoves); case OthelloManager.ComputerLevelEnum.Two: return LevelTwoMove(bricks, possibleMoves); case OthelloManager.ComputerLevelEnum.Three: return LevelThreeMove(bricks, possibleMoves); case OthelloManager.ComputerLevelEnum.Four: return LevelFourMove(bricks, possibleMoves); case OthelloManager.ComputerLevelEnum.Five: return LevelFiveMove(bricks, possibleMoves); } return null; }
static bool IsEmpty(OthelloPiece brick) { if (brick.brickColor == BrickColor.Empty || brick.brickColor == BrickColor.Hint) { return true; } return false; }
static bool IsColored(OthelloPiece brick) { if (brick.brickColor == BrickColor.Black || brick.brickColor == BrickColor.White) { return true; } return false; }
static void Flash(OthelloPiece brick) { brick.ShouldFlash = true; }
private static bool isNearLeftDownCorner(OthelloPiece brick) { return ( brick.x == 1 && brick.y == 0 || brick.x == 1 && brick.y == 1 || brick.x == 0 && brick.y == 1 ); }
public void UpdateBoard(OthelloPiece[,] bricks) { int blacks = 0; int whites = 0; foreach (OthelloPiece i in bricks) { if (i.brickColor == BrickColor.Black) { blacks++; } else if (i.brickColor == BrickColor.White) { whites++; } } UpdateLabels(blacks, whites); }
private static OthelloPiece LevelFourMove(OthelloPiece[,] bricks, List<OthelloPiece> possibleMoves) { Debug.Log("Computer Level 4 Move"); var corner = GetRandomValidCorner(bricks); if (corner != null) return corner; //possibleMoves = RemoveFieldsNextToCorners(possibleMoves); //OthelloPiece bestChoice = GetMoveWithLeastOpponentMoves(bricks, possibleMoves); var computerColor = OthelloManager.Instance.PlayerColor == Othello.PlayerColor.White ? Othello.PlayerColor.Black : Othello.PlayerColor.White; return OthelloRulesTestGround.GetMoveWithLeastOpponentMoves(bricks, possibleMoves, computerColor); }
private static OthelloPiece LevelThreeMove(OthelloPiece[,] bricks, List<OthelloPiece> possibleMoves) { Debug.Log("Computer Level 3 Move"); var corner = GetRandomValidCorner(bricks); if (corner != null) return corner; //Highly penalize taking the fields next to the corners possibleMoves = RemoveFieldsNextToCorners(possibleMoves); return possibleMoves.Count > 0 ? GetRandomMove(possibleMoves) : GetRandomMove(bricks); }
private static OthelloPiece LevelFiveMove(OthelloPiece[,] bricks, List<OthelloPiece> possibleMoves) { throw new NotImplementedException(); }
public void BroadcastMyTurn(OthelloPiece[,] bricks, Othello.PlayerColor currentPlayerColor) { _othelloPacket = bricks.ToByteArray(); BroadcastMyTime(); PlayGamesPlatform.Instance.RealTime.SendMessageToAll(true, _othelloPacket); }
private static OthelloPiece LevelTwoMove(OthelloPiece[,] bricks, List<OthelloPiece> possibleMoves) { Debug.Log("Computer Level 2 Move"); var corner = GetRandomValidCorner(bricks); if (corner != null) return corner; return GetRandomMove(bricks); }
public static OthelloPiece GetMoveWithLeastOpponentMoves(OthelloPiece[,] bricks, List<OthelloPiece> possibleMoves, Othello.PlayerColor currentColor) { var chosenBrick = new Brick(new Position(0, 0), BrickColor.Empty); var opponentColor = currentColor == Othello.PlayerColor.Black ? Othello.PlayerColor.White : Othello.PlayerColor.Black; var reservIndexex = new List<int>(); var bestNumberOfOpponentReserveMoves = int.MaxValue; var chosenIndexex = new List<int>(); var index = 0; int bestNumberOfOppenentMoves = int.MaxValue; foreach (var brick in possibleMoves) { var board = MakeCopyOfBricks(bricks); Brick tempBrick = board[brick.x, brick.y]; MakeMove(ref board, tempBrick, currentColor); List<Brick> allValidMoves = GetAllValidMoves(board, opponentColor); bool opponentCanTakeCorner = false; opponentCanTakeCorner = CheckIfOpponentCanTakeACorner(allValidMoves); if (opponentCanTakeCorner) { int numberOfReservMoves = allValidMoves.Count; if (numberOfReservMoves == bestNumberOfOpponentReserveMoves) { reservIndexex.Add(index); } else if (numberOfReservMoves < bestNumberOfOpponentReserveMoves) { bestNumberOfOpponentReserveMoves = numberOfReservMoves; reservIndexex.Clear(); reservIndexex.Add(index); } index++; Debug.Log("If I take " + brick.x + " , " + brick.y + " you will have " + numberOfReservMoves + " number of possible moves. But you can take the corner"); continue; } int numberOfOpponentMoves = allValidMoves.Count; Debug.Log("If I take " + brick.x + " , " + brick.y + " you will have " + numberOfOpponentMoves + " number of possible moves."); if (numberOfOpponentMoves == bestNumberOfOppenentMoves) { chosenIndexex.Add(index); } else if (numberOfOpponentMoves < bestNumberOfOppenentMoves) { bestNumberOfOppenentMoves = numberOfOpponentMoves; chosenIndexex.Clear(); chosenIndexex.Add(index); } index++; } Debug.Log("I got " + chosenIndexex.Count + " best moves to choose from."); int chosenIndex = 0; if (chosenIndexex.Count > 0) { chosenIndex = chosenIndexex[UnityEngine.Random.Range(0, chosenIndexex.Count - 1)]; Debug.Log("Sorry, but I chose " + possibleMoves[chosenIndex].x + " , " + possibleMoves[chosenIndex].y + " for you to only have " + bestNumberOfOppenentMoves + " moves next turn"); } else { chosenIndex = reservIndexex[UnityEngine.Random.Range(0, reservIndexex.Count - 1)]; Debug.Log("Sorry, but I chose " + possibleMoves[chosenIndex].x + " , " + possibleMoves[chosenIndex].y + " for you to only have " + bestNumberOfOppenentMoves + " moves next turn. But you can take the corner...."); } return possibleMoves[chosenIndex]; }
private static Brick[,] MakeCopyOfBricks(OthelloPiece[,] bricks) { var bricksWidth = bricks.GetLength(0); var bricksHeight = bricks.GetLength(1); Brick[,] board = new Brick[bricksWidth, bricksHeight]; for (int y = 0; y < bricksHeight; y++) { for (int x = 0; x < bricksWidth; x++) { var brick = bricks[x, y]; board[x, y] = new Brick(new Position(brick.x, brick.y), brick.brickColor); } } return board; }
private static bool isNearLeftUpCorner(OthelloPiece brick) { return ( brick.x == 0 && brick.y == GameBoard.BoardWidth - 2 || brick.x == 1 && brick.y == GameBoard.BoardWidth - 2 || brick.x == 1 && brick.y == GameBoard.BoardWidth - 1 ); }
static void Turn(OthelloPiece brick) { if (brick.brickColor == BrickColor.White) { brick.brickColor = BrickColor.Black; } else if (brick.brickColor == BrickColor.Black) { brick.brickColor = BrickColor.White; } }
static bool ValidateLine(int X, int Y, Direction direction, int step, OthelloPiece[,] bricks, Othello.PlayerColor currentPlayer) { //Here we want to get a complete Othello Line. Where int max = (int)Mathf.Sqrt(bricks.Length); max--; //if outside the board return false if (X < 0 || X > max || Y < 0 || Y > max) { // print (direction + " Next brick is OUTSIDE!"); return false; } //if empty return false else if (IsEmpty(bricks[X, Y])) { //print (direction + " Next brick is EMPTY!"); return false; } //if has stepped over atleast 1 of opponents bricks and now finds your own color. Returns true and validates the move as a valid move. else if (step > 1 && ((currentPlayer == Othello.PlayerColor.Black && bricks[X, Y].brickColor == BrickColor.Black) || (currentPlayer == Othello.PlayerColor.White && bricks[X, Y].brickColor == BrickColor.White))) { // print (direction + " Next brick makes the line VALID!"); return true; } //if first checked brick is the same color return false else if (step == 1 && ((currentPlayer == Othello.PlayerColor.Black && bricks[X, Y].brickColor == BrickColor.Black) || (currentPlayer == Othello.PlayerColor.White && bricks[X, Y].brickColor == BrickColor.White))) { // print (direction + " Next brick on the first step is the same color!"); return false; } else { // print (direction + " CONTINUING for next Validation"); OthelloPiece brick = NextBrickInDirection(X, Y, direction, bricks); if (brick != null) { step += 1; return ValidateLine(brick.x, brick.y, direction, step, bricks, currentPlayer); } else { // print (direction + " Reached the end, not a valid direction"); return false; } } }
public static bool HasWinner(OthelloPiece[,] bricks) { int bricksLeft = 0; foreach (OthelloPiece brick in bricks) { if (brick.brickColor == BrickColor.Empty || brick.brickColor == BrickColor.Hint) { bricksLeft++; } } bool hasWinner = false; hasWinner = bricksLeft == 0 ? true : false; return hasWinner; }
private static OthelloPiece LevelOneMove(OthelloPiece[,] bricks, List<OthelloPiece> possibleMoves) { Debug.Log("Computer Level 1 Move"); return GetRandomMove(bricks); }
public static OthelloPiece NextBrickInDirection(int X, int row, Direction dir, OthelloPiece[,] bricks) { int Y = row; int max = (int)Mathf.Sqrt(bricks.Length); max--; if ((dir == Direction.NW) && X > 0 && Y < max && !IsEmpty(bricks[X - 1, Y + 1])) { //Found something in NW return bricks[X - 1, Y + 1]; } else if ((dir == Direction.N) && Y < max && !IsEmpty(bricks[X, Y + 1])) { //Found something in N return bricks[X, Y + 1]; } else if ((dir == Direction.NE) && X < max && Y < max && !IsEmpty(bricks[X + 1, Y + 1])) { //Found something in NE return bricks[X + 1, Y + 1]; } else if ((dir == Direction.W) && X > 0 && !IsEmpty(bricks[X - 1, Y])) { //Found something in W return bricks[X - 1, Y]; } else if ((dir == Direction.E) && X < max && !IsEmpty(bricks[X + 1, Y])) { //Found something in E return bricks[X + 1, Y]; } else if ((dir == Direction.SW) && X > 0 && Y > 0 && !IsEmpty(bricks[X - 1, Y - 1])) { //Found something in SW return bricks[X - 1, Y - 1]; } else if ((dir == Direction.S) && Y > 0 && !IsEmpty(bricks[X, Y - 1])) { //Found something in S" return bricks[X, Y - 1]; } else if ((dir == Direction.SE) && Y > 0 && X < max && !IsEmpty(bricks[X + 1, Y - 1])) { //Found something in SE" return bricks[X + 1, Y - 1]; } return null; }
public static ArrayList GetValidDirections(OthelloPiece[,] bricks, OthelloPiece brick, Othello.PlayerColor currentPlayer) { // print ("Checking Valid Moves"); ArrayList validDirections = new ArrayList(); foreach (Direction direction in Enum.GetValues(typeof(Direction))) { OthelloPiece nextBrick = NextBrickInDirection(brick.x, brick.y, direction, bricks); if (nextBrick != null) { //print ("valid move: X." + nextBrick.x + " Y. " + nextBrick.y + " in direction " + direction); if (ValidateLine(nextBrick.x, nextBrick.y, direction, 1, bricks, currentPlayer)) { validDirections.Add(direction); } } } return validDirections; }
public static void PutDownBrick(OthelloPiece brick, Othello.PlayerColor currentPlayer) { if (currentPlayer == Othello.PlayerColor.White) { brick.brickColor = BrickColor.White; } else { brick.brickColor = BrickColor.Black; } }
public static void ReleaseAllFlashes(OthelloPiece[,] bricks) { foreach (OthelloPiece brick in bricks) { if (IsColored(brick)) { brick.ShouldFlash = false; } } }
static OthelloPiece GetRandomValidCorner(OthelloPiece[,] bricks) { var validCorners = GetValidCorners(bricks); return validCorners.Count > 0 ? validCorners[UnityEngine.Random.Range(0, validCorners.Count - 1)] : null; }