-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChess.sol
131 lines (119 loc) · 3.77 KB
/
Chess.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "./ChessBoard.sol";
import "./Player.sol";
contract ChessGame {
address public owner;
enum GAME_STATUS {
PAUSED,
ACTIVE,
BLACK_WIN,
WHITE_WIN,
FORFEIT,
STALEMATE,
RESIGNED
}
GAME_STATUS gameStatus;
Player[2] public player;
uint256 playerTurnIdx;
ChessBoard public chessBoard;
address public resignedBy;
uint256 public startedAt;
modifier isValidCoor(uint256 _x, uint256 _y) {
require(_x >= 0 && _x < 8 && _y >= 0 && _y < 8, "INVALID CORD");
_;
}
constructor(address player1, address player2) {
player[0] = new Player(player1, true);
player[1] = new Player(player2, false);
playerTurnIdx = 0;
chessBoard = new ChessBoard(player);
startedAt = block.timestamp;
owner = msg.sender;
gameStatus = GAME_STATUS.PAUSED;
}
function startGame() public {
require(msg.sender == owner, "action not allowed");
require(gameStatus >= GAME_STATUS.ACTIVE, "game already started");
gameStatus = GAME_STATUS.ACTIVE;
}
function moveAPiece(
uint256 sx,
uint256 sy,
uint256 ex,
uint256 ey
) public isValidCoor(sx, sy) isValidCoor(ex, ey) {
require(gameStatus == GAME_STATUS.ACTIVE, "Game not started yet");
require(
player[playerTurnIdx].getPlayerAddress() == msg.sender,
"You are not a game participant or not your turn"
);
Piece pieceAtS = chessBoard.getPiecesAtCoor(sx, sy);
require(pieceAtS != Piece(address(0)), "select piece to move");
Piece pieceAtE = chessBoard.getPiecesAtCoor(ex, ey);
if (
pieceAtS.canMove(
pieceAtS,
pieceAtE,
ex,
ey,
player[playerTurnIdx],
chessBoard
)
) {
if (pieceAtE != Piece(address(0))) {
pieceAtE.setKilled(
true,
player[(playerTurnIdx + 1) % 2],
pieceAtE
);
}
chessBoard.move(pieceAtS, ex, ey);
//after each move check is this checkmate condition for opponent
(bool checkmate, Piece byPiece) = chessBoard.checkmateCheck(
player,
(0 == playerTurnIdx),
chessBoard
);
if (checkmate) {
if (
chessBoard.resolveCheckMate(
player[0],
player[1],
(0 == playerTurnIdx),
chessBoard
)
) {
// emit event regarding checkmate here byPiece
} else {
// emit opponent lost the game
}
}
// switch turn
playerTurnIdx = (playerTurnIdx + 1) % 2;
} else revert("Invalid Move");
}
function getPieceAtIndex(uint256 _x, uint256 _y)
public
view
returns (Piece)
{
return chessBoard.getPiecesAtCoor(_x, _y);
}
function getPlayerColor(uint256 _x, uint256 _y) public view returns (bool) {
return getPieceAtIndex(_x, _y).isWhite();
}
function resignGame() public {
require(
(player[0].getPlayerAddress() == msg.sender ||
player[1].getPlayerAddress() == msg.sender),
"Action not allowed"
);
require(
gameStatus == GAME_STATUS.ACTIVE,
"game already over or didn't started"
);
resignedBy = msg.sender;
gameStatus = GAME_STATUS.RESIGNED;
}
}