我刚开始这个项目,我一直坚持如何实现我的ChessBoard类。我想要的是我的std::vector<std::vector<ChessPiece*>>
存储从它派生的类型的对象(特定的棋子)。
查看ChessBoard类中std::vector<std::vector<ChessPiece*>> board
的赋值。
#include <iostream>
#include <string>
#include <vector>
enum class COLOR
{
BLACK,
WHITE,
NOTHING
};
class ChessPiece
{
protected:
COLOR color;
public:
ChessPiece() = default;
ChessPiece(COLOR c) : color{ c } {}
COLOR get_color() const { return color; }
friend std::ostream& operator<<(std::ostream& out, const ChessPiece piece)
{
if (piece.color == COLOR::BLACK)
return out << '-';
if (piece.color == COLOR::WHITE)
return out << '+';
}
};
class King : public ChessPiece
{
private:
bool moved;
public:
King() = default;
King(COLOR c) { color = c; }
void set_moved(bool b) { moved = b; }
bool has_moved() { return moved; }
};
class Queen : public ChessPiece
{
private:
public:
Queen() = default;
Queen(COLOR c) { color = c; }
};
class Bishop : public ChessPiece
{
private:
public:
Bishop() = default;
Bishop(COLOR c) { color = c; }
};
class Knight : public ChessPiece
{
private:
public:
Knight() = default;
Knight(COLOR c) { color = c; }
};
class Rook : public ChessPiece
{
private:
bool moved;
public:
Rook() = default;
Rook(COLOR c) { color = c; }
void set_moved(bool b) { moved = b; }
bool has_moved() { return moved; }
};
class Pawn : public ChessPiece
{
private:
public:
Pawn() = default;
Pawn(COLOR c) { color = c; }
};
class Board
{
private:
std::vector<std::vector<ChessPiece*>> board[8][8];
Pawn white_pawn1(COLOR::WHITE), white_pawn2, white_pawn3, white_pawn4, white_pawn5, white_pawn6, white_pawn7, white_pawn8;
Rook white_rook1, white_rook2;
Knight white_knight1, white_knight2;
Bishop white_bishop1, white_bishop2;
Queen white_queen;
King white_king;
Pawn black_pawn1, black_pawn2, black_pawn3, black_pawn4, black_pawn5, black_pawn6, black_pawn7, black_pawn8;
Rook black_rook1, black_rook2;
Knight black_knight1, black_knight2;
Bishop black_bishop1, black_bishop2;
Queen black_queen;
King black_king;
public:
Board(std::string color)
{
if (color == "white")
{
**board =
{
{ &black_rook1, &black_knight1, &black_bishop1, &black_queen, &black_king, &black_bishop2, &black_knight2, &black_rook2 },
{ &black_pawn1, &black_pawn2, &black_pawn3, &black_pawn4, &black_pawn5, &black_pawn6, &black_pawn7, &black_pawn8 },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ &white_pawn1, &white_pawn2, &white_pawn3, &white_pawn4, &white_pawn5, &white_pawn6, &white_pawn7, &white_pawn8 },
{ &white_rook1, &white_knight1, &white_bishop1, &white_queen, &white_king, &white_bishop2, &white_knight2, &white_rook2 }
};
}
if (color == "black")
{
**board =
{
{ &white_rook1, &white_knight1, &white_bishop1, &white_queen, &white_king, &white_bishop2, &white_knight2, &white_rook2 },
{ &white_pawn1, &white_pawn2, &white_pawn3, &white_pawn4, &white_pawn5, &white_pawn6, &white_pawn7, &white_pawn8 },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ &black_pawn1, &black_pawn2, &black_pawn3, &black_pawn4, &black_pawn5, &black_pawn6, &black_pawn7, &black_pawn8 },
{ &black_rook1, &black_knight1, &black_bishop1, &black_queen, &black_king, &black_bishop2, &black_knight2, &black_rook2 }
};
}
}
void print_board()
{
std::cout << "\ta\tb\tc\td\te\tf\tg\th\n1\t";
for (int i = 0; i != 8; ++i)
{
for (int j = 0; j != 8; ++j)
{
if (board[i][j] == nullptr)
std::cout << '#' << std::endl;
std::cout << board[i][j] << '\t';
}
std::cout << std::endl;
if (i != 7)
std::cout << i + 2 << '\t';
}
}
~Board() = default;
};
class Game
{
private:
bool won;
bool lost;
public:
bool is_over();
void update(std::string);
};
int main()
{
std::cout << "white or black:\n";
std::string color;
std::cin >> color;
// Start game with your given color on the bottom.
// TODO throw exception if user enters an invalid color.
Game game(color);
std::string move;
while (!game.is_over())
{
std::cin >> move;
game.update(move);
}
system("pause");
return 0;
}
Rook* white_rook1, white_rook2;
不等于
Rook* white_rook1;
Rook* white_rook2;
但
Rook* white_rook1;
Rook white_rook2; // not a pointer !!!
(所有其他类似的行相同) 这就是operator =无法匹配的原因。
此外,你不必在这里使用std::vector
:你的棋盘在比赛期间不会增长或缩小(除非你有特殊规则:))。请改用std::array
。
您应该注意,您的代码中没有任何指针被初始化。正如Galik所建议的那样,最好更换对象并将其地址存储在board
中。
您不创建任何实际对象。到目前为止,你所有的指针都是晃来晃去。除了你的棋盘之外,你还有一整套游戏棋子指针作为成员。
最好使用&
(运算符地址)将您的片段成员设为实际对象而不是指针并将其地址放入您的板中。
class Board
{
private:
std::vector<std::vector<ChessPiece*>> board;
// make these non-pointers (many of them already were)
// and give their address to the board
Pawn white_pawn1, white_pawn2, white_pawn3, white_pawn4, white_pawn5, white_pawn6, white_pawn7, white_pawn8;
Rook white_rook1, white_rook2;
Knight white_knight1, white_knight2;
Bishop white_bishop1, white_bishop2;
Queen white_queen;
King white_king;
Pawn black_pawn1, black_pawn2, black_pawn3, black_pawn4, black_pawn5, black_pawn6, black_pawn7, black_pawn8;
Rook black_rook1, black_rook2;
Knight black_knight1, black_knight2;
Bishop black_bishop1, black_bishop2;
Queen black_queen;
King black_king;
public:
Board(std::string color)
{
if (color == "white")
{
board =
{ // NOTE the use of & to take their address aand obtain a pointer
{ &black_rook1, &black_knight1, &black_bishop1, &black_queen, &black_king, &black_bishop2, &black_knight2, &black_rook2 },
{ &black_pawn1, &black_pawn2, &black_pawn3, &black_pawn4, &black_pawn5, &black_pawn6, &black_pawn7, &black_pawn8 },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ &white_pawn1, &white_pawn2, &white_pawn3, &white_pawn4, &white_pawn5, &white_pawn6, &white_pawn7, &white_pawn8 },
{ &white_rook1, &white_knight1, &white_bishop1, &white_queen, &white_king, &white_bishop2, &white_knight2, &white_rook2 }
};
}
通过制作适当的物品,它们可以保持个别状态,您不必担心创建和销毁它们 - 只需将它们移动到板上(或上下)。
我也会考虑使用std::array<std::array<ChessPiece*>, 8>, 8>
而不是矢量。但这将使你的Board
对象更大。
我认为你没有通过使用矢量得到任何东西,你可以使用2D数组。喜欢:
#include <iostream>
#include <string>
#include <vector>
class EmptySquare : public ChessPiece
{
private:
public:
};
class King : public ChessPiece
{
private:
public:
};
class Queen : public ChessPiece
{
private:
public:
};
class Bishop : public ChessPiece
{
private:
public:
};
class Knight : public ChessPiece
{
private:
public:
};
class Rook : public ChessPiece
{
private:
public:
};
class Pawn : public ChessPiece
{
private:
public:
};
enum class COLOR
{
BLACK,
WHITE,
NOTHING
};
class ChessPiece
{
private:
COLOR color;
public:
COLOR get_color();
};
class Board
{
private:
ChessPiece* board[8][8];
Pawn white_pawn1(COLOR(WHITE)), white_pawn2, white_pawn3, white_pawn4, white_pawn5, white_pawn6, white_pawn7, white_pawn8;
Rook white_rook1, white_rook2;
Knight white_knight1, white_knight2;
Bishop white_bishop1, white_bishop2;
Queen white_queen;
King white_king;
Pawn black_pawn1, black_pawn2, black_pawn3, black_pawn4, black_pawn5, black_pawn6, black_pawn7, black_pawn8;
Rook black_rook1, black_rook2;
Knight black_knight1, black_knight2;
Bishop black_bishop1, black_bishop2;
Queen black_queen;
King black_king;
public:
Board(std::string color)
{
if (color == "white")
{
ChessPiece* l_board[8][8] =
{
{ &black_rook1, &black_knight1, &black_bishop1, &black_queen, &black_king, &black_bishop2, &black_knight2, &black_rook2 },
{ &black_pawn1, &black_pawn2, &black_pawn3, &black_pawn4, &black_pawn5, &black_pawn6, &black_pawn7, &black_pawn8 },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ &white_pawn1, &white_pawn2, &white_pawn3, &white_pawn4, &white_pawn5, &white_pawn6, &white_pawn7, &white_pawn8 },
{ &white_rook1, &white_knight1, &white_bishop1, &white_queen, &white_king, &white_bishop2, &white_knight2, &white_rook2 }
};
memcpy(board, l_board, sizeof(ChessPiece*) *8 *8);
}
if (color == "black")
{
ChessPiece* l_board[8][8] =
{
{ &white_rook1, &white_knight1, &white_bishop1, &white_queen, &white_king, &white_bishop2, &white_knight2, &white_rook2 },
{ &white_pawn1, &white_pawn2, &white_pawn3, &white_pawn4, &white_pawn5, &white_pawn6, &white_pawn7, &white_pawn8 },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
{ &black_pawn1, &black_pawn2, &black_pawn3, &black_pawn4, &black_pawn5, &black_pawn6, &black_pawn7, &black_pawn8 },
{ &black_rook1, &black_knight1, &black_bishop1, &black_queen, &black_king, &black_bishop2, &black_knight2, &black_rook2 }
};
memcpy(board, l_board, sizeof(ChessPiece*) *8 *8);
}
}
void print_board();
~Board();
};
class Game
{
private:
bool won;
bool lost;
public:
bool is_over();
void update(std::string);
};
int main()
{
std::cout << "white or black:\n";
std::string color;
std::cin >> color;
// Start game with your given color on the bottom.
// TODO throw exception if user enters an invalid color.
Game game(color);
std::string move;
while (!game.is_over())
{
std::cin >> move;
game.update(move);
}
system("pause");
return 0;
}