【问题标题】:Compute every combination of 6 numbers计算 6 个数字的每个组合
【发布时间】:2018-05-13 20:07:12
【问题描述】:

我更像是一名媒体开发人员,而不是最好的程序员,但我发现自己需要更好地学习 javascript。我正在创建一个数学纸牌游戏,其中人类玩家和自动玩家各发 6 张牌。每个玩家必须将三张牌组合(连接)成顶部数字,其他三张作为底部数字。然后减去这两个数字。对于自动播放器,我必须检查六张牌的任何可能组合,因此当两个数字相减时,它会尽可能接近目标数字。我对数组不是很好,所以我开始测试每一种可能的组合,然后比较哪个更接近(见下面的例子)。这是一种非常低效的编码方式,但我只是不知道该怎么做。任何帮助将不胜感激。

变量已经被声明了。

alienTopNum = "" + alienNum1 + alienNum2 + alienNum3;
alienBottomNum = "" + alienNum4 + alienNum5 + alienNum6;
oldDiff = targetNum - (alienTopNum - alienBottomNum);
player.SetVar("AC1R1", alienNum1);
player.SetVar("AC2R1", alienNum2);
player.SetVar("AC3R1", alienNum3);
player.SetVar("AC4R1", alienNum4);
player.SetVar("AC4R1", alienNum5);
player.SetVar("AC4R1", alienNum6);
player.SetVar("ATR1", alienTopNum - alienBottomNum);
alienTopNum = "" + alienNum1 + alienNum2 + alienNum3;
alienBottomNum = "" + alienNum4 + alienNum6 + alienNum5;
newDiff = targetNum - (alienTopNum - alienBottomNum);
if (Math.abs(newDiff) < Math.abs(oldDiff)) {
    oldDiff = newDiff;
    player.SetVar("AC1R1", alienNum1);
    player.SetVar("AC2R1", alienNum2);   
    player.SetVar("AC3R1", alienNum3);
    player.SetVar("AC4R1", alienNum4);
    player.SetVar("AC4R1", alienNum6);   
    player.SetVar("AC4R1", alienNum5);
    player.SetVar("ATR1", alienTopNum - alienBottomNum);
}

等等……

【问题讨论】:

  • 识别您的代码相当困难,因为它目前被格式化为引号。如果您希望将其呈现为代码,则可以在问题编辑器中使用标有花括号 {} 的按钮。由于您的问题不清楚,目前也很难提供帮助。请在此处查看出色的指南,该指南解释了什么是一个好的 Stackoverflow 问题:stackoverflow.com/help/how-to-ask

标签: javascript arrays loops


【解决方案1】:

将发牌存储在一个数组中而不是单个变量中,因为这使得它们在生成排列时更容易处理。你没有说卡片可以有什么值,但作为一个例子,如果你将排列作为数组的数组,给定一个[1,2,3,4,5,6] 的“手”:

[ [1,2,3,4,5,6], [1,2,3,4,6,5], [1,2,3,5,4,6], ...etc. ]

然后您可以循环处理每个排列以获取前三个“卡片”和最后三个以获得当前迭代的两个数字,将它们相减,并查看结果是否比先前迭代的结果更接近目标.

以下是使用我在this answer to another question 中找到的数组置换函数来实现的。我不打算解释该算法,因为您可以轻松地为自己搜索各种排列算法,但我已将 cmets 放入我的 bestPlay() 函数中,以解释我如何处理排列以确定哪个是手牌的最佳得分.

我没有尝试使用您的 playerplayer.SetVar() 方法,但希望如果您研究此方法,您可以调整它以用于您的对象。

你没有说卡片可以有什么价值,所以我假设一副二十张卡片重复数字 0-9 两次。

function bestPlay(hand, target) {
  var perms = permutator(hand);            // Get all permutations for hand
  var best = perms[0];                     // Use the first as initial best
  var bestDiff = difference(best);
  for (var i = 1; i < perms.length; i++) { // Loop over the rest of the permutations
    var diff = difference(perms[i]);       // Get diff for current permutation
    if (Math.abs(target - diff) < Math.abs(target - bestDiff)) { // Check if
      best = perms[i];                     // current beats previous best
      bestDiff = diff;                     // and if so make it new best
    }
  }
  // Output the results for this hand:
  console.log(`Hand: ${hand.join(" ")}`);
  console.log(`Best Numbers: ${best.slice(0,3).join("")} ${best.slice(3).join("")}`);
  console.log(`Difference: ${bestDiff}`);
}

var hands = deal();
var target = 112;
console.log(`Target: ${target}`);
bestPlay(hands[1], target);
bestPlay(hands[2], target);

function difference(cards) {
  return Math.abs(cards.slice(0,3).join("") - cards.slice(3).join(""));
}

function deal() {
  var cards = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0];
  // shuffle
  cards.sort(function() { return Math.random() - 0.5; });
  // first hand is first six cards, second hand is next six
  return {
    1: cards.slice(0,6),
    2: cards.slice(6, 12)
  };
}

function permutator(inputArr) {
  var results = [];
  function permute(arr, memo) {
    var cur, memo = memo || [];
    for (var i = 0; i < arr.length; i++) {
      cur = arr.splice(i, 1);
      if (arr.length === 0) {
        results.push(memo.concat(cur));
      }
      permute(arr.slice(), memo.concat(cur));
      arr.splice(i, 0, cur[0]);
    }
    return results;
  }
  return permute(inputArr);
}

如果您多次单击“运行代码片段”按钮,您会看到有时给定手牌的数字组合与目标完全匹配,有时则不然。

【讨论】:

  • nnnnnnn,非常感谢您的回复和解释!非常感谢,让我朝着一个非常好的方向前进。谢谢,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
相关资源
最近更新 更多