GameEndCondition _innerCheck() { var inner = ChessService.CurrentGame.InnerGame; if (inner.half_moves >= 100) { // counts number of moves made without a pawn moving or capture return(GameEndCondition.Draw($"No captures or pawn movements made in 50 moves")); } if (inner.in_checkmate()) { var opposite = inner.swap_color(inner.turn); var player = opposite == "w" ? CurrentGame.White : CurrentGame.Black; return(GameEndCondition.Win(player, "In check with no legal moves")); } if (inner.in_stalemate()) { return(GameEndCondition.Draw("Not in check but no legal moves")); } if (inner.insufficient_material()) { return(GameEndCondition.Draw("Insufficient material to cause checkmate")); } if (inner.in_threefold_repetition()) { return(GameEndCondition.Draw("Board repeated thrice")); } return(GameEndCondition.NotEnded()); }
void handleInGame(ChessPacket ping) { if (ping.Id == PacketId.MoveRequest) { var r = new OtherGame.Move(); var g = CurrentGame; string sFrom = ping.Content["from"].ToObject <string>(); string sTo = ping.Content["to"].ToObject <string>(); if (!(Side == PlayerSide.White && g.InnerGame.turn == "w" || Side == PlayerSide.Black && g.InnerGame.turn == "b")) { Send(new ChessPacket(PacketId.MoveRequestRefuse, new MoveRefuse($"{sFrom} -> {sTo}", $"It is not your turn").ToJson())); return; } r.from = g.InnerGame.parseAlgebraic(sFrom); r.to = g.InnerGame.parseAlgebraic(sTo); var promVal = ping.Content["promote"]; if (promVal != null) { r.promotion = getPieceSimple(promVal.ToObject <int>()); } var legalMoves = g.InnerGame.generate_moves(new Dictionary <string, string>() { { "legal", "true" }, { "square", r.from.ToString() } }); OtherGame.Move?legalMove = null; foreach (var mv in legalMoves) { if (mv.from == r.from && mv.to == r.to) { if (!string.IsNullOrWhiteSpace(mv.promotion) && !string.IsNullOrWhiteSpace(r.promotion)) { if (mv.promotion != r.promotion) { continue; } } if (!string.IsNullOrWhiteSpace(mv.promotion) && string.IsNullOrWhiteSpace(r.promotion)) { if (mv.promotion != "q") { continue; } } if (string.IsNullOrWhiteSpace(mv.promotion) && !string.IsNullOrWhiteSpace(r.promotion)) { continue; } legalMove = mv; break; } } if (legalMove.HasValue == false) { Send(new ChessPacket(PacketId.MoveRequestRefuse, new MoveRefuse($"{sFrom} -> {sTo}", $"No legal move to that location").ToJson())); return; } g.InnerGame.make_move(legalMove.Value); g.InnerGame.registerMoveMade(); Program.LogMsg("Player made move", Discord.LogSeverity.Error, "Player"); ChessService.CurrentGame.updateBoard(); Broadcast(new ChessPacket(PacketId.MoveMade, ping.Content)); CheckGameEnd(); } else if (ping.Id == PacketId.IdentRequest) { var id = ping.Content["id"].ToObject <int>(); var player = CurrentGame.GetPlayer(id); var jobj = ping.Content; jobj["player"] = player?.ToJson() ?? JObject.FromObject(null); Send(new ChessPacket(PacketId.PlayerIdent, jobj)); } else if (ping.Id == PacketId.RequestScreen) { if (Player.Permission.HasFlag(ChessPerm.Moderator)) { var player = CurrentGame.GetPlayer(ping.Content["id"].ToObject <int>()); if (player != null) { player.ExpectDemand = true; player.Send(new ChessPacket(PacketId.DemandScreen, new JObject())); } } } else if (ping.Id == PacketId.RequestGameEnd) { var id = ping.Content["id"].ToObject <int>(); var player = id == 0 ? null : ChessService.CurrentGame.GetPlayer(id); var end = id == 0 ? GameEndCondition.Draw($"A-Drawn by {Player.Name}") : GameEndCondition.Win(player, $"A-Won by {Player.Name}"); ChessService.CurrentGame.DeclareWinner(end); } else if (ping.Id == PacketId.RequestProcesses) { if (Player.Permission.HasFlag(ChessPerm.Moderator)) { var player = CurrentGame.GetPlayer(ping.Content["id"].ToObject <int>()); if (player != null) { player.ExpectDemand = true; player.Send(new ChessPacket(PacketId.DemandProcesses, new JObject())); } } } else if (ping.Id == PacketId.ResignRequest) { ChessConnection opponent; if (Side == PlayerSide.White) { opponent = ChessService.CurrentGame.Black; } else if (Side == PlayerSide.Black) { opponent = ChessService.CurrentGame.White; } else { // spectators can't resign. return; } ChessService.CurrentGame.DeclareWinner(GameEndCondition.Win(opponent, "Resigned")); } else if (ping.Id == PacketId.RequestRevertMove) { if (Player.Permission.HasFlag(ChessPerm.Moderator)) { CurrentGame.InnerGame.undo_move(); Broadcast(new ChessPacket(PacketId.MoveReverted, ping.Content)); } } }