Skip to content

Commit

Permalink
feat: 完成移動棋子的測試
Browse files Browse the repository at this point in the history
Co-authored-by: jaychou2211 <[email protected]>
Co-authored-by:  miku3920 <[email protected]>
Co-authored-by: Rick Su <[email protected]>
  • Loading branch information
4 people committed May 7, 2024
1 parent 51a34d3 commit 7b4ab4a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 28 deletions.
63 changes: 55 additions & 8 deletions src/ChineseCheckers.Domain/Board.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,45 +196,92 @@ public void SetPieceColor(int x, int y, PieceColor color)
_board[x, y] = (int)color;
}

public bool IsValidMove(int fromX, int fromY, int toX, int toY)
public bool IsValidMoves(Point[] moves)
{
MoveType lastMove;
for (int i = 0; i < moves.Length - 1; i++)
{
lastMove = IsValidMove(moves[i].X, moves[i].Y, moves[i + 1].X, moves[i + 1].Y);
if (lastMove == MoveType.Error)
{
return false;
}
}
return true;
}

public enum MoveType
{
OneStep, Jump, Error
}

public MoveType IsValidMove(int fromX, int fromY, int toX, int toY)
{
// 檢查是否超出絕對邊界
if (toX < 0 || toX > 16 || toY < 0 || toY > 16)
{
return false;
return MoveType.Error;
}

// From 必須要有棋子
if (_board[fromX, fromY] <= (int)PieceColor.None)
{
return false;
return MoveType.Error;
}

// To 必須是空位
if (_board[toX, toY] != (int)PieceColor.None)
{
return false;
return MoveType.Error;
}

// 檢查是否為一步移動
if (Math.Abs(fromX - toX) is 0 or 1 && Math.Abs(fromY - toY) is 0 or 1)
var isOneStep = (fromX - toX, fromY - toY) switch
{
// 左上
(1, 1) => true,
// 右上
(0, 1) => true,
// 右
(-1, 0) => true,
// 右下
(-1, -1) => true,
// 左下
(0, -1) => true,
// 左
(1, 0) => true,
// 排除不合法的跳躍
_ => false
};

if (isOneStep)
{
return true;
return MoveType.OneStep;
}

// 檢查是否為跳躍移動
if (Math.Abs(fromX - toX) is 0 or 2 && Math.Abs(fromY - toY) is 0 or 2)
{
// 排除不合法的跳躍
if (fromX - toX == 2 && fromY - toY == -2)
{
return MoveType.Error;
}
if (fromX - toX == -2 && fromY - toY == 2)
{
return MoveType.Error;
}

int middleX = (fromX + toX) / 2;
int middleY = (fromY + toY) / 2;

if (_board[middleX, middleY] > (int)PieceColor.None)
{
return true;
return MoveType.Jump;
}
}

return false;
return MoveType.Error;
}
}

13 changes: 5 additions & 8 deletions src/ChineseCheckers.Domain/Game.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@

using System.Runtime.Serialization;

namespace ChineseCheckers.Domain;

public class Game
Expand Down Expand Up @@ -33,16 +30,16 @@ public void Start()
_board.Initialize(_players.Count);
}

public void MoveChess(int sx, int sy, int dx, int dy)
public void MoveChess(Point[] moves)
{
if (_board.IsValidMove(sx, sy, dx, dy) == false)
if (_board.IsValidMoves(moves) == false)
{
throw new InvalidMoveException("Invalid Move");
}

var tmp = _board.GetPieceColor(sx, sy);
_board.SetPieceColor(sx, sy, _board.GetPieceColor(dx, dy));
_board.SetPieceColor(dx, dy, tmp);
var tmp = _board.GetPieceColor(moves[0].X, moves[0].Y);
_board.SetPieceColor(moves[0].X, moves[0].Y, PieceColor.None);
_board.SetPieceColor(moves[^1].X, moves[^1].Y, tmp);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/ChineseCheckers.Domain/Point.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
namespace ChineseCheckers.Domain;
public record Point(int X, int Y);
24 changes: 12 additions & 12 deletions tests/ChineseCheckers.Tests/MoveChessTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public void CanMoveChessButtomRight()
.Build();

// Act
game.MoveChess(4, 0, 5, 1);
game.MoveChess([new Point(4, 0), new Point(5, 1)]);

// Assert
game.Board.GetPieceColor(4, 0).Should().Be(PieceColor.None);
Expand All @@ -99,7 +99,7 @@ public void CanMoveChessButtomLeft()
.Build();

// Act
game.MoveChess(4, 0, 4, 1);
game.MoveChess([new Point(4, 0), new Point(4, 1)]);

// Assert
game.Board.GetPieceColor(4, 0).Should().Be(PieceColor.None);
Expand All @@ -109,7 +109,7 @@ public void CanMoveChessButtomLeft()
[Description("""
Given: (4, 0) is red, (5, 1) is red, (6, 2) is none
When: (4, 0) jump to (6, 2)
Then: InvalidMoveException
Then: Success
""")]
[TestMethod]
public void CanJumpChessButtomRight()
Expand All @@ -124,7 +124,7 @@ public void CanJumpChessButtomRight()
.Build();

// Act
var act = () => game.MoveChess(4, 0, 6, 2);
game.MoveChess([new Point(4, 0), new Point(6, 2)]);

// Assert
game.Board.GetPieceColor(4, 0).Should().Be(PieceColor.None);
Expand All @@ -150,7 +150,7 @@ public void CanNotJumpChessButtomRightWhenMiddleNone()
.Build();

// Act
var act = () => game.MoveChess(4, 0, 6, 2);
var act = () => game.MoveChess([new Point(4, 0), new Point(6, 2)]);

// Assert
act.Should().Throw<InvalidMoveException>();
Expand All @@ -172,14 +172,14 @@ public void CanNotMoveChessButtom()
.Build();

// Act
var act = () => game.MoveChess(4, 0, 5, 2);
var act = () => game.MoveChess([new Point(4, 0), new Point(5, 2)]);

// Assert
act.Should().Throw<InvalidMoveException>();
}

[Description("""
Given: (4, 3) is red
Given: (4, 3) is red, (5, 2) is none
When: (4, 3) move to (5, 2)
Then: InvalidMoveException
""")]
Expand All @@ -190,11 +190,12 @@ public void CanNotMoveChessTopRightRight()
var game = new GameBuilder()
.WithPlayers("Player 1", "Player 2")
.WithBoard(4, 3, PieceColor.Red)
.WithBoard(5, 2, PieceColor.None)
.Started(true)
.Build();

// Act
var act = () => game.MoveChess(4, 3, 5, 2);
var act = () => game.MoveChess([new Point(4, 3), new Point(5, 2)]);

// Assert
act.Should().Throw<InvalidMoveException>();
Expand All @@ -216,7 +217,7 @@ public void CanNotMoveChessTopLeftLeft()
.Build();

// Act
var act = () => game.MoveChess(7, 3, 5, 2);
var act = () => game.MoveChess([new Point(7, 3), new Point(5, 2)]);

// Assert
act.Should().Throw<InvalidMoveException>();
Expand All @@ -239,7 +240,7 @@ public void CanNotJumpChessTopRightRight()
.Build();

// Act
var act = () => game.MoveChess(3, 4, 5, 2);
var act = () => game.MoveChess([new Point(3, 4), new Point(5, 2)]);

// Assert
act.Should().Throw<InvalidMoveException>();
Expand All @@ -261,10 +262,9 @@ public void CanNotMoveChessButtomLeftAfterJumpChess()
.WithBoard(6, 2, PieceColor.None)
.Started(true)
.Build();
game.MoveChess(4, 0, 6, 2);

// Act
var act = () => game.MoveChess(6, 2, 6, 3);
var act = () => game.MoveChess([new Point(4, 0), new Point(6, 2), new Point(6, 3)]);

// Assert
act.Should().Throw<InvalidMoveException>();
Expand Down

0 comments on commit 7b4ab4a

Please sign in to comment.