public void generate(List <sbyte> customPlacements = null) { //Destroy existing squares before we generate the new squares to fit the new board width and height. _destroyChildren(boardScript.chessPieceHolder); _destroyChildren(boardScript.chessSquareHolder); // Debug.Log("boardscript "+boardScript.chessSquareHolder); ////Add placemetns for the tiny board as is available from cgMenuScript //cgCustomBoardSettings.AddPiecePlacement(6, 7, new List<sbyte>{ // -2,-3,-5,-6,-3,-2, // -1,-1,-1,-1,-1,-1, // 0, 0, 0, 0, 0, 0, // 0, 0, 0, 0, 0, 0, // 0, 0, 0, 0, 0, 0, // 1, 1, 1, 1, 1, 1, // 2, 3, 5, 6, 3, 2 // }); _piecePlacements = customPlacements;// cgCustomBoardSettings.GetPiecePlacements(this.boardWidth, this.boardHeight); Debug.Log("piece placements " + _piecePlacements.Count); _board = new global::cgBoard(_piecePlacements, boardWidth, boardHeight); byte totalSquareCount = (byte)(boardWidth * boardHeight); List <cgSquareScript> squares = new List <cgSquareScript>(); for (byte b = 0; b < totalSquareCount; b++) { float y = Mathf.Floor(b / boardWidth); float x = b - (y * boardWidth); bool black = (b + y) % 2 == 0; GameObject newSquare = (GameObject)PrefabUtility.InstantiatePrefab(black ? blackSquarePrefab : whiteSquarePrefab); newSquare.transform.SetParent(boardScript.chessSquareHolder.transform); y *= squareSpacing.y; x *= squareSpacing.x; y = -y; newSquare.transform.localScale = new Vector3(squareScale.x, squareScale.y, newSquare.transform.localScale.z); newSquare.transform.localPosition = new Vector3(x + squareStartPoint.x, y - squareStartPoint.y, squareStartPoint.z); newSquare.GetComponent <cgSquareScript>().uniqueName = _board.SquareNames[b]; //UnityEngine.Debug.Log("Scale: "+newSquare.transform.localScale); squares.Add(newSquare.GetComponent <cgSquareScript>()); //newSquare.GetComponentInChildren<TextMesh>().text= b.ToString(); //newSquare.GetComponentInChildren<TextMesh>().GetComponent<MeshRenderer>().sortingOrder = 9; } for (byte b = 0; b < _piecePlacements.Count; b++) { if (_piecePlacements[b] != 0) { //Create a piece and place it accordingly. cgChessPieceScript piece = ((GameObject)PrefabUtility.InstantiatePrefab(piecePrefab)).GetComponent <cgChessPieceScript>(); piece.SetType(_piecePlacements[b]); piece.transform.SetParent(boardScript.chessPieceHolder.transform); } } boardScript.displayAs3d = use3d; boardScript.setBoardTo(_board); //We delay the start by 1 frame to allow unity garbage collector to destroy and remove any gameobjects that we've destroyed in this scope. //StartCoroutine(_startNextFrame(_board)); }
/// <summary> /// A piece has callbacked that the user has pressed it. /// </summary> /// <param name="piece"></param> private void _pieceDown(cgChessPieceScript piece) { if (highlightLegalMoves && playerCanMove) { List <cgSimpleMove> moves = _abstractBoard.findStrictLegalMoves(_abstractBoard.whiteTurnToMove); foreach (cgSimpleMove move in moves) { if (_abstractBoard.SquareNames[move.from] == piece.square.uniqueName) { if (move is cgCastlingMove) //Highlighting rook instead of king destinatif when castling. { _getSquare(_abstractBoard.SquareNames[(move as cgCastlingMove).secondFrom]).changeColor(_getSquare(_abstractBoard.SquareNames[(move as cgCastlingMove).secondFrom]).legalMoveToColor); } else { _getSquare(_abstractBoard.SquareNames[move.to]).changeColor(_getSquare(_abstractBoard.SquareNames[move.from]).legalMoveToColor); } } } } _downPiece = piece; //int indexPosition = cgGlobal.IndexFromCellName(_downPiece.square.uniqueName); //_abstractBoard.squares[indexPosition = 2//make the changes you want. }
private void _setDeadPiece(cgChessPieceScript cp) { cp.dead = true; cp.square = null; if (!_deadPieces.Contains(cp)) { //UnityEngine.Debug.Log("cp white: "+cp.white); if (cp.white) { cp.transform.position = whiteDeadPiecesLocation + new Vector3(0, (float)(_deadWhitePieces * .4), 0); } else if (!cp.white) { cp.transform.position = blackDeadPiecesLocation + new Vector3(0, (float)(_deadBlackPieces * .4), 0); } _deadPieces.Add(cp); if (cp.white) { _deadWhitePieces++; } else { _deadBlackPieces++; } } }
/// <summary> /// The user has released a dragged piece. Verify that its a legal move, if so perform the move and perform the next move if appropriate mode. /// </summary> /// <param name="piece"></param> private void _pieceUp(cgChessPieceScript piece) { if (_downPiece != null) { if (playerCanMove || Mode == BoardMode.PlayerVsPlayer) { cgSimpleMove legalMove = null; cgSquareScript closestSquare = _findSquareAt(_downPiece.transform.position); List <cgSimpleMove> legalMoves = _abstractBoard.findLegalMoves(whiteTurnToMove); foreach (cgSimpleMove move in legalMoves) { if (cgGlobal.SquareNames[move.from] == _downPiece.square.uniqueName && cgGlobal.SquareNames[move.to] == closestSquare.uniqueName) { legalMove = move; } } //test legality of move here. if (legalMove != null && _abstractBoard.verifyLegality(legalMove)) { //piece.moveToSquare(closestSquare); _makeMove(legalMove); if (Mode == BoardMode.PlayerVsEngine) { _engine.MakeMove(_abstractBoard, false, _engineCallback); } else if (Mode == BoardMode.EngineVsPlayer) { _engine.MakeMove(_abstractBoard, true, _engineCallback); } } else { piece.moveToSquare(piece.square); } } else { piece.moveToSquare(piece.square); } _downPiece = null; } else { piece.moveToSquare(piece.square); _downPiece = null; } if (highlightLastMove) {//revert colors if highlighting is active foreach (cgSquareScript square in _squares) { square.changeColor(square.startColor); } } }
/// <summary> /// Place pieces according to the current state of the underlying abstractboard. /// </summary> public void placePieces() { //Collect existing pieces, we instantiate new ones if we run out of existing pieces below. List <cgChessPieceScript> pieces = new List <cgChessPieceScript>(); foreach (cgChessPieceScript piece in chessPieceHolder.GetComponentsInChildren <cgChessPieceScript>()) { pieces.Add(piece); } UnityEngine.Debug.Log("Place pieces called. " + pieces.Count + " " + chessPieceHolder.GetComponentsInChildren <cgChessPieceScript>().Length + " " + _abstractBoard.squares.Count); for (byte i = 0; i < _abstractBoard.squares.Count; i++) { if (_abstractBoard.squares[i] != 0) { if (pieces.Count == 0) //We instantiate more pieces if we run out of pieces to place. { cgChessPieceScript newPiece = GameObject.Instantiate(ChessPiecePrefab).GetComponent <cgChessPieceScript>(); newPiece.gameObject.transform.parent = chessPieceHolder.transform; newPiece.displayAs3D = this.displayAs3d; newPiece.gameObject.SetActive(true); pieces.Add(newPiece); //UnityEngine.Debug.Log("Instantiating piece"); } cgChessPieceScript piece = pieces[pieces.Count - 1]; //UnityEngine.Debug.Log("i: "+i+" squarenames: "+_abstractBoard.SquareNames.Length); piece.StartAtSquare(_getSquare(_abstractBoard.SquareNames[i])); _livePieces.Add(piece); piece.dead = false; piece.displayAs3D = this.displayAs3d; piece.SetType((int)_abstractBoard.squares[i]); pieces.Remove(piece); //UnityEngine.Debug.Log("Finding piece for " + _abstractBoard.squares[i]); } } //Unused pieces foreach (cgChessPieceScript piece in pieces) { GameObject.DestroyImmediate(piece.gameObject); } cgChessPieceScript[] allPieces = chessPieceHolder.GetComponentsInChildren <cgChessPieceScript>(); foreach (cgChessPieceScript piece in allPieces) { if (piece.square == null) { GameObject.Destroy(piece.gameObject); } } //Give all active pieces callback functions for mouse events. foreach (cgChessPieceScript piece in _livePieces) { piece.SetCallbacks(_pieceDown, _pieceUp); } }
/// <summary> /// Peform the provided move on the visual board and the abstract board, with no legality checks - thus should be performed prior to calling this. /// </summary> /// <param name="move"></param> private void _makeMove(cgSimpleMove move) { UnityEngine.Debug.Log("White: " + _abstractBoard.whiteTurnToMove); movesMade++; playSound(moveSound); _abstractBoard.move(move); _writeLog(move); //_abstractBoard.debugReadBoard(); if (_getPieceOn(_abstractBoard.SquareNames[move.to]) != null && !(move is cgCastlingMove)) { _setDeadPiece(_getPieceOn(_abstractBoard.SquareNames[move.to])); } cgChessPieceScript piece = _getPieceOn(_abstractBoard.SquareNames[move.from]); if (move.queened) { piece.SetType(_abstractBoard.squares[move.to] > 0 ? cgChessPieceScript.Type.WhiteQueen : cgChessPieceScript.Type.BlackQueen); } if (move is cgCastlingMove) { cgChessPieceScript piece2 = _getPieceOn(_abstractBoard.SquareNames[(move as cgCastlingMove).secondFrom]); if (piece2) { piece2.moveToSquare(_getSquare(_abstractBoard.SquareNames[(move as cgCastlingMove).secondTo])); } } else if (move is cgEnPassantMove) { cgChessPieceScript piece2 = _getPieceOn(_abstractBoard.SquareNames[(move as cgEnPassantMove).attackingSquare]); piece2.dead = true; } piece.moveToSquare(_getSquare(_abstractBoard.SquareNames[move.to])); whiteTurnToMove = _abstractBoard.whiteTurnToMove; _checkGameOver(); if (highlightLastMove) { //Color copyFrom = _getSquare(cgGlobal.SquareNames[move.to]).startColor; Color color = _getSquare(_abstractBoard.SquareNames[move.to]).recentMoveColor; _getSquare(_abstractBoard.SquareNames[move.to]).highlightTemporarily(color); } //Debug.Log("making move. " + _abstractBoard.whiteTurnToMove+" moves "+_abstractBoard.moves.Count); //UnityEngine.Debug.Log("Time elapsed: " + stopwatch.Elapsed); if (Mode == BoardMode.EngineVsEngine) { MakeEngineMove(_abstractBoard.duplicate(), _abstractBoard.whiteTurnToMove, _engineCallback); } }
private void _setDeadPiece(cgChessPieceScript cp) { cp.dead = true; cp.square = null; if (!_deadPieces.Contains(cp)) { cp.transform.position = new Vector3(3 + (cp.white ? .3f : 0), (float)((cp.white ? _deadWhitePieces : _deadBlackPieces) * .4) - 2, 0); _deadPieces.Add(cp); if (cp.white) { _deadWhitePieces++; } else { _deadBlackPieces++; } } }
/// <summary> /// Peform the provided move on the visual board and the abstract board, with no legality checks - thus should be performed prior to calling this. /// </summary> /// <param name="move"></param> private void _makeMove(cgSimpleMove move) { //Debug.Log("making move:" + cgGlobal.MoveToString(move)); movesMade++; playSound(moveSound); _abstractBoard.move(move); _writeLog(move); //_abstractBoard.debugReadBoard(); if (_getPieceOn(cgGlobal.SquareNames[move.to]) != null) { _setDeadPiece(_getPieceOn(cgGlobal.SquareNames[move.to])); } cgChessPieceScript piece = _getPieceOn(cgGlobal.SquareNames[move.from]); piece.moveToSquare(_getSquare(cgGlobal.SquareNames[move.to])); if (move.promoted) { piece.SetType(_abstractBoard.squares[move.to] > 0 ? cgChessPieceScript.Type.WhiteQueen : cgChessPieceScript.Type.BlackQueen); } if (move is cgCastlingMove) { cgChessPieceScript piece2 = _getPieceOn(cgGlobal.SquareNames[(move as cgCastlingMove).secondFrom]); if (piece2) { piece2.moveToSquare(_getSquare(cgGlobal.SquareNames[(move as cgCastlingMove).secondTo])); } } else if (move is cgEnPassantMove) { cgChessPieceScript piece2 = _getPieceOn(cgGlobal.SquareNames[(move as cgEnPassantMove).attackingSquare]); piece2.dead = true; } whiteTurnToMove = _abstractBoard.whiteTurnToMove; _checkGameOver(); if (highlightLastMove) { //Color copyFrom = _getSquare(cgGlobal.SquareNames[move.to]).startColor; Color color = _getSquare(cgGlobal.SquareNames[move.to]).recentMoveColor; _getSquare(cgGlobal.SquareNames[move.to]).highlightTemporarily(color); } }
/// <summary> /// A piece has callbacked that the user has pressed it. /// </summary> /// <param name="piece"></param> private void _pieceDown(cgChessPieceScript piece) { if (highlightLegalMoves) { List <cgSimpleMove> moves = _abstractBoard.findStrictLegalMoves(_abstractBoard.whiteTurnToMove); foreach (cgSimpleMove move in moves) { if (cgGlobal.SquareNames[move.from] == piece.square.uniqueName) { _getSquare(cgGlobal.SquareNames[move.to]).changeColor(_getSquare(cgGlobal.SquareNames[move.from]).legalMoveToColor); } } } _downPiece = piece; //int indexPosition = cgGlobal.IndexFromCellName(_downPiece.square.uniqueName); //_abstractBoard.squares[indexPosition = 2//make the changes you want. }