【发布时间】:2013-10-24 21:16:17
【问题描述】:
我想知道如何创建一个值从 1111 开始一直到 8888 的数组。我问这个是因为我需要生成一个 4 位数字的列表,每个数字的范围是 1-8。我想把它做成一个循环形式。此外,我在以下程序中迷失了函数 trim、methodicalEliminate、guessAndEliminate 和 guessThreeThenEliminate。以下是路线:
本作业侧重于在程序中使用数组,包括将数组用作函数的参数。
问题描述 在 Mastermind 游戏中,玩家只获得有限次数的猜测来尝试识别隐藏的组合(例如 12 次猜测)。通常这是玩游戏的唯一限制。 但是有些玩家可能会互相竞争,看谁能在更少的尝试中猜出对方的组合。在这种情况下,问题不仅在于提出一种可以在指定范围内找到答案的策略,还在于找到一种可能需要最少猜测次数的策略。
这就是计算机的用武之地——人们可以编写一个程序来尝试不同的猜测策略,然后看看它们是如何工作的。由于计算机可以比人更快地进行分析和计算,它可以使用我们选择的任何策略假装代表我们玩 Mastermind,并告诉我们这样做需要多长时间。
整体解决方案
当然,教计算机按照与人相同的思路进行推理是极其困难的。例如,如果我们猜出一个组合 1111 并得到一个黑色钉子,我们会在心里记下答案中正好有一个 1,然后在记住这一事实的情况下继续进行其他猜测。如果我们接下来猜测 1222 并得到一个白色钉子,我们会知道没有 2,并且单个 1 不在第一个位置。但是如何在一系列猜测之后跟踪这些信息将是相当困难的。
幸运的是,对于带有数组的计算机模拟,我们可以以不同的方式记录所有已知事实。我们只是维护一个可能存在的所有可能答案的列表,然后从列表中删除不再是解决方案的数字。如果我们的第一个猜测告诉我们恰好有一个 1 数字,我们将删除所有不具有该特征的数字。当我们发现没有 2 时,我们消除所有包含 2 的值。最终,剩下的唯一数字将是正确的答案。
一些简单的策略
这是许多玩家使用的策略,类似于上面描述的策略。只是有条不紊地以一种简单的方式解决了这些可能性。 1111 的第一个猜测将回答解决方案中有多少个 1;下一个猜测将回答解决方案中有多少个 2,并说出任何 1 可能在哪里,等等。 使用我们的列表方法,其中包含从 1111、1112、1113、1114 等开始的顺序的大量可能性,我们的下一个猜测将始终是列表中的第一个。
下一个策略是为那些喜欢更多刺激的人准备的。这些猜测似乎或多或少是随机的,希望能发现更多信息。模拟这种方法非常简单——如果你有一个数字列表,只需随机选择一个。如果你在一个数组中有 837 种可能性可供选择,只需在 0 到 836 范围内随机选择一个下标即可。
第三种策略考虑了与给定猜测给出相似结果的答案在某种意义上彼此相似的可能性。因此,为了获得更多信息,它仍然会随机选择一些数字,而不考虑它们是如何评估的,然后才开始考虑结果。 为了实现这一点,让我们选择任意三个可能的答案并猜测它们,暂时忽略它们为我们赢得了多少黑钉和白钉。只有在做出这些猜测之后,我们才会修剪可能性列表,然后按照上面的第二个策略进行。
示例界面 这些是当前实现的示例结果:请输入要尝试的组合,或 0 表示随机值:0 猜测2475
Guessing 1111...
Guessing 2222...
Guessing 2333...
Guessing 2444...
Guessing 2455...
Guessing 2456...
Guessing 2475...
有条不紊地消除所需的 7 次尝试。
Guessing 6452...
Guessing 2416...
Guessing 2485...
Guessing 2445...
Guessing 2435...
Guessing 2425...
Guessing 2475...
猜测和消除需要 7 次尝试。
Guessing 7872...
Guessing 6472...
Guessing 1784...
Guessing 2475...
猜三然后消除所需的 4 次尝试。
玩另一个游戏? (y/n) 是 请输入要尝试的组合,或 0 表示随机值:0 猜测4474
Guessing 1111...
Guessing 2222...
Guessing 3333...
Guessing 4444...
Guessing 4445...
Guessing 4464...
Guessing 4474...
有条不紊地消除所需的 7 次尝试。
Guessing 3585...
Guessing 7162...
Guessing 4474...
猜测和消除需要 3 次尝试。
Guessing 8587...
Guessing 1342...
Guessing 1555...
Guessing 7464...
Guessing 6764...
Guessing 4468...
Guessing 4474...
猜三然后消除所需的 7 次尝试。 注意:这个程序允许每个数字上升到 8 而不是 6。即使有 4096 个可能的答案,它仍然可以很快找到它们。
程序规范 分配的程序必须实现以下所有功能。根据需要允许额外的 - 以下这些是必需的。未来的作业将不会详细说明以下功能——而是要求学生提前设计自己的功能描述以编写程序。主要的: 简单地控制程序的整体行为。将是一个数字 选择作为目标组合,然后每个策略将尝试 找到它。 调用:generateAnswer,(要比较所有三个必须有相同的答案) 有条不紊的消除,guessAndEliminate,guessThreeThenEliminate
生成答案: 要么让用户在键盘上选择神秘组合, 或提供让计算机生成随机组合的选项。 (对于竞技游戏,知道什么类型可能会很有趣 的组合将是最难猜的!) 参数:无! 返回:一个 4 位组合,每个数字在 1 到 8 的范围内
生成搜索空间: 用四位数的所有可能组合填充数组 值在 1 到 8 的范围内。 参数: guesses(修改后的 int 数组)猜测列表 长度(输出整数)列表中的值数 前提: 该数组必须分配给不少于 4096 个元素。
修剪: 分析对特定猜测的响应,然后消除 可能性列表中不再存在的任何值 可能的答案。在每种情况下,它假定 list 是一个答案,并相应地评估猜测。如果 黑白钉的数量与指定的不同, 那么它不可能是正确的答案。 参数: guesses(修改后的 int 数组)猜测列表 长度(修改后的 int)列表中的值数 guess (input int) 已经被评估的猜测 black (input int) 猜到了多少个黑钉子 white (input int) 猜到了多少个白色钉子 前置条件: 黑白实际上确实包含比较的结果 与实际答案的猜测 后置条件: 长度已减少(我们学到了一些东西) 可行的答案占据第一个“长度”位置 在猜测数组中(所以列表更短) 调用:评估
methodicalEliminate: 从所有可能的候选答案列表开始 不断猜测列表中的第一个元素,并且 相应地修剪答案,直到找到答案 范围: answer (input int) 实际答案 (需要获得黑色/白色钉子) 返回:找到答案所需的猜测次数 调用:generateSearchSpace、评估、修剪
gusssAndEliminate: 从所有可能的候选答案列表开始 不断猜测列表中的随机元素,并且 相应地修剪答案,直到找到答案 范围: answer (input int) 实际答案 返回:找到答案所需的猜测次数 调用:generateSearchSpace、评估、修剪
gusssThreeThenEliminate: 从所有可能的候选答案列表开始 先随机猜三个答案再剪裁 可能性列表,然后缩小答案 一次随机猜测 范围: answer (input int) 实际答案 返回:找到答案所需的猜测次数 调用:generateSearchSpace、评估、修剪
注意:这些最后的函数使用正确的答案来评估 每次猜测,然后使用黑色/白色钉子进行猜测 战略。这些策略中的任何一个都可能窥探到以下问题的答案 决定下一步做什么!
ALSO:以下功能也应该出现在这个程序中 来自之前的任务,虽然他们不是他们自己 这个成绩的一部分。
评估: 通过将组合与答案进行比较来评估组合 正确性由黑色钉子指示(正确位置的正确数字) 和白色钉子(正确的数字在错误的位置) 参数: 回答(输入int)正确的组合 guess (input int) 当前的猜测 black (output int) 黑色钉子的数量 white (output int) 白色钉子的数量 前置条件: answer 和 guess 都是没有零位的 4 位数字 后置条件: 黑色和白色都 > 0 并且它们的和是
第 n 位: 识别出组合的第 n 个数字 数字是从左到右还是从右到左计数未指定 参数: 组合(输入 int)组合检查 位置(输入 int)要检查的数字 (返回) (输出 int) 实际数字的值 前置条件: 组合具有适当的位数,并且 0
清除NthDigit: 将组合的第 n 个数字设为零,因此它将不再匹配 数字必须以与上述 nthDigit 相同的方式计算。 参数: 组合 (in/out int) 组合修改 位置(输入 int)将哪个数字设置为 0 前提: 与上面的 nthDigit 相同 后置条件: 对应的数字设置为零 调用:nthDigit(可选,取决于实现)
感谢您阅读这么长的问题,希望您能在数组方面帮助我!
【问题讨论】:
-
哇!真的很长!我不确定,但我认为这个问题不适合 SO,也许你应该在programmer.stackexchange.com 中问它
-
感谢您的努力,但确实没有任何理由提供如此冗长的作业描述。询问您在代码的特定方面遇到的具体问题,例如 - 我正在尝试这样做,但我这样做的方式给了我这个,这是出乎意料的。我在这里想念什么?我到处寻找,但似乎找不到解决方案。
-
你似乎有很好的提问技巧,但你可以改进你的风格以适应Stack Overflow阅读指南How to Ask和SSCCE。