private static bool InCheckmate(ChessMoveData moveData) { //get all enemy moves var enemyMoves = GetMyMoves(moveData.NewBoard, EnemyColor(moveData.Color)); //if any enemy move results in a board where i can't take the king, is not checkmate var checkmate = true; foreach (var enemyMove in enemyMoves) { var myCounterMoves = GetMyMoves(enemyMove.NewBoard, moveData.Color); var canTakeKing = false; foreach (var counterMove in myCounterMoves) { var toTile = counterMove.OldBoard[counterMove.Move.To.X, counterMove.Move.To.Y]; if ((moveData.Color == ChessColor.Black && toTile == ChessPiece.WhiteKing) || (moveData.Color == ChessColor.White && toTile == ChessPiece.BlackKing)) { canTakeKing = true; break; } } if (!canTakeKing) { checkmate = false; break; } } return(checkmate); }
public GameEventOpponentTurn(Session session, ObjectGuid boardGuid, ChessMoveData moveData) : base(GameEventType.OpponentTurn, GameMessageGroup.UIQueue, session) { Writer.Write(boardGuid.Full); Writer.Write((int)moveData.Color); Writer.Write(moveData); }
public async Task <string> ConfirmChessMove([FromBody] ChessMoveData data) { try { if (string.IsNullOrEmpty(data.gameId)) { throw new HttpResponseException((HttpStatusCode)501, "Cannot write move, wrong game Id!"); } if (string.IsNullOrEmpty(data.player1Address) || string.IsNullOrEmpty(data.player2Address)) { throw new HttpResponseException((HttpStatusCode)501, "Cannot write move, wrong account address!"); } if (MainGameDataContext.Games.TryGetValue(data.gameId, out var game)) { var res = await(game as ChessGame).WriteMove(data.chessboardState, data.player1Address, data.player2Address, data.password); return(res); } else { throw new HttpResponseException((HttpStatusCode)501, "Cannot write move, game does not exists!"); } } catch (Exception ex) { log.Error("Cannot create chess move", ex); throw new HttpResponseException((HttpStatusCode)501, "Cannot write chess move!"); } }
public bool ValidateMove(ChessMoveData move, Color color) { return(move.FromRow >= 0 && move.FromRow < ChessboardSize && move.FromColumn >= 0 && move.FromColumn < ChessboardSize && move.ToRow >= 0 && move.ToRow < ChessboardSize && move.ToColumn >= 0 && move.ToColumn < ChessboardSize && !board[move.FromRow, move.FromColumn].Empty && board[move.FromRow, move.FromColumn].Piece !.Color == color); }
private void HandleTap(int row, int column, Rectangle field) { if (Match.State != Core.Enums.GameState.YourTurn) { return; } var board = Match.CurrentBoard.Content as ChessMoveResult; var playerIndex = Match.PlayerIndex; var clickedPiece = board.PieceInfos.FirstOrDefault(p => p.Row == row && p.Column == column); // We clicked on an empty field if (clickedPiece == null) { // ... and haven't selected any pieces to move, so we return early if (lastTapped == null) { return; } } // If we clicked on our own piece else if ((playerIndex == 0 && clickedPiece.Color == Core.DTOs.Chess.Color.White) || (playerIndex == 1 && clickedPiece.Color == Core.DTOs.Chess.Color.Black)) { // Save the position as our selected piece and return lastTapped = new Field() { Column = column, Row = row }; if (lastTappedRect != null) { lastTappedRect.Fill = new SolidColorBrush(lastTappedRectColor); } lastTappedRect = field; var fieldColor = (row + column) % 2 == 0 ? Colors.White : Colors.DarkGray; lastTappedRectColor = fieldColor; (field as Rectangle).Fill = new SolidColorBrush(Colors.Yellow); return; } // Else if we clicked on the opponent's piece else if ((playerIndex == 0 && clickedPiece.Color == Core.DTOs.Chess.Color.Black) || (playerIndex == 1 && clickedPiece.Color == Core.DTOs.Chess.Color.White)) { // Do nothing if we haven't selected our piece to move yet if (lastTapped == null) { return; } } // Perform the move, then reset highlight var moveData = new ChessMoveData() { FromColumn = lastTapped.Column, FromRow = lastTapped.Row, ToColumn = column, ToRow = row, MatchId = Match.Id }; MoveCommand.Execute(moveData); lastTapped = null; lastTappedRect.Fill = new SolidColorBrush(lastTappedRectColor); lastTappedRect = null; }
IEnumerator TweenMoveChessAndBeat(ChessHeroData heroChoosed, ChessHeroData hero, ChessMoveResult resultR, ChessMoveData moveData) { m_MyChessIsMoving = true; if ((resultR == ChessMoveResult.CANNOT_MOVE && moveData.crashType <= 0) || (resultR == ChessMoveResult.CAN_MOVE && moveData.crashType > 0)) { ChessDataHasProblem(); } else { if (moveData.crashType > 0) { App.Package.ChessGame.MyselfChooseChessId = hero.id; Debugger.Warn("ChessHeroItem Cant MoveTo " + hero.point.ToString() + " : " + moveData.crashType); m_MyChessIsMoving = false; } else { Push("_cleanArrow"); m_lastPath = moveData.points; ChessMoveResult result = resultR;//ChessAgainst.ChessCanBeat(heroChoosed, hero); float dur = 0.4f / moveData.points.Length; for (int i = 1; i < moveData.points.Length - 1; i++) { ShowChessMoveTo(heroChoosed.point, moveData.points[i]); ChessMoveTo(heroChoosed, moveData.points[i]); yield return(new WaitForSeconds(dur)); } //加入历史走子 App.Package.ChessGame.ChessHistorySteps.Insert(0, App.Package.ChessGame.BuildHistoryStep( App.Package.ChessGame.GameRoundCounter, heroChoosed, hero, App.Package.ChessGame.BuildChessDataPathFromPoints(moveData.points), (int)result ) ); Push("_updateHistory"); switch (result) { case ChessMoveResult.LOSE: heroChoosed.state = ChessHeroState.Died; heroChoosed.gameObject.SetActive(false); break; case ChessMoveResult.TIE: heroChoosed.state = ChessHeroState.Died; heroChoosed.gameObject.SetActive(false); hero.state = ChessHeroState.Died; hero.gameObject.SetActive(false); break; case ChessMoveResult.WIN: hero.state = ChessHeroState.Died; hero.gameObject.SetActive(false); break; } ShowChessMoveTo(heroChoosed.point, moveData.points[moveData.points.Length - 1]); ChessMoveTo(heroChoosed, moveData.points[moveData.points.Length - 1]); if (result > 0) { //UIWChessHeroItem uiChess = heroChoosed.gameObject.GetComponent<UIWChessHeroItem>(); //uiChess.isChoosed = true; //uiChess.UpdateView(); } else { //App.Package.ChessGame.MyselfChooseChessId = -1; } int cid = -1; bool resultS; if (heroChoosed.group == ChessHeroGroup.Myself) { cid = heroChoosed.realChessType; resultS = result == ChessMoveResult.WIN; if (cid > 0 && cid < 11 && cid != 1) { m_roundOver.SetState(cid, resultS); } } else { cid = hero.realChessType; resultS = result == ChessMoveResult.WIN; if (cid > 0 && cid < 11 && cid != 1) { switch (result) { case ChessMoveResult.WIN: case ChessMoveResult.TIE: m_roundOver.SetState(cid, false); break; case ChessMoveResult.LOSE: m_roundOver.SetState(cid, true); break; } } } App.Package.ChessGame.MyselfChooseChessId = heroChoosed.id; Push("_chessHeroChoosed", heroChoosed.id); m_MyChessIsMoving = false; NextGameRound(); } } }
IEnumerator TweenMoveChess(ChessHeroData heroChoosed, ChessPoint moveToPoint, ChessMoveResult result, ChessMoveData moveData) { m_MyChessIsMoving = true; //if((ChessMoveResult.CANNOT_MOVE == result && moveData.crashType > 0) || (ChessMoveResult.CAN_MOVE == result && moveData.crashType == 0)) //{ Push("_cleanArrow"); m_lastPath = moveData.points; float dur = 0.2f / moveData.points.Length; for (int i = 1; i < moveData.points.Length; i++) { ShowChessMoveTo(heroChoosed.point, moveData.points[i]); ChessMoveTo(heroChoosed, moveData.points[i]); yield return(new WaitForSeconds(dur)); } //加入历史走子 App.Package.ChessGame.ChessHistorySteps.Insert(0, App.Package.ChessGame.BuildHistoryStep( App.Package.ChessGame.GameRoundCounter, heroChoosed, moveToPoint, App.Package.ChessGame.BuildChessDataPathFromPoints(moveData.points), (int)result ) ); Push("_updateHistory"); heroChoosed.point = moveToPoint; m_MyChessIsMoving = false; NextGameRound(); //} /*else * { * ChessDataHasProblem(); * }*/ }
void RequestToMove(ChessHeroData heroChoosed, ChessPoint moveToPoint, ChessHeroData hero, ChessMoveData moveData) { m_MyChessIsMoving = true; MoveChessRequest request = new MoveChessRequest(); request.Source = ChessHeroDataToChessData(App.Package.Player.playerInfo, heroChoosed); if (hero != null) { request.Target = ChessHeroDataToChessData(App.Package.ChessGame.EnemyPlayerList[0], hero);//多人的时候要修改 } else { request.Target = new ChessData(); request.Target.Point = moveToPoint.ParseToRpc(); } App.Manager.Network.Request("MoveChess", request, delegate(IMessage responseData) { MoveChessResponse response = (MoveChessResponse)responseData; int result = response.ChessMoveResult; //强制回合同步 App.Package.ChessGame.GameRoundCounter = response.Counter - 1; if (response.Counter == App.Package.ChessGame.GameRoundCounter + 1) { if (hero == null) { StartCoroutine(TweenMoveChess(heroChoosed, moveToPoint, (ChessMoveResult)result, moveData)); } else { StartCoroutine(TweenMoveChessAndBeat(heroChoosed, hero, (ChessMoveResult)result, moveData)); } } else { ChessDataHasProblem(); } }, true, false, false); }
private void OnChessHeroClick(object content)//吃子移动 { if (App.Package.ChessGame.IsGameStart) { if (!App.Package.ChessGame.IsMyRound) { Common.UI.OpenTips("敌方回合,无法行动"); return; } if (m_MyChessIsMoving) { return; //正在移动 } Intent intent = (Intent)content; int id = (int)intent.Value("id"); GameObject go = (GameObject)intent.Value("gameObject"); ChessHeroData hero = App.Package.ChessGame.GetChessHeroDataById(id); ChessHeroGroup group = hero.group; Push("_chessHeroChoosed", id); //明棋模式提醒 if (group == ChessHeroGroup.Myself) { for (int i = 0; i < App.Package.ChessGame.ChessDataIds.Count; i++) { int chessId = App.Package.ChessGame.ChessDataIds[i]; ChessHeroData heroPre = App.Package.ChessGame.GetChessHeroDataById(chessId); if (heroPre.group == ChessHeroGroup.Myself) { continue; } UIWChessHeroItem uiChess = heroPre.gameObject.GetComponent <UIWChessHeroItem>(); uiChess.willLose.SetActive(false); uiChess.willWin.SetActive(false); uiChess.willTie.SetActive(false); if (heroPre.heroTypeId > -1 && ChessAgainst.ChessHeroCanMove(hero)) { ChessMoveResult result = ChessAgainst.ChessCanBeat(hero, heroPre); switch (result) { case ChessMoveResult.LOSE: uiChess.willLose.SetActive(true); break; case ChessMoveResult.TIE: uiChess.willTie.SetActive(true); break; case ChessMoveResult.WIN: uiChess.willWin.SetActive(true); break; } } } } else { for (int i = 0; i < App.Package.ChessGame.ChessDataIds.Count; i++) { int chessId = App.Package.ChessGame.ChessDataIds[i]; ChessHeroData heroPre = App.Package.ChessGame.GetChessHeroDataById(chessId); if (heroPre.group == ChessHeroGroup.Myself) { continue; } UIWChessHeroItem uiChess = heroPre.gameObject.GetComponent <UIWChessHeroItem>(); uiChess.willLose.SetActive(false); uiChess.willWin.SetActive(false); uiChess.willTie.SetActive(false); } } if (App.Package.ChessGame.MyselfChooseChessId > -1) { ChessHeroData heroChoosed = App.Package.ChessGame.GetChessHeroDataById(App.Package.ChessGame.MyselfChooseChessId); if (heroChoosed.group == ChessHeroGroup.Myself && group != ChessHeroGroup.Myself) //之前有选择自己,当前非己方的棋 { if (App.Package.ChessGame.IsGameStart) //游戏开始了之后才能走并吃子 { if (ChessAgainst.IsBarrack(hero.point) && hero.point.y > 5) //敌方的军营 { Common.UI.OpenTips("敌军在行营里,不要浪啊~"); } else { if (ChessAgainst.IsStronghold(heroChoosed.point)) { Common.UI.OpenTips("大本营的棋子无法移动!"); } else { ChessMoveData moveData = ChessAgainst.ChessHeroCanMoveTo(heroChoosed, hero.point); if (moveData.crashType > 0) { if (moveData.crashType == 1) { switch (moveData.crashHero.heroTypeId) { case 0: Common.UI.OpenTips("地雷无法移动!"); break; case 11: Common.UI.OpenTips("军旗无法移动!"); break; default: Common.UI.OpenTips("嗷!走不过去啊!"); break; } } else { Common.UI.OpenTips("嗷!走不过去啊!"); } } else { RequestToMove(heroChoosed, hero.point, hero, moveData); } } } } } } App.Package.ChessGame.MyselfChooseChessId = id; } else { if (App.Package.ChessGame.IsReadyGame) { Common.UI.OpenTips("比赛还没开始哦,不要心急"); } else { Common.UI.OpenTips("赶紧布兵吧!你还没有准备呢\n长按拖动可以交换棋子!"); } } }
private void OnChessClick(object content) //移动 { if (App.Package.ChessGame.IsGameStart) //游戏开始了之后才能走 { if (!App.Package.ChessGame.IsMyRound) { Common.UI.OpenTips("敌方回合,无法行动"); return; } if (m_MyChessIsMoving) { return; //正在移动 } Intent intent = (Intent)content; ChessPoint point = (ChessPoint)intent.Value("point"); GameObject go = (GameObject)intent.Value("gameObject"); //Debugger.Warn("ChessItem Click:" + id +"|"+ App.Package.ChessGame.MyselfChooseChessId + "|" +App.Package.ChessGame.GetFieldRoadStationByPoint(point).type); if (App.Package.ChessGame.MyselfChooseChessId > -1) { ChessHeroData heroChoosed = App.Package.ChessGame.GetChessHeroDataById(App.Package.ChessGame.MyselfChooseChessId); if (heroChoosed.group == ChessHeroGroup.Myself) { if (ChessAgainst.IsStronghold(heroChoosed.point)) { Common.UI.OpenTips("大本营的棋子无法移动!"); } else { ChessMoveData moveData = ChessAgainst.ChessHeroCanMoveTo(heroChoosed, point); if (moveData.crashType > 0) { if (moveData.crashType == 1) { switch (moveData.crashHero.heroTypeId) { case 0: Common.UI.OpenTips("地雷无法移动!"); break; case 11: Common.UI.OpenTips("军旗无法移动!"); break; default: Common.UI.OpenTips("嗷!走不过去啊!"); break; } } else { Common.UI.OpenTips("嗷!走不过去啊!"); } } else { RequestToMove(heroChoosed, point, null, moveData); } } } } } else { if (App.Package.ChessGame.IsReadyGame) { Common.UI.OpenTips("比赛还没开始哦,不要心急"); } else { Common.UI.OpenTips("赶紧布兵吧!你还没有准备呢\n长按拖动可以交换棋子!"); } } }
/// <summary> /// 走子情况 /// </summary> void OnReceiveChessMove(object data) { ChessMovePush push = (ChessMovePush)data; ChessData source = push.Source; ChessData target = push.Target; ChessMoveResult result = (ChessMoveResult)push.ChessMoveResult; ChessHeroData sourceReal = App.Package.ChessGame.GetChessHeroDataByRemoteId(source.ChessRemoteId); //强制回合同步 App.Package.ChessGame.GameRoundCounter = push.Counter - 1; if (target != null) { ChessHeroData targetReal = App.Package.ChessGame.GetChessHeroDataByRemoteId(target.ChessRemoteId); if (sourceReal == null || (targetReal == null && result != ChessMoveResult.CAN_MOVE && result != ChessMoveResult.CANNOT_MOVE) || push.Counter != App.Package.ChessGame.GameRoundCounter + 1) { ChessDataHasProblem(); return; } ChessHeroData fake = ChessDataToChessHeroData(target, true); if (targetReal != null) { fake = targetReal; } ChessMoveData moveData = ChessAgainst.ChessHeroCanMoveTo(sourceReal, fake.point); switch (result) { case ChessMoveResult.LOSE: fake.heroTypeId = 12; StartCoroutine(TweenMoveChessAndBeat(sourceReal, fake, result, moveData)); break; case ChessMoveResult.WIN: fake.heroTypeId = -2; StartCoroutine(TweenMoveChessAndBeat(sourceReal, fake, result, moveData)); break; case ChessMoveResult.TIE: fake.heroTypeId = -3; StartCoroutine(TweenMoveChessAndBeat(sourceReal, fake, result, moveData)); break; case ChessMoveResult.CAN_MOVE: StartCoroutine(TweenMoveChess(sourceReal, fake.point, result, moveData)); break; case ChessMoveResult.CANNOT_MOVE: break; } } else { NextGameRound(); if (source.Belong == App.Package.Player.GetBelong()) { Common.UI.OpenTips("超时跳过"); } else { Common.UI.OpenTips("敌方超时跳过"); } Debugger.Error("skip"); } }
private void SetMoveFlagAndValue(ChessMoveData moveData) { var myMoves = StudentAI.GetMyMoves(moveData.NewBoard, moveData.Color); //see if checking other player bool any = false; foreach (var move in myMoves) { var oldToTile = move.OldBoard[move.Move.To.X, move.Move.To.Y]; if ((moveData.Color == ChessColor.Black && oldToTile == ChessPiece.WhiteKing) || (moveData.Color == ChessColor.White && oldToTile == ChessPiece.BlackKing)) { any = true; break; } } moveData.Move.Flag = any ? ChessFlag.Check : ChessFlag.NoFlag; //see if in checkmate if (moveData.Move.Flag == ChessFlag.Check) { if (InCheckmate(moveData)) { moveData.Move.Flag = ChessFlag.Checkmate; } } moveData.Move.ValueOfMove = GetBoardValue(moveData.NewBoard, moveData.Color); var otherMoves = StudentAI.GetMyMoves(moveData.NewBoard, EnemyColor(moveData.Color)); foreach (var otherMove in otherMoves) { if (otherMove.Move.To.X != moveData.Move.To.X || otherMove.Move.To.Y != moveData.Move.To.Y) { continue; } var currentPiece = moveData.NewBoard[moveData.Move.To.X, moveData.Move.To.Y]; if (currentPiece == ChessPiece.Empty) { continue; } var colorMulti = (GetChessPieceColor(currentPiece) == moveData.Color) ? 1 : -1; var value = 0; switch (currentPiece) { case ChessPiece.BlackPawn: value += colorMulti * pawnValue; value += colorMulti * (pawnValue / PawnRankModifier) * (moveData.Move.To.Y - 1); break; case ChessPiece.WhitePawn: value += colorMulti * pawnValue; value += colorMulti * (pawnValue / PawnRankModifier) * (6 - moveData.Move.To.Y); break; case ChessPiece.BlackRook: case ChessPiece.WhiteRook: value += colorMulti * rookValue; break; case ChessPiece.BlackKnight: case ChessPiece.WhiteKnight: value += colorMulti * knightValue; break; case ChessPiece.BlackBishop: case ChessPiece.WhiteBishop: value += colorMulti * bishopValue; break; case ChessPiece.BlackQueen: case ChessPiece.WhiteQueen: value += colorMulti * queenValue; break; case ChessPiece.BlackKing: case ChessPiece.WhiteKing: break; default: throw new Exception("Somehow not catching a specific piece? Empty?"); break; } value = (int)(value * 1.5f); moveData.Move.ValueOfMove -= value; break; } var random = new Random(); moveData.Move.ValueOfMove += random.Next(randomValue * 2) - randomValue; if (moveData.Move.Flag == ChessFlag.Check) { moveData.Move.ValueOfMove += checkValue; } if (moveData.Move.Flag == ChessFlag.Checkmate) { moveData.Move.ValueOfMove += checkmateValue; } }
public static ChessMoveData ChessHeroCanMoveTo(ChessHeroData heroData, ChessPoint point) { ChessMoveData moveData = new ChessMoveData(); FieldRoadStation roadStationS = App.Package.ChessGame.GetFieldRoadStationByPoint(heroData.point); FieldRoadStation roadStationT = App.Package.ChessGame.GetFieldRoadStationByPoint(point); if (ChessHeroCanMove(heroData))//检测棋子本身,地雷、军旗不能走 { //检测目的地是否禁止 /*for(int i = 0; i < roadStationT.forbidChessHeros.Length; i++) * { * if(heroData.heroTypeId == roadStationT.forbidChessHeros[i]) * { * moveData.crashType = 2; * moveData.crashHero = heroData; * return moveData; * } * }*/ /// for (int i = 0; i < roadStationS.connectedPointIds.Length; i++) { FieldRoadStation roadStation = App.Package.ChessGame.GetFieldRoadStationById(roadStationS.connectedPointIds[i]); if (roadStation == roadStationT) { moveData.crashType = 0; moveData.points = new ChessPoint[] { roadStationS.point, roadStationT.point }; return(moveData); } } if (roadStationS.type == FieldRoadStationType.Rail && roadStationT.type == FieldRoadStationType.Rail) { if (heroData.heroTypeId == 2)//工兵行走 { List <FieldRoadPath> paths = new List <FieldRoadPath>(); List <int> usedStations = new List <int>(); usedStations.Add(roadStationS.id); FieldRoadPath pathStart = new FieldRoadPath(); pathStart.pathStations.Add(roadStationS.id); paths.Add(pathStart); LookForRailWayPath(roadStationT, paths, usedStations, 1, 32); for (int i = 0; i < paths.Count; i++) { FieldRoadPath path = paths[i]; if (path.pathStations[path.pathStations.Count - 1] != roadStationT.id) { continue; } ChessPoint[] points = path.ToChessPoints(); ChessHeroData crashHero = HasChessHeroOnPathPoints(points); if (crashHero == null) { moveData.crashType = 0; moveData.crashHero = null; moveData.points = points; return(moveData); } else { moveData.crashHero = heroData; } } moveData.crashType = 3; moveData.crashHero = heroData; return(moveData); } else if (roadStationS.point.x == roadStationT.point.x)//这里要特别注意 { ChessPoint[] points = new ChessPoint[Mathf.Abs(roadStationS.point.y - roadStationT.point.y) + 1]; int d = (roadStationS.point.y < roadStationT.point.y) ? 1 : -1; points[0] = roadStationS.point; for (int i = 1; i < points.Length; i++) { points[i] = new ChessPoint(roadStationS.point.x, roadStationS.point.y + d * i); if (!IsConnected(points[i - 1], points[i]) || !IsRailWay(points[i - 1], points[i]))//要判断是否相连啊,且都是铁路 { moveData.crashType = 2; return(moveData); } } ChessHeroData crashHero = HasChessHeroOnPathPoints(points); if (crashHero == null) { moveData.crashType = 0; moveData.points = points; } else { moveData.crashType = 3; moveData.crashHero = crashHero; } return(moveData); } else if (roadStationS.point.y == roadStationT.point.y) { ChessPoint[] points = new ChessPoint[Mathf.Abs(roadStationS.point.x - roadStationT.point.x) + 1]; int d = (roadStationS.point.x < roadStationT.point.x) ? 1 : -1; points[0] = roadStationS.point; for (int i = 1; i < points.Length; i++) { points[i] = new ChessPoint(roadStationS.point.x + d * i, roadStationS.point.y); if (!IsConnected(points[i - 1], points[i]) || !IsRailWay(points[i - 1], points[i]))//要判断是否相连啊,且都是铁路 { moveData.crashType = 2; return(moveData); } } ChessHeroData crashHero = HasChessHeroOnPathPoints(points); if (crashHero == null) { moveData.crashType = 0; moveData.points = points; } else { moveData.crashType = 3; moveData.crashHero = crashHero; } return(moveData); } else { //不能走直角 } } } moveData.crashType = 1; moveData.crashHero = heroData; return(moveData); }