我的家人和我一起玩Mancala很开心,我真的很喜欢它简单的规则,但有几个问题,比如“最高可能得分是多少”。我认为这将是一个有趣的小项目,在Rust中实现,但我陷入了困境,需要帮助。
有许多Mancala玩法的规则。我想要实现这个版本:https://www.youtube.com/watch?v=-A-djjimCcM。了解游戏规则可以更容易理解我的问题,但这可能不是必须的。
这是Mancala棋盘的样子:
有许多Mancala玩法的规则。我想要实现这个版本:https://www.youtube.com/watch?v=-A-djjimCcM。了解游戏规则可以更容易理解我的问题,但这可能不是必须的。
这是Mancala棋盘的样子:
| |04|04|04|04|04|04| |
|00|-----------------|00|
| |04|04|04|04|04|04| |
每个数字表示一个孔,较大方框左右两侧的数字表示“曼卡拉”。曼卡拉基本上是一个用于计算得分的洞。右侧的曼卡拉是您自己的曼卡拉,左侧的是对手的曼卡拉。数字表示该特定孔中弹珠的数量。
在游戏中,您可以选择一个孔,取出所有弹珠,然后在接下来的每个孔/曼卡拉中放置一个弹珠,直到您用尽弹珠为止。跳过对手的曼卡拉。这就是我正在努力解决的问题。
我的解决方法是:曼卡拉板是一个包含四个存储孔的数组的结构体。对于玩家一侧的每个孔和他们的曼卡拉分别有一个数组。我想将这三个Holes数组连接在一起并循环遍历,以便我可以在这些Holes上运行相关函数(跳过对手的曼卡拉)。以下是我的代码:
pub const STARTING_MARBLES: i8 = 4;
pub const NO_OF_HOLES_OF_EACH_PLAYER: usize = 6;
// There can be two players
#[derive(Debug, Copy, Clone)]
pub enum Player {
A,
B,
}
// A dip in a mancala board that can contain a number of marbles
#[derive(Debug, Copy, Clone)]
struct Hole {
marbles: i8,
}
impl Hole {
// Adds x marbles to the hole
fn add_x(&mut self, x: i8) {
self.marbles += x;
}
// Takes all marbles from the hole and returns their number
fn take_all(&mut self) -> i8 {
let marbles = self.marbles;
self.marbles = 0;
marbles
}
// Returns the number of marbles in the hole
fn count(&self) -> i8 {
self.marbles
}
}
// A mancala board with all its holes and mancalas to count the players points
#[derive(Debug, Copy, Clone)]
pub struct Board {
holes_a: [Hole; NO_OF_HOLES_OF_EACH_PLAYER],
holes_b: [Hole; NO_OF_HOLES_OF_EACH_PLAYER],
mancala_a: [Hole; 1],
mancala_b: [Hole; 1],
}
impl Board {
// Create, initialize and return a new mancala board
pub fn new() -> Self {
let init_hole = Hole {
marbles: STARTING_MARBLES,
};
let holes_a = [init_hole; NO_OF_HOLES_OF_EACH_PLAYER];
let holes_b = [init_hole; NO_OF_HOLES_OF_EACH_PLAYER];
let mancala_a = [Hole { marbles: 0 }];
let mancala_b = [Hole { marbles: 0 }];
Board {
holes_a,
holes_b,
mancala_a,
mancala_b,
}
}
// Take all marbles from the chosen hole and add them to the following holes and the player's mancala
// player: Player whos turn it is
// no: number of the selected hole. The numbering starts with 0 on the very left hole of the player whos turn it is
pub fn choose_hole(mut self, player: Player, no: usize) {
let (mut players_own_holes, other_players_holes, players_mancala) = match player {
Player::A => (self.holes_a, self.holes_b, self.mancala_a),
Player::B => (self.holes_b, self.holes_a, self.mancala_b),
};
let marbles_to_spend = players_own_holes[no].take_all() as usize;
let holes_iter = self
.holes_a
.iter_mut()
.chain(self.mancala_a.iter_mut())
.chain(self.holes_b.iter_mut())
.cycle()
.skip(no + 1)
.take(marbles_to_spend);
for mut hole in holes_iter {
hole.add_x(1);
}
}
}
然而,我遇到了以下错误:
error[E0277]: the trait bound `std::slice::IterMut<'_, Hole>: Clone` is not satisfied
--> src/lib.rs:75:14
|
75 | .cycle()
| ^^^^^ the trait `Clone` is not implemented for `std::slice::IterMut<'_, Hole>`
|
= note: required because of the requirements on the impl of `Clone` for `std::iter::Chain<std::iter::Chain<std::slice::IterMut<'_, Hole>, std::slice::IterMut<'_, Hole>>, std::slice::IterMut<'_, Hole>>`
note: required by a bound in `cycle`
--> /home/batman/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:3262:23
|
3262 | Self: Sized + Clone,
| ^^^^^ required by this bound in `cycle`
我还尝试使用into_iter()
方法,但没有出现错误,然而孔的值没有发生改变。我想一个副本被创建并且该方法在副本上运行,然后副本超出了范围,看起来好像什么也没有改变。