public void MoveBlackTest1() { var board = MakeBoard1(BWType.Black); var move = BoardMove.CreateMove( BWType.Black, new Square(8, 3), new Square(8, 2), new Piece(PieceType.Kyo, false), true); Assert.True(board.CanMove(move)); // 駒が設定されてないと動けません。 MethodUtil.SetPropertyValue(move, "MovePiece", new Piece()); Assert.False(board.CanMove(move)); MethodUtil.SetPropertyValue(move, "MovePiece", new Piece(PieceType.Kyo, false)); // 84の駒は移動できません。 MethodUtil.SetPropertyValue(move, "SrcSquare", new Square(8, 4)); Assert.False(board.CanMove(move)); MethodUtil.SetPropertyValue(move, "SrcSquare", new Square(8, 3)); CanMoveTo(board, move, new List <Tuple <Square, bool> > { Tuple.Create(new Square(8, 2), false), Tuple.Create(new Square(8, 1), true), }); }
/// <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); }
public void MoveWhiteTest1() { var board = MakeBoard1(BWType.White); var move = BoardMove.CreateMove( BWType.White, new Square(9, 7), new Square(9, 8), new Piece(PieceType.Hu, false), true); Assert.True(board.CanMove(move)); // 84の駒は移動できません。 MethodUtil.SetPropertyValue(move, "SrcSquare", new Square(8, 4)); Assert.False(board.CanMove(move)); MethodUtil.SetPropertyValue(move, "SrcSquare", new Square(9, 7)); CanMoveTo(board, move, new List <Tuple <Square, bool> > { Tuple.Create(new Square(9, 8), false), }); }
/// <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]))); } }