public void MateTest2() { var bod = "# ---- 棋譜ファイル ----\n" + "先手:先手\n" + "後手:後手\n" + "後手の持駒:歩三 \n" + " 9 8 7 6 5 4 3 2 1\n" + "+---------------------------+\n" + "|v香v桂 ・ ・ ・ ・ ・ ・ ・|一\n" + "| ・ ・ ・ ・ ・ ・ ・ ・ ・|二\n" + "|v玉v桂v歩 金 ・ ・ ・ ・ ・|三\n" + "| ・ ・ ・ ・ ・ ・ ・ ・ ・|四\n" + "| ・ 銀 ・ 歩 ・ ・ ・ ・ ・|五\n" + "| 玉 ・ 歩 ・ 歩 香 ・ ・ ・|六\n" + "| ・v金 銀 金 ・ ・ ・ ・ ・|七\n" + "| ・ ・v馬 銀 ・ ・ ・ ・ ・|八\n" + "| 香 ・ ・ ・ ・ ・ ・ ・ ・|九\n" + "+---------------------------+\n" + "先手の持駒:飛二 角 金 銀 桂二 香 歩十一 \n" + "手数=0\n" + "後手番\n"; var board = BodBoard.Parse(bod); var move = BoardMove.CreateDrop( BWType.White, new Square(9, 5), PieceType.Hu); Assert.False(board.CanMove(move)); Assert.False(board.DoMove(move)); }
public void MateTest1() { var bod = "後手の持駒:角二 桂二 歩五 \n" + " 9 8 7 6 5 4 3 2 1\n" + "+---------------------------+\n" + "|v香 ・ ・ ・ ・ ・ ・ ・v香|一\n" + "| ・ ・ ・ ・ 銀 ・v金 ・ ・|二\n" + "| ・ ・ とv歩v歩 ・ ・v歩 ・|三\n" + "| ・ ・ ・ ・ ・ ・v歩 ・v歩|四\n" + "| 歩 ・ 銀 金 ・ 飛 ・ ・ ・|五\n" + "| ・ ・ 銀 歩 ・ 金 ・v玉 歩|六\n" + "| 玉 歩 桂 ・ ・ ・ ・ ・ ・|七\n" + "| ・ ・ 歩 ・ ・ 歩 金 ・ ・|八\n" + "| 香v飛 ・ ・ ・ 銀 ・ ・ 香|九\n" + "+---------------------------+\n" + "先手の持駒:桂 歩 \n" + "手数=130"; var board = BodBoard.Parse(bod); var move = BoardMove.CreateDrop( BWType.Black, new Square(2, 7), PieceType.Hu); Assert.False(board.CanMove(move)); Assert.False(board.DoMove(move)); }
/// <summary> /// 移動中の駒を新しい位置に移動します。 /// </summary> /// <remarks> /// 指せない指し手の場合は、駒の移動を終了します。 /// </remarks> private void DoMoveNormal(Square dstSquare) { var srcSquare = this.movingPiece.Square; var piece = this.movingPiece.Piece; BoardMove move = null; if (srcSquare != null) { // 駒の移動の場合 move = BoardMove.CreateMove( piece.BWType, srcSquare, dstSquare, piece.Piece, false); // 成/不成りのダイアログを出す前に着手可能か確認します。 if (!CanMove(move)) { move.IsPromote = true; if (!CanMove(move)) { EndMove(); return; } } // 成れる場合は選択用のダイアログを出します。 if (!move.IsPromote && Board.CanPromote(move)) { var promote = CheckToPromote(piece.PieceType, move.BWType); move.IsPromote = promote; } } else { // 駒打ちの場合 move = BoardMove.CreateDrop( piece.BWType, dstSquare, piece.PieceType); if (!CanMove(move)) { EndMove(); return; } } EndMove(); DoMove(move); }
/// <summary> /// CSA形式の指し手を解析します。 /// </summary> public static BoardMove CsaToMove(this Board board, string csa) { if (board == null) { throw new ArgumentNullException("board"); } if (string.IsNullOrEmpty(csa)) { throw new ArgumentNullException("csa"); } // 特殊な指し手 var smove = board.CsaToSpecialMove(csa); if (smove != null) { return(smove); } // 普通の指し手 var m = MoveRegex.Match(csa); if (!m.Success) { return(null); } var c = m.Groups[1].Value; var side = ( c == "+" ? BWType.Black : c == "-" ? BWType.White : BWType.None); // 移動前の位置 var srcFile = int.Parse(m.Groups[2].Value); var srcRank = int.Parse(m.Groups[3].Value); var srcSquare = (srcFile == 0 || srcRank == 0 ? (Square)null : new Square(srcFile, srcRank)); // 移動後の位置 var dstFile = int.Parse(m.Groups[4].Value); var dstRank = int.Parse(m.Groups[5].Value); var dstSquare = (dstFile == 0 || dstRank == 0 ? (Square)null : new Square(dstFile, dstRank)); // 駒 var piece = CsaUtil.StrToPiece(m.Groups[6].Value); if (piece == null || piece.PieceType == PieceType.None) { return(null); } if (srcSquare == null) { // 駒打ちの場合 return(BoardMove.CreateDrop(side, dstSquare, piece.PieceType)); } else { // 駒の移動の場合、成りの判定を行います。 var srcPiece = board[srcSquare]; if (srcPiece == null || !srcPiece.Validate()) { return(null); } // CSA形式の場合、駒が成ると駒の種類が変わります。 var isPromote = (!srcPiece.IsPromoted && piece.IsPromoted); if (isPromote) { piece = new Piece(piece.PieceType, false); } return(BoardMove.CreateMove(side, srcSquare, dstSquare, piece, isPromote)); } }
public void SerializeTest() { // すべてのマスをテストすると時間がかかりすぎるため、 // 移動元・移動先共にテストするマスを絞っています。 var validMoveList = from turn in new BWType[] { BWType.Black, BWType.White } from dst in Board.AllSquares() from src in Board.AllSquares() from pc in EnumEx.GetValues <PieceType>() from promoted in new bool[] { false, true } from tookPc in EnumEx.GetValues <PieceType>() from tookPromoted in new bool[] { false, true } from promote in new bool[] { false, true } let pcPiece = new Piece(pc, promoted) let tookPiece = (tookPc != PieceType.None ? new Piece(tookPc, tookPromoted) : null) where pcPiece.Validate() where tookPiece == null || tookPiece.Validate() where (dst.Rank % 2) == 1 && (dst.File % 3) == 1 where (src.Rank % 2) == 1 && (src.File % 3) == 1 let bmove = BoardMove.CreateMove( turn, src, dst, pcPiece, promote, tookPiece) where bmove.Validate() select bmove; var validDropList = from turn in new BWType[] { BWType.Black, BWType.White } from dst in Board.AllSquares() from pc in EnumEx.GetValues <PieceType>() where pc != PieceType.None let bmove = BoardMove.CreateDrop(turn, dst, pc) where bmove.Validate() select bmove; var specialMoveList = from turn in new BWType[] { BWType.Black, BWType.White } from special in EnumEx.GetValues <SpecialMoveType>() where special != SpecialMoveType.None let bmove = BoardMove.CreateSpecialMove(turn, special) where bmove.Validate() select bmove; var count = 0; var moveList = validMoveList.Concat(validDropList).Concat(specialMoveList); foreach (var bmove in moveList) { var bytes = PbUtil.Serialize(bmove); Assert.NotNull(bytes); var newMove = PbUtil.Deserialize <BoardMove>(bytes); Assert.NotNull(newMove); Assert.True(newMove.Validate()); Assert.AreEqual(bmove, newMove); // 多くのテストがあるため、一応 if (count++ % 50000 == 0) { Console.WriteLine("BoardMoveTest.SerializeTest testing..."); } } }
/// <summary> /// SFEN形式の指し手を、指し手に変換します。 /// </summary> public static BoardMove SfenToMove(this Board board, string sfen) { if (board == null) { throw new ArgumentNullException("board"); } if (string.IsNullOrEmpty(sfen)) { throw new ArgumentNullException("sfen"); } if (sfen.Length < 4) { return(null); } var dropPieceType = SfenUtil.SfenToPieceType(sfen[0]); if (dropPieceType != PieceType.None) { // 駒打ちの場合 if ((sfen[1] != '*') || (sfen[2] < '1' || '9' < sfen[2]) || (sfen[3] < 'a' || 'i' < sfen[3])) { return(null); } var dstFile = (sfen[2] - '1') + 1; var dstRank = (sfen[3] - 'a') + 1; return(BoardMove.CreateDrop( board.Turn, new Square(dstFile, dstRank), dropPieceType)); } else { // 駒の移動の場合 if ((sfen[0] < '1' || '9' < sfen[0]) || (sfen[2] < '1' || '9' < sfen[2]) || (sfen[1] < 'a' || 'i' < sfen[1]) || (sfen[3] < 'a' || 'i' < sfen[3])) { return(null); } var srcFile = (sfen[0] - '1') + 1; var srcRank = (sfen[1] - 'a') + 1; var dstFile = (sfen[2] - '1') + 1; var dstRank = (sfen[3] - 'a') + 1; var piece = board[srcFile, srcRank]; if (piece == null) { return(null); } var promote = (sfen.Length > 4 && sfen[4] == '+'); return(BoardMove.CreateMove( board.Turn, new Square(srcFile, srcRank), new Square(dstFile, dstRank), piece.Piece, promote, BoardPiece.GetPiece(board[dstFile, dstRank]))); } }