【问题标题】:What is the best way to put 20 pieces on a chessboard in random places?将 20 个棋子放在棋盘上随机位置的最佳方法是什么?
【发布时间】:2009-01-08 03:19:01
【问题描述】:

我必须解决这个问题的一个想法是组成一个大小为 8x8 的缓冲区,用指向我的检查器(全部 20 个)的指针填充它,其余的保留 0(空),然后运行洗牌算法在缓冲区上,仅此而已(只需将其读取为 8x8 数组)

  1. 我想知道是否有更好的方法来做到这一点。
  2. 我需要用 C# 编写它,而我的建议不会按照我描述的方式工作

有人吗?

【问题讨论】:

  • "提案不会像我描述的那样工作" 什么意思?你有一个具体的问题吗?一个不起作用的代码 sn-p?你有一个例子说明什么不能按照你描述的方式工作吗?
  • 这些作品必须遵循它们的正常规则吗?即一位白色和一位黑色方形主教等?
  • @Mitch:好问题!没想到
  • 另外,你暗示使用跳棋和棋子(标题说国际象棋,内容说跳棋)。也就是说,我假设跳棋。
  • S.Lott:我写的东西很有效,但我认为有更聪明的方法。米奇:没有规则,就像我说的,只是在随机的地方填充它们,但全部 20 个。

标签: c# arrays algorithm random


【解决方案1】:

为了借鉴 Borzio 的想法,当您接近第 20 块时,您有三分之一的机会必须重新生成随机数并重试。有 20 件,您可能仍然安全,但如果您有 40 件,那么您的机会将超过二分之一,您可能会被卡住等待一段时间。

  1. 构造板数组,全部为空。
  2. 将每个棋盘格的引用复制到列表 (emptySquareList)。
  3. 为您要添加的每个部分循环:
    1. 0emptySquareList.Length-1 之间生成一个随机数。
    2. 把棋子放在那个正方形里
    3. emptySquareList 中删除正方形。

这样,您始终可以维护一个 方格列表,并从中进行选择。请注意,板数组中的索引数组也可以正常工作,并且可能更快 (Enumerable.Range(0,64))。

我鼓励您尝试随机检查算法以及这个算法;看看哪个效率更高。

【讨论】:

  • 是的,最好保证你的算法退出,即使你运气不好。
【解决方案2】:

包含指向片段对象的指针 (c++) 或引用 (c#/java) 的 8x8 矩阵似乎是一个非常合理的设计。

您可以使用 64 个元素大的一维数组(您可以轻松地将二维索引映射到一维数组)并使用如下内容:

using System;
using System.Linq;

Piece[] board = whatever();

// New random number generator.
Random random = new Random();

// LINQ query orders each element by the next random number.
Piece[] randomBoard = (from piece in board
    orderby random.Next()
    select piece).ToArray();

注意:我不是 c# 程序员,但这似乎是合理的。

要将 x,y 对转换为数组索引,请使用以下算法:

int index = (y * 8) + x;

注意2:我不知道你是否必须遵循跳棋的放置规则,如果你这样做,你需要做一些更聪明的事情。您可能有一个 32 个元素大的数组(代表所有黑色方块)。在其中随机播放,然后将 32 大数组中的每个元素分配给真正的 64 元素数组的每个“黑色”方块。

【讨论】:

    【解决方案3】:

    回答提出的问题:

    1. 将第一个棋子放在尚未被占用的随机位置
    2. 重复其他 19 件

    说真的,您根本没有给我们足够的信息来继续回答这个问题。这里有一些问题:

    • 哪些棋子?
    • 哪些颜色(每种颜色有 16 种),颜色是否重要?白人是否必须避免被黑人俘虏,反之亦然?

    假设没有要遵循的规则,除了您需要将所有 20 个都放在板上,即。没有冲突,这会做你想做的:

    Piece[] pieces = ... your 20 pieces here
    Piece[] board = new Piece[8 * 8];
    Random r = new Random();
    foreach (Piece piece in pieces)
    {
        while (true)
        {
            Int32 location = r.Next(board.Length);
            if (board[location] == null)
            {
                board[location] = piece;
                break;
            }
        }
    }
    

    如果您在某处已经有辅助例程,一个更简单的解决方案是将它们放在 64 元素数组的开头,然后将整个数组打乱。这会将这 20 个棋子和 44 个空方格打乱,并将它们有效地放置在随机位置。

    【讨论】:

    • 这种算法的问题在于它是不确定的。如果你碰巧特别倒霉,它可能永远不会结束。
    • 如果 Random 真的是随机的,那么是的,而且你非常非常不走运。不幸的是(对于您的评论),在这种情况下,Random 会产生 0 到 63 之间的所有数字,而不管起始种子是什么。
    【解决方案4】:

    如果您必须遵循放置规则,给定您的 8x8 矩阵示例,我也会将其视为 Evan 指出的一维数组——(请参阅他的数学以确定 x 和 y)——

    黑白方块是奇偶索引值;但是,嘿,你从来没有说过你需要放置规则——我还假设你不是在寻找 c# 代码,而是更多“逻辑”级别的想法......

    如果您正在尝试 Linq-Challenged 解决方案,请考虑以下事项;

    1. 构造“board”数组,全部为空; (64 个元素)
    2. 构建由您的棋子组成的“游戏棋子”数组
    3. 创建一个从 1 到 # 个片段的循环
    4. 生成一个介于 1 和 # 个棋盘空间 (64) 之间的随机数
    5. 如果 #4 指向的电路板空间是 !0,重做第 4 步(或者您可以“while” !0)
    6. 将块(步骤 3 中的循环中的#)放入步骤 4 中的正方形 X

    只有一个想法,肯定会很多——

    希望对你有帮助...

    【讨论】:

      猜你喜欢
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多