我正在尝试通过一项任务提高自己的概率,但无法弄清楚: 在西洋双陆棋游戏中,我有四行(动态)布局。
假设第 5、7、11、13 行。我正在 throw 动态数量的骰子。我试图找到每个游戏玩法的概率。例如:
我掷了 4 个骰子,结果是 1,3,4,6
所以
我可以从 5.row-1,3,4,6 骰子开始玩
我可以从 5. row-1,3,4 骰子和 7. row-6 骰子玩
我可以从 5. row-3,1 骰子和 11. row-6 骰子和 13. row-4 骰子玩 等等等等
骰子必须是动态的,行必须是动态的,骰子可以像 1,3,4,6 或 6,1,4,3 或 3,1,6,4 一样混合玩。它必须计算分布在行上的不同骰子变化的所有可能性。
简单地说,我正在尝试计算玩无限骰子西洋双陆棋的可能性。我正在尝试使用它来获得可调整大小的可能移动类的方法,并且在此类内部,有可调整大小的行类。在 rows 类中,有可调整大小的 List moves 变量。我为每个变体添加一个 Action 。这是非动态 4 骰子的代码。
public List<int> dice;
public List<int> places;
[System.Serializable]
public class arrayData
{
public List<arrayData2> places = new List<arrayData2>();
}
public List<arrayData> pos = new List<arrayData>();
[System.Serializable]
public class arrayData2
{
public List<int> moves = new List<int> {};
}
void Start()
{
vs();
}
void vs()
{
for (int i = 0; i < places.Count; i++)
{
for (int a = 0; a < dice.Count; a++)
{
for (int b = 0; b < dice.Count; b++)
{
for (int c = 0; c < dice.Count; c++)
{
for (int d = 0; d < dice.Count; d++)
{
if (a == b || a == c || a == d || b == c || b == d || c == d)
{
continue;
}
pos.Add(new arrayData());
for (int s = 0; s < places.Count; s++)
{
pos[pos.Count - 1].places.Add(new arrayData2());
}
pos[pos.Count - 1].places[i].moves.Add(dice[a]);
pos[pos.Count - 1].places[i].moves.Add(dice[b]);
pos[pos.Count - 1].places[i].moves.Add(dice[c]);
pos[pos.Count - 1].places[i].moves.Add(dice[d]);
}
}
}
}
}
}
我想不通的是:
-首先,我试图使它成为一个递归循环,但我无法弄清楚结构
-其次,输出为我提供了行间分布变化的缺失值:它给出了这样的值:5. row-1,3,4,6 dices 但不是这样的值:5. row-3,1骰子和来自 11. row-6 骰子和来自 13. row-4 骰子
我知道这是一个很大的问题,但任何形式的指出错误或正确指导的方式都将不胜感激。
谢谢
最佳答案
将您的 Action 视为 game tree 的一部分可能会很有用.基本思想是所有游戏都以特定状态开始。我们称它为 x
。然后移动将游戏状态更改为 x1
,下一个移动为 x2
,依此类推。大多数 Action 都涉及选择,并且根据所做的选择,每个 Action 都会将游戏推向不同的状态。从起始状态开始,所有可能的 Action 形成一棵巨大的树。这很方便,因为我们可以使用 tree traversal algorithms探索我们的树。这就是递归的用武之地。
西洋双陆棋在概念上比国际象棋或西洋跳棋等游戏要复杂一些,因为您必须考虑骰子的随机性以及对手的行为。这在移动过程中增加了更多选择。在伪代码中,我可能会这样解决问题:
function get_next_move (current_state):
dice = roll_dice()
possible_states = an empty collection
get_possible_states (dice, current_state, possible_states)
return decide_best_state (possible_states)
function get_possible_states (dice, state, possible_states):
// If we've exhausted all dice, we're done.
// Add the state we've reached to our possible outcomes.
if dice are empty:
add state to possible_states
return
for each die in dice:
dice_without_die = remove die from dice
for each next_state in get_legal_states (state, die):
// Here's the recursion. Go a level deeper in our tree.
get_possible_states (dice_without_die , next_state, possible_states)
function get_legal_states (state, die):
// Here's where you determine legal moves based on the
// die rolled and the current state of the game.
换句话说,为了确定我的下一步行动,我必须:
- 掷骰子。
- 随着每个骰子的滚动,生成其所有合法移动(状态)。
- 使用新状态重复该过程,但不要使用已使用的骰子。
- 当没有剩余的骰子时,将最终状态添加到可能状态列表中。
- 最后,确定哪一步是最好的。请记住,某些生成的状态可能是重复的。将您的作品移动到相同位置的方法不止一种。
这种方法的好处是没有硬编码的数字。它可以处理任意数量的合法移动或骰子。 (虽然我不确定西洋双陆棋何时会使用可变数量的骰子。)我遗漏的一个细节是你需要知道轮到谁了。合法的举措将取决于谁在制定这些举措。
关于c# - 递归嵌套循环c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24906708/